##// END OF EJS Templates
Bugfix: floating 0 in axi labels
Michal Klocek -
r779:a05112f857cf
parent child
Show More
@@ -1,421 +1,421
1 1 #include "axisitem_p.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartanimator_p.h"
5 5 #include <QPainter>
6 6 #include <QDebug>
7 7 #include <cmath>
8 8
9 9 static int label_padding = 5;
10 10
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12
13 13 Axis::Axis(QChartAxis *axis,ChartPresenter *presenter,AxisType type) : Chart(presenter),
14 14 m_chartAxis(axis),
15 15 m_type(type),
16 16 m_labelsAngle(0),
17 17 m_grid(presenter->rootItem()),
18 18 m_shades(presenter->rootItem()),
19 19 m_labels(presenter->rootItem()),
20 20 m_axis(presenter->rootItem()),
21 21 m_min(0),
22 22 m_max(0),
23 23 m_ticksCount(0)
24 24 {
25 25 //initial initialization
26 26 m_axis.setZValue(ChartPresenter::AxisZValue);
27 27 m_axis.setHandlesChildEvents(false);
28 28
29 29 m_shades.setZValue(ChartPresenter::ShadesZValue);
30 30 m_grid.setZValue(ChartPresenter::GridZValue);
31 31
32 32 connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
33 33 connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
34 34
35 35 handleAxisUpdated();
36 36 }
37 37
38 38 Axis::~Axis()
39 39 {
40 40 }
41 41
42 42 void Axis::createItems(int count)
43 43 {
44 44
45 45 if (m_axis.children().size() == 0)
46 46 m_axis.addToGroup(new AxisItem(this));
47 47 for (int i = 0; i < count; ++i) {
48 48 m_grid.addToGroup(new QGraphicsLineItem());
49 49 m_labels.addToGroup(new QGraphicsSimpleTextItem());
50 50 m_axis.addToGroup(new QGraphicsLineItem());
51 51 if ((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
52 52 }
53 53 }
54 54
55 55 void Axis::deleteItems(int count)
56 56 {
57 57 QList<QGraphicsItem *> lines = m_grid.childItems();
58 58 QList<QGraphicsItem *> labels = m_labels.childItems();
59 59 QList<QGraphicsItem *> shades = m_shades.childItems();
60 60 QList<QGraphicsItem *> axis = m_axis.childItems();
61 61
62 62 for (int i = 0; i < count; ++i) {
63 63 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
64 64 delete(lines.takeLast());
65 65 delete(labels.takeLast());
66 66 delete(axis.takeLast());
67 67 }
68 68 }
69 69
70 70 void Axis::updateLayout(QVector<qreal> &layout)
71 71 {
72 72 if (animator()) {
73 73 animator()->updateLayout(this,layout);
74 74 } else {
75 75 setLayout(layout);
76 76 }
77 77 }
78 78
79 79 bool Axis::createLabels(QStringList &labels,qreal min, qreal max,int ticks) const
80 80 {
81 81 Q_ASSERT(max>=min);
82 82 Q_ASSERT(ticks>1);
83 83
84 84 QChartAxisCategories* categories = m_chartAxis->categories();
85 85
86 86 bool category = categories->count()>0;
87 87
88 88 if (!category) {
89 89 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
90 90 for (int i=0; i< ticks; i++) {
91 91 qreal value = min + (i * (max - min)/ (ticks-1));
92 92 labels << QString::number(value,'f',n);
93 93 }
94 94 } else {
95 95 QList<qreal> values = categories->values();
96 96 for (int i=0; i< ticks; i++) {
97 97 qreal value = (min + (i * (max - min)/ (ticks-1)));
98 98 int j=0;
99 99 for (; j<values.count(); j++) {
100 100 if (values.at(j) > value) break;
101 101 }
102 102 if (j!=0) value=values.at(j-1);
103 103
104 104 QString label = categories->label(value);
105 105 labels << label;
106 106 }
107 107 }
108 108
109 109 return category;
110 110 }
111 111
112 112 void Axis::setAxisOpacity(qreal opacity)
113 113 {
114 114 m_axis.setOpacity(opacity);
115 115 }
116 116
117 117 qreal Axis::axisOpacity() const
118 118 {
119 119 return m_axis.opacity();
120 120 }
121 121
122 122 void Axis::setGridOpacity(qreal opacity)
123 123 {
124 124 m_grid.setOpacity(opacity);
125 125 }
126 126
127 127 qreal Axis::gridOpacity() const
128 128 {
129 129 return m_grid.opacity();
130 130 }
131 131
132 132 void Axis::setLabelsOpacity(qreal opacity)
133 133 {
134 134 m_labels.setOpacity(opacity);
135 135 }
136 136
137 137 qreal Axis::labelsOpacity() const
138 138 {
139 139 return m_labels.opacity();
140 140 }
141 141
142 142 void Axis::setShadesOpacity(qreal opacity)
143 143 {
144 144 m_shades.setOpacity(opacity);
145 145 }
146 146
147 147 qreal Axis::shadesOpacity() const
148 148 {
149 149 return m_shades.opacity();
150 150 }
151 151
152 152 void Axis::setLabelsAngle(int angle)
153 153 {
154 154 foreach(QGraphicsItem* item , m_labels.childItems()) {
155 155 item->setRotation(angle);
156 156 }
157 157
158 158 m_labelsAngle=angle;
159 159 }
160 160
161 161 void Axis::setLabelsPen(const QPen &pen)
162 162 {
163 163 foreach(QGraphicsItem* item , m_labels.childItems()) {
164 164 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
165 165 }
166 166 }
167 167
168 168 void Axis::setLabelsBrush(const QBrush &brush)
169 169 {
170 170 foreach(QGraphicsItem* item , m_labels.childItems()) {
171 171 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
172 172 }
173 173 }
174 174
175 175 void Axis::setLabelsFont(const QFont &font)
176 176 {
177 177 foreach(QGraphicsItem* item , m_labels.childItems()) {
178 178 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
179 179 }
180 180 }
181 181
182 182 void Axis::setShadesBrush(const QBrush &brush)
183 183 {
184 184 foreach(QGraphicsItem* item , m_shades.childItems()) {
185 185 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
186 186 }
187 187 }
188 188
189 189 void Axis::setShadesPen(const QPen &pen)
190 190 {
191 191 foreach(QGraphicsItem* item , m_shades.childItems()) {
192 192 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
193 193 }
194 194 }
195 195
196 196 void Axis::setAxisPen(const QPen &pen)
197 197 {
198 198 foreach(QGraphicsItem* item , m_axis.childItems()) {
199 199 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
200 200 }
201 201 }
202 202
203 203 void Axis::setGridPen(const QPen &pen)
204 204 {
205 205 foreach(QGraphicsItem* item , m_grid.childItems()) {
206 206 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
207 207 }
208 208 }
209 209
210 210 QVector<qreal> Axis::calculateLayout() const
211 211 {
212 212 Q_ASSERT(m_ticksCount>=2);
213 213
214 214 QVector<qreal> points;
215 215 points.resize(m_ticksCount);
216 216
217 217 switch (m_type)
218 218 {
219 219 case X_AXIS:
220 220 {
221 221 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
222 222 for (int i = 0; i < m_ticksCount; ++i) {
223 223 int x = i * deltaX + m_rect.left();
224 224 points[i] = x;
225 225 }
226 226 }
227 227 break;
228 228 case Y_AXIS:
229 229 {
230 230 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
231 231 for (int i = 0; i < m_ticksCount; ++i) {
232 232 int y = i * -deltaY + m_rect.bottom();
233 233 points[i] = y;
234 234 }
235 235 }
236 236 break;
237 237 }
238 238 return points;
239 239 }
240 240
241 241 void Axis::setLayout(QVector<qreal> &layout)
242 242 {
243 243 int diff = m_layoutVector.size() - layout.size();
244 244
245 245 if (diff>0) {
246 246 deleteItems(diff);
247 247 } else if (diff<0) {
248 248 createItems(-diff);
249 249 }
250 250
251 251 if( diff!=0) handleAxisUpdated();
252 252
253 253 QStringList ticksList;
254 254
255 255 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
256 256
257 257 QList<QGraphicsItem *> lines = m_grid.childItems();
258 258 QList<QGraphicsItem *> labels = m_labels.childItems();
259 259 QList<QGraphicsItem *> shades = m_shades.childItems();
260 260 QList<QGraphicsItem *> axis = m_axis.childItems();
261 261
262 262 Q_ASSERT(labels.size() == ticksList.size());
263 263 Q_ASSERT(layout.size() == ticksList.size());
264 264
265 265 switch (m_type)
266 266 {
267 267 case X_AXIS:
268 268 {
269 269 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
270 270 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
271 271
272 272 for (int i = 0; i < layout.size(); ++i) {
273 273 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
274 274 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
275 275 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
276 if (!categories) {
276 if (!categories || i<1) {
277 277 labelItem->setText(ticksList.at(i));
278 278 QPointF center = labelItem->boundingRect().center();
279 279 labelItem->setTransformOriginPoint(center.x(), center.y());
280 280 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
281 } else if(i>0) {
281 } else {
282 282 labelItem->setText(ticksList.at(i));
283 283 QPointF center = labelItem->boundingRect().center();
284 284 labelItem->setTransformOriginPoint(center.x(), center.y());
285 285 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
286 286 }
287 287
288 288 if ((i+1)%2 && i>1) {
289 289 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
290 290 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
291 291 }
292 292 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
293 293 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
294 294 }
295 295 }
296 296 break;
297 297
298 298 case Y_AXIS:
299 299 {
300 300 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
301 301 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
302 302
303 303 for (int i = 0; i < layout.size(); ++i) {
304 304 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
305 305 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
306 306 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
307 307
308 if (!categories) {
308 if (!categories || i<1) {
309 309 labelItem->setText(ticksList.at(i));
310 310 QPointF center = labelItem->boundingRect().center();
311 311 labelItem->setTransformOriginPoint(center.x(), center.y());
312 312 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
313 } else if (i>0) {
313 } else {
314 314 labelItem->setText(ticksList.at(i));
315 315 QPointF center = labelItem->boundingRect().center();
316 316 labelItem->setTransformOriginPoint(center.x(), center.y());
317 317 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
318 318 }
319 319
320 320 if ((i+1)%2 && i>1) {
321 321 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
322 322 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
323 323 }
324 324 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
325 325 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
326 326 }
327 327 }
328 328 break;
329 329 default:
330 330 qDebug()<<"Unknown axis type";
331 331 break;
332 332 }
333 333
334 334 m_layoutVector=layout;
335 335 }
336 336
337 337 bool Axis::isEmpty()
338 338 {
339 339 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max) || m_ticksCount==0;
340 340 }
341 341
342 342 //handlers
343 343
344 344 void Axis::handleAxisCategoriesUpdated()
345 345 {
346 346 if (isEmpty()) return;
347 347 updateLayout(m_layoutVector);
348 348 }
349 349
350 350 void Axis::handleAxisUpdated()
351 351 {
352 352
353 353 if (isEmpty()) return;
354 354
355 355 if (m_chartAxis->isAxisVisible()) {
356 356 setAxisOpacity(100);
357 357 } else {
358 358 setAxisOpacity(0);
359 359 }
360 360
361 361 if (m_chartAxis->isGridLineVisible()) {
362 362 setGridOpacity(100);
363 363 } else {
364 364 setGridOpacity(0);
365 365 }
366 366
367 367 if (m_chartAxis->labelsVisible()) {
368 368 setLabelsOpacity(100);
369 369 } else {
370 370 setLabelsOpacity(0);
371 371 }
372 372
373 373 if (m_chartAxis->shadesVisible()) {
374 374 setShadesOpacity(m_chartAxis->shadesOpacity());
375 375 } else {
376 376 setShadesOpacity(0);
377 377 }
378 378
379 379 setLabelsAngle(m_chartAxis->labelsAngle());
380 380 setAxisPen(m_chartAxis->axisPen());
381 381 setLabelsPen(m_chartAxis->labelsPen());
382 382 setLabelsBrush(m_chartAxis->labelsBrush());
383 383 setLabelsFont(m_chartAxis->labelsFont());
384 384 setGridPen(m_chartAxis->gridLinePen());
385 385 setShadesPen(m_chartAxis->shadesPen());
386 386 setShadesBrush(m_chartAxis->shadesBrush());
387 387
388 388 }
389 389
390 390 void Axis::handleRangeChanged(qreal min, qreal max,int tickCount)
391 391 {
392 392 if (qFuzzyIsNull(min - max) || tickCount < 2)
393 393 return;
394 394
395 395 m_min = min;
396 396 m_max = max;
397 397 m_ticksCount= tickCount;
398 398
399 399 if (isEmpty()) return;
400 400 QVector<qreal> layout = calculateLayout();
401 401 updateLayout(layout);
402 402
403 403 }
404 404
405 405 void Axis::handleGeometryChanged(const QRectF &rect)
406 406 {
407 407 m_rect = rect;
408 408 if (isEmpty()) return;
409 409 QVector<qreal> layout = calculateLayout();
410 410 updateLayout(layout);
411 411 }
412 412
413 413 void Axis::axisSelected()
414 414 {
415 415 qDebug()<<"TODO axis clicked";
416 416 }
417 417
418 418 //TODO "nice numbers algorithm"
419 419 #include "moc_axisitem_p.cpp"
420 420
421 421 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now