1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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;
}
|