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