#include "ChartScene.h" #include "ChartAxes.h" #include #include #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& 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; }