Add graph to stats page; update Rules
[harbour-pedalo.git] / src / graph.cpp
1 #include <QBrush>
2 #include <QPainter>
3
4 #include "journey.h"
5 #include "graph.h"
6
7 Graph::Graph(QQuickItem *parent)
8 : QQuickPaintedItem(parent)
9 , primary(QColor("#ff0000"))
10 , secondary(QColor("#00ff00"))
11 , highlight(QColor("#0000ff"))
12 , axisThickness(0.02)
13 , bars(7)
14 , gap(0.1)
15 , minmodel(0.0f)
16 , maxmodel(1.0f)
17 , miny(0.0f)
18 , maxy(1.0f)
19 , stepy(0.1f)
20 , unitsy("%")
21 , fontsize(24.0)
22 , animate(1.0)
23 {
24 model.clear();
25 labelsx.clear();
26 labelsy.clear();
27 }
28
29 void Graph::paint(QPainter *painter) {
30 QLocale locale;
31 float barwidth;
32 float axiswidth;
33 int count;
34 int barfullwidth;
35 float labelygap;
36 float labelxgap;
37 int labels;
38 float labelheight;
39
40 QRectF size = contentsBoundingRect();
41
42 bars = model.length();
43 labelygap = size.height() * 0.1l;
44 labelxgap = size.width() * 0.11;
45 axiswidth = qMin(size.width() * axisThickness, size.height() * axisThickness);
46 barfullwidth = ((size.width() - labelxgap - axiswidth) / bars);
47 barwidth = barfullwidth * (1.0 - gap);
48 labels = labelsy.length() > 0 ? labelsy.length() : 1 + (maxy - miny) / stepy;
49 labelheight = (size.height() - labelygap - axiswidth) / (labels - 0.5);
50
51 QBrush axiscolour(primary);
52 QBrush barcolour(secondary);
53
54 painter->setBrush(axiscolour);
55 painter->setPen(Qt::NoPen);
56 painter->setRenderHint(QPainter::Antialiasing);
57 painter->setOpacity(1.0);
58
59 const QPointF points[6] = {
60 QPointF(labelxgap, (labelheight / 2.0)),
61 QPointF(labelxgap, size.height() - labelygap),
62 QPointF(size.width(), size.height() - labelygap),
63 QPointF(size.width(), size.height() - labelygap - axiswidth),
64 QPointF(labelxgap + axiswidth, size.height() - labelygap - axiswidth),
65 QPointF(labelxgap + axiswidth, (labelheight / 2.0))
66 };
67 painter->drawPolygon(points, 6);
68
69 if (bars > 0) {
70 painter->setBrush(barcolour);
71
72 count = 0;
73 for (QList<float>::const_iterator iter = model.constBegin(); (count < bars) && (iter != model.constEnd()); iter++) {
74 float barheight = ((*iter) - miny) / (maxy - miny);
75 barheight = qBound(0.0f, barheight, 1.0f) * (size.height() - labelygap - axiswidth - (labelheight / 2.0));
76 barheight *= animate;
77 painter->drawRect(labelxgap + axiswidth + (barfullwidth * count) + (barfullwidth * gap / 2.0), size.height() - labelygap - barheight - axiswidth, barwidth, barheight);
78
79 count++;
80 }
81 }
82
83 QFont font = painter->font();
84 font.setPixelSize(fontsize);
85 painter->setFont(font);
86 painter->setPen(primary);
87 painter->setBrush(Qt::NoBrush);
88
89 if ((bars > 0) && (labelsx.length() == bars)) {
90 for (count = 0; count < bars; count++) {
91 QRectF rect(labelxgap + axiswidth + (barfullwidth * count), size.height() - labelygap + 8.0, barfullwidth, labelygap - 8.0);
92 painter->drawText(rect, Qt::AlignHCenter | Qt::NoClip | Qt::TextSingleLine, labelsx[count]);
93 //painter->drawRect(rect);
94 }
95 }
96
97 if (labelsy.length() > 0) {
98 for (count = 0; count < labels; count++) {
99 QRectF rect(0, size.height() - (labelheight * (count + 0.5)) - labelygap, labelxgap - 8.0, labelheight);
100 painter->drawText(rect, Qt::AlignVCenter | Qt::AlignRight | Qt::NoClip | Qt::TextSingleLine, labelsy[count]);
101 //painter->drawRect(rect);
102 }
103 }
104 else {
105 float labelvalue = miny;
106 for (count = 0; count < labels; count++) {
107 QString labeltext = unitsy == "%" ? locale.toString(labelvalue * 100, 'f', 0) + "%" : locale.toString(labelvalue, 'g', 2) + unitsy;
108 QRectF rect(0, size.height() - (labelheight * (count + 0.5)) - labelygap, labelxgap - 8.0, labelheight);
109 painter->drawText(rect, Qt::AlignVCenter | Qt::AlignRight | Qt::NoClip | Qt::TextSingleLine, labeltext);
110 //painter->drawRect(rect);
111 labelvalue += stepy;
112 }
113
114 }
115 }
116
117 QList<float> Graph::getModel() const {
118 return model;
119 }
120
121 void Graph::setModel(QList<float> value) {
122 model = value;
123 emit modelChanged();
124
125 if (model.length() > 0) {
126 minmodel = model[0];
127 maxmodel = minmodel;
128 foreach (int y, model) {
129 if (y < minmodel) {
130 minmodel = y;
131 }
132 if (y > maxmodel) {
133 maxmodel = y;
134 }
135 }
136 }
137 }
138
139 QStringList Graph::getLabelsx() const {
140 return labelsx;
141 }
142
143 void Graph::setLabelsx(QStringList value) {
144 labelsx = value;
145 emit labelsxChanged();
146 }
147
148 QStringList Graph::getLabelsy() const {
149 return labelsy;
150 }
151
152 void Graph::setLabelsy(QStringList value) {
153 labelsy = value;
154 emit labelsyChanged();
155 }
156
157 QColor Graph::getPrimary() const {
158 return this->primary;
159 }
160
161 void Graph::setPrimary(QColor value) {
162 if (primary != value) {
163 primary = value;
164 emit primaryChanged(value);
165 }
166 }
167
168 QColor Graph::getSecondary() const {
169 return this->secondary;
170 }
171
172 void Graph::setSecondary(QColor value) {
173 if (secondary != value) {
174 secondary = value;
175 emit secondaryChanged(value);
176 }
177 }
178
179 QColor Graph::getHighlight() const {
180 return this->highlight;
181 }
182
183 void Graph::setHighlight(QColor value) {
184 if (highlight != value) {
185 highlight = value;
186 emit highlightChanged(value);
187 }
188 }
189
190 float Graph::getGap() const {
191 return gap;
192 }
193
194 void Graph::setGap(float value) {
195 if (gap != value) {
196 gap = value;
197 emit gapChanged(value);
198 }
199 }
200
201 float Graph::getMiny() const {
202 return miny;
203 }
204
205 void Graph::setMiny(float value) {
206 if (miny != value) {
207 miny = value;
208 emit minyChanged(value);
209 }
210 }
211
212 float Graph::getMaxy() const {
213 return maxy;
214 }
215
216 void Graph::setMaxy(float value) {
217 if (maxy != value) {
218 maxy = value;
219 emit maxyChanged(value);
220 }
221 }
222
223 float Graph::getStepy() const {
224 return stepy;
225 }
226
227 void Graph::setStepy(float value) {
228 if (stepy != value) {
229 stepy = value;
230 emit stepyChanged(value);
231 }
232 }
233
234 QString Graph::getUnitsy() const {
235 return unitsy;
236 }
237
238 void Graph::setUnitsy(QString value) {
239 if (unitsy != value) {
240 unitsy = value;
241 emit unitsyChanged();
242 }
243 }
244
245 float Graph::getFontsize() const {
246 return fontsize;
247 }
248
249 void Graph::setFontsize(float value) {
250 if (fontsize != value) {
251 fontsize = value;
252 emit fontsizeChanged(value);
253 }
254 }
255
256 float Graph::getAnimate() const {
257 return animate;
258 }
259
260 void Graph::setAnimate(float value) {
261 if (animate != value) {
262 animate = value;
263 emit animateChanged(value);
264 update();
265 }
266 }
267