diff options
Diffstat (limited to 'src/charts/ChartScene.cpp')
-rw-r--r-- | src/charts/ChartScene.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/charts/ChartScene.cpp b/src/charts/ChartScene.cpp new file mode 100644 index 0000000..559ecc5 --- /dev/null +++ b/src/charts/ChartScene.cpp @@ -0,0 +1,111 @@ +#include "ChartScene.h" +#include "ChartAxes.h" +#include <cstdlib> +#include <cmath> +#include "ChartDataLine.h" + +const QSizeF ChartScene::Margin(30, 20); +const QSizeF ChartScene::Padding(20, 20); +const QSizeF ChartScene::DataSetPadding(10, 10); + +ChartScene::ChartScene(Chart* chart): + QGraphicsScene(chart), chart(chart), dataDirection(1) +{ + setSceneRect(0, 0, 600, 300); +} + +void ChartScene::setDataSet(const QList<DataPoint>& dataSet, int xTickInterval) +{ + clear(); + this->dataSet = dataSet; + initYScale(); + ChartAxes(this, xTickInterval).paint(); + ChartDataLine(this).paint(); +} + +void ChartScene::initYScale() +{ + yMin = computeMinY(); + yMax = computeMaxY(); + yTickSpacing = computeYTickSpacing(); + extendYMinMax(); + yScale = getDataSetSize().height() / getYDiff(); +} + +int ChartScene::computeMinY() const +{ + int min = 1000000; + foreach(DataPoint point, dataSet) + if(point.value < min) + min = point.value; + return min; +} + +int ChartScene::computeMaxY() const +{ + int max = -1000000; + foreach(DataPoint point, dataSet) + if(point.value > max) + max = point.value; + return max; +} + +int ChartScene::computeYTickSpacing() const +{ + const int higherZonesLimit = 4; + const int lowerZonesLimit = 3; + + double order = floor(log10(getYDiff())); + double base = pow(10, order); + double zonesNum = ceil(getYDiff() / base); + if(zonesNum > higherZonesLimit) + base *= 2; + else if(zonesNum < lowerZonesLimit) + base /= 2; + int res = (int)base; + if(res == 0) + res = 10; + return res; +} + +void ChartScene::extendYMinMax() +{ + yMin = int(floor(yMin / double(yTickSpacing))) * yTickSpacing; + yMax = int(ceil(yMax / double(yTickSpacing))) * yTickSpacing; + if (yMax == yMin) + yMax = yMin + yTickSpacing; +} + +QSizeF ChartScene::getBorder() +{ + return Margin + Padding; +} + +QRectF ChartScene::getChartRect() const +{ + QSizeF border = getBorder(); + return sceneRect().adjusted(border.width(), border.height(), + -border.width(), -border.height()); +} + +QPointF ChartScene::getChartOrigin() const +{ + QRectF chartRect = getChartRect(); + return QPointF(chartRect.left(), chartRect.bottom()); +} + +QSizeF ChartScene::getDataSetSize() const +{ + QSizeF dataSetBorder(2 * getBorder() + DataSetPadding); + return sceneRect().size() - dataSetBorder; +} + +qreal ChartScene::getXTickSpacing() const +{ + return getDataSetSize().width() / (dataSet.size() - 1); +} + +qreal ChartScene::getYPosFromValue(int value) const +{ + return yScale * value; +} |