##// END OF EJS Templates
Fix to discard NaN, Inf and -Inf values from chart....
Mika Salmela -
r2424:4543a29c8891
parent child
Show More
@@ -0,0 +1,26
1 #ifndef CHARTHELPERS_P_H
2 #define CHARTHELPERS_P_H
3
4 #include <qnumeric.h>
5 #include <QPointF>
6
7 static inline bool isValidValue(qreal value)
8 {
9 if (qIsNaN(value) || qIsInf(value)) {
10 qWarning("Ignored NaN, Inf, or -Inf value.");
11 return false;
12 }
13 return true;
14 }
15
16 static inline bool isValidValue(qreal x, qreal y)
17 {
18 return (isValidValue(x) && isValidValue(y));
19 }
20
21 static inline bool isValidValue(const QPointF point)
22 {
23 return (isValidValue(point.x()) && isValidValue(point.y()));
24 }
25
26 #endif // CHARTHELPERS_P_H
@@ -1,638 +1,644
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 "qbarset.h"
22 22 #include "qbarset_p.h"
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 /*!
27 27 \class QBarSet
28 28 \brief Building block for different bar charts
29 29
30 30 QBarSet represents one set of bars. Set of bars contains one data value for each category.
31 31 First value of set is assumed to belong to first category, second to second category and so on.
32 32 If set has fewer values than there are categories, then the missing values are assumed to be
33 33 at the end of set. For missing values in middle of a set, numerical value of zero is used.
34 34
35 35 \mainclass
36 36
37 37 \sa QAbstractBarSeries, QBarSeries, QStackedBarSeries, QPercentBarSeries
38 38 */
39 39 /*!
40 40 \qmlclass BarSet QBarSet
41 41
42 42 BarSet represents one set of bars. Set of bars contains one data value for each category.
43 43 First value of set is assumed to belong to first category, second to second category and so on.
44 44 If set has fewer values than there are categories, then the missing values are assumed to be
45 45 at the end of set. For missing values in middle of a set, numerical value of zero is used.
46 46 \sa AbstractBarSeries, BarSeries, StackedBarSeries, PercentBarSeries
47 47 */
48 48
49 49 /*!
50 50 \property QBarSet::label
51 51 Defines the label of the barSet.
52 52 */
53 53 /*!
54 54 \qmlproperty string BarSet::label
55 55 Defines the label of the barSet.
56 56 */
57 57
58 58 /*!
59 59 \property QBarSet::pen
60 60 \brief Defines the pen used by the barSet.
61 61 */
62 62
63 63 /*!
64 64 \property QBarSet::brush
65 65 \brief Defines the brush used by the barSet.
66 66 */
67 67
68 68 /*!
69 69 \property QBarSet::labelBrush
70 70 \brief Defines the brush used by the barSet's label.
71 71 */
72 72
73 73 /*!
74 74 \property QBarSet::labelFont
75 75 \brief Defines the font used by the barSet's label.
76 76 */
77 77
78 78 /*!
79 79 \qmlproperty Font BarSet::labelFont
80 80 Defines the font used by the barSet's label.
81 81
82 82 See the \l {Font} {QML Font Element} for detailed documentation.
83 83 */
84 84
85 85 /*!
86 86 \property QBarSet::color
87 87 The fill (brush) color of the bar set.
88 88 */
89 89 /*!
90 90 \qmlproperty color BarSet::color
91 91 The fill (brush) color of the bar set.
92 92 */
93 93
94 94 /*!
95 95 \property QBarSet::borderColor
96 96 The line (pen) color of the bar set.
97 97 */
98 98 /*!
99 99 \qmlproperty color BarSet::borderColor
100 100 The line (pen) color of the bar set.
101 101 */
102 102
103 103 /*!
104 104 \qmlproperty real BarSet::borderWidth
105 105 The width of the border line. By default the width is 2.0.
106 106 */
107 107
108 108 /*!
109 109 \property QBarSet::labelColor
110 110 The text (label) color of the bar set.
111 111 */
112 112 /*!
113 113 \qmlproperty color BarSet::labelColor
114 114 The text (label) color of the bar set.
115 115 */
116 116
117 117 /*!
118 118 \fn void QBarSet::clicked(int index)
119 119
120 120 The signal is emitted if the user clicks with a mouse on top of barset.
121 121 Clicked bar inside set is indexed by \a index
122 122 */
123 123
124 124 /*!
125 125 \fn void QBarSet::hovered(bool status)
126 126
127 127 The signal is emitted if mouse is hovered on top of barset.
128 128 Parameter \a status is true, if mouse entered on top of barset, false if mouse left from top of barset.
129 129 */
130 130
131 131
132 132 /*!
133 133 \fn void QBarSet::labelChanged()
134 134 This signal is emitted when the label of the barSet has changed.
135 135 \sa label
136 136 */
137 137 /*!
138 138 \qmlsignal BarSet::onLabelChanged()
139 139 This signal is emitted when the label of the barSet has changed.
140 140 */
141 141
142 142 /*!
143 143 \fn void QBarSet::penChanged()
144 144 This signal is emitted when the pen of the barSet has changed.
145 145 \sa pen
146 146 */
147 147
148 148 /*!
149 149 \fn void QBarSet::brushChanged()
150 150 This signal is emitted when the brush of the barSet has changed.
151 151 \sa brush
152 152 */
153 153
154 154 /*!
155 155 \fn void QBarSet::labelBrushChanged()
156 156 This signal is emitted when the brush of the barSet's label has changed.
157 157 \sa labelBrush
158 158 */
159 159
160 160 /*!
161 161 \fn void QBarSet::labelFontChanged()
162 162 This signal is emitted when the font of the barSet's label has changed.
163 163 \sa labelBrush
164 164 */
165 165
166 166 /*!
167 167 \fn void QBarSet::colorChanged(QColor)
168 168 This signal is emitted when the fill (brush) color of the set has changed to \a color.
169 169 */
170 170 /*!
171 171 \qmlsignal BarSet::onColorChanged(color color)
172 172 This signal is emitted when the fill (brush) color of the set has changed to \a color.
173 173 */
174 174
175 175 /*!
176 176 \fn void QBarSet::borderColorChanged(QColor)
177 177 This signal is emitted when the line (pen) color of the set has changed to \a color.
178 178 */
179 179 /*!
180 180 \qmlsignal BarSet::onBorderColorChanged(color color)
181 181 This signal is emitted when the line (pen) color of the set has changed to \a color.
182 182 */
183 183
184 184 /*!
185 185 \fn void QBarSet::labelColorChanged(QColor)
186 186 This signal is emitted when the text (label) color of the set has changed to \a color.
187 187 */
188 188 /*!
189 189 \qmlsignal BarSet::onLabelColorChanged(color color)
190 190 This signal is emitted when the text (label) color of the set has changed to \a color.
191 191 */
192 192
193 193 /*!
194 194 \fn void QBarSet::valuesAdded(int index, int count)
195 195 This signal is emitted when new values have been added to the set.
196 196 Parameter \a index indicates the position of the first inserted value.
197 197 Parameter \a count is the number of iserted values.
198 198 \sa append(), insert()
199 199 */
200 200 /*!
201 201 \qmlsignal BarSet::onValuesAdded(int index, int count)
202 202 This signal is emitted when new values have been added to the set.
203 203 Parameter \a index indicates the position of the first inserted value.
204 204 Parameter \a count is the number of iserted values.
205 205 */
206 206
207 207 /*!
208 208 \fn void QBarSet::valuesRemoved(int index, int count)
209 209 This signal is emitted values have been removed from the set.
210 210 Parameter \a index indicates the position of the first removed value.
211 211 Parameter \a count is the number of removed values.
212 212 \sa remove()
213 213 */
214 214 /*!
215 215 \qmlsignal BarSet::onValuesRemoved(int index, int count)
216 216 This signal is emitted values have been removed from the set.
217 217 Parameter \a index indicates the position of the first removed value.
218 218 Parameter \a count is the number of removed values.
219 219 */
220 220
221 221 /*!
222 222 \fn void QBarSet::valueChanged(int index)
223 223 This signal is emitted values the value in the set has been modified.
224 224 Parameter \a index indicates the position of the modified value.
225 225 \sa at()
226 226 */
227 227 /*!
228 228 \qmlsignal BarSet::onValueChanged(int index)
229 229 This signal is emitted values the value in the set has been modified.
230 230 Parameter \a index indicates the position of the modified value.
231 231 */
232 232
233 233 /*!
234 234 \qmlproperty int BarSet::count
235 235 The count of values on the barset
236 236 */
237 237
238 238 /*!
239 239 \qmlproperty QVariantList BarSet::values
240 240 The values of the barset. You can set either a list of reals or a list of points as values. If you set a list of
241 241 reals as values, the values are automatically completed to points by using the index of a value as it's
242 242 x-coordinate. For example:
243 243 \code
244 244 myBarSet1.values = [0, 5, 1, 5];
245 245 myBarSet2.values = [Qt.point(0, 1), Qt.point(1, 5), Qt.point(2.2, 4.3)];
246 246 \endcode
247 247 */
248 248
249 249 /*!
250 250 Constructs QBarSet with a label of \a label and with parent of \a parent
251 251 */
252 252 QBarSet::QBarSet(const QString label, QObject *parent)
253 253 : QObject(parent),
254 254 d_ptr(new QBarSetPrivate(label, this))
255 255 {
256 256 }
257 257
258 258 /*!
259 259 Destroys the barset
260 260 */
261 261 QBarSet::~QBarSet()
262 262 {
263 263 // NOTE: d_ptr destroyed by QObject
264 264 }
265 265
266 266 /*!
267 267 Sets new \a label for set.
268 268 */
269 269 void QBarSet::setLabel(const QString label)
270 270 {
271 271 d_ptr->m_label = label;
272 272 emit labelChanged();
273 273 }
274 274
275 275 /*!
276 276 Returns label of the set.
277 277 */
278 278 QString QBarSet::label() const
279 279 {
280 280 return d_ptr->m_label;
281 281 }
282 282
283 283 /*!
284 284 Appends new value \a value to the end of set.
285 285 */
286 286 void QBarSet::append(const qreal value)
287 287 {
288 288 // Convert to QPointF
289 289 int index = d_ptr->m_values.count();
290 290 d_ptr->append(QPointF(d_ptr->m_values.count(), value));
291 291 emit valuesAdded(index, 1);
292 292 }
293 293
294 294 /*!
295 295 Appends a list of reals to set. Works like append with single real value. The \a values in list
296 296 are appended to end of barset
297 297 \sa append()
298 298 */
299 299 void QBarSet::append(const QList<qreal> &values)
300 300 {
301 301 int index = d_ptr->m_values.count();
302 302 d_ptr->append(values);
303 303 emit valuesAdded(index, values.count());
304 304 }
305 305
306 306 /*!
307 307 Convenience operator. Same as append, with real \a value.
308 308 \sa append()
309 309 */
310 310 QBarSet &QBarSet::operator << (const qreal &value)
311 311 {
312 312 append(value);
313 313 return *this;
314 314 }
315 315
316 316 /*!
317 317 Inserts new \a value on the \a index position.
318 318 The value that is currently at this postion is moved to postion index + 1
319 319 \sa remove()
320 320 */
321 321 void QBarSet::insert(const int index, const qreal value)
322 322 {
323 323 d_ptr->insert(index, value);
324 324 emit valuesAdded(index, 1);
325 325 }
326 326
327 327 /*!
328 328 Removes \a count number of values from the set starting at \a index.
329 329 \sa insert()
330 330 */
331 331 void QBarSet::remove(const int index, const int count)
332 332 {
333 333 int removedCount = d_ptr->remove(index, count);
334 334 if (removedCount > 0)
335 335 emit valuesRemoved(index, removedCount);
336 336 return;
337 337 }
338 338
339 339 /*!
340 340 Sets a new value \a value to set, indexed by \a index
341 341 */
342 342 void QBarSet::replace(const int index, const qreal value)
343 343 {
344 344 if (index >= 0 && index < d_ptr->m_values.count()) {
345 345 d_ptr->replace(index, value);
346 346 emit valueChanged(index);
347 347 }
348 348 }
349 349
350 350
351 351 /*!
352 352 Returns value of set indexed by \a index.
353 353 If the index is out of bounds 0.0 is returned.
354 354 */
355 355 qreal QBarSet::at(const int index) const
356 356 {
357 357 if (index < 0 || index >= d_ptr->m_values.count())
358 358 return 0;
359 359 return d_ptr->m_values.at(index).y();
360 360 }
361 361
362 362 /*!
363 363 Returns value of set indexed by \a index.
364 364 If the index is out of bounds 0.0 is returned.
365 365 */
366 366 qreal QBarSet::operator [](const int index) const
367 367 {
368 368 return at(index);
369 369 }
370 370
371 371 /*!
372 372 Returns count of values in set.
373 373 */
374 374 int QBarSet::count() const
375 375 {
376 376 return d_ptr->m_values.count();
377 377 }
378 378
379 379 /*!
380 380 Returns sum of all values in barset.
381 381 */
382 382 qreal QBarSet::sum() const
383 383 {
384 384 qreal total(0);
385 385 for (int i = 0; i < d_ptr->m_values.count(); i++)
386 386 total += d_ptr->m_values.at(i).y();
387 387 return total;
388 388 }
389 389
390 390 /*!
391 391 Sets pen for set. Bars of this set are drawn using \a pen
392 392 */
393 393 void QBarSet::setPen(const QPen &pen)
394 394 {
395 395 if (d_ptr->m_pen != pen) {
396 396 d_ptr->m_pen = pen;
397 397 emit d_ptr->updatedBars();
398 398 emit penChanged();
399 399 }
400 400 }
401 401
402 402 /*!
403 403 Returns pen of the set.
404 404 */
405 405 QPen QBarSet::pen() const
406 406 {
407 407 return d_ptr->m_pen;
408 408 }
409 409
410 410 /*!
411 411 Sets brush for the set. Bars of this set are drawn using \a brush
412 412 */
413 413 void QBarSet::setBrush(const QBrush &brush)
414 414 {
415 415 if (d_ptr->m_brush != brush) {
416 416 d_ptr->m_brush = brush;
417 417 emit d_ptr->updatedBars();
418 418 emit brushChanged();
419 419 }
420 420 }
421 421
422 422 /*!
423 423 Returns brush of the set.
424 424 */
425 425 QBrush QBarSet::brush() const
426 426 {
427 427 return d_ptr->m_brush;
428 428 }
429 429
430 430 /*!
431 431 Sets \a brush of the values that are drawn on top of this barset
432 432 */
433 433 void QBarSet::setLabelBrush(const QBrush &brush)
434 434 {
435 435 if (d_ptr->m_labelBrush != brush) {
436 436 d_ptr->m_labelBrush = brush;
437 437 emit d_ptr->updatedBars();
438 438 emit labelBrushChanged();
439 439 }
440 440 }
441 441
442 442 /*!
443 443 Returns brush of the values that are drawn on top of this barset
444 444 */
445 445 QBrush QBarSet::labelBrush() const
446 446 {
447 447 return d_ptr->m_labelBrush;
448 448 }
449 449
450 450 /*!
451 451 Sets the \a font for values that are drawn on top of this barset
452 452 */
453 453 void QBarSet::setLabelFont(const QFont &font)
454 454 {
455 455 if (d_ptr->m_labelFont != font) {
456 456 d_ptr->m_labelFont = font;
457 457 emit d_ptr->updatedBars();
458 458 emit labelFontChanged();
459 459 }
460 460
461 461 }
462 462
463 463 /*!
464 464 Returns the pen for values that are drawn on top of this barset
465 465 */
466 466 QFont QBarSet::labelFont() const
467 467 {
468 468 return d_ptr->m_labelFont;
469 469 }
470 470
471 471 /*!
472 472 Returns the color of the brush of barset.
473 473 */
474 474 QColor QBarSet::color()
475 475 {
476 476 return brush().color();
477 477 }
478 478
479 479 /*!
480 480 Sets the \a color of brush for this barset
481 481 */
482 482 void QBarSet::setColor(QColor color)
483 483 {
484 484 QBrush b = brush();
485 485 if ((b.color() != color) || (b.style() == Qt::NoBrush)) {
486 486 b.setColor(color);
487 487 if (b.style() == Qt::NoBrush) {
488 488 // Set tyle to Qt::SolidPattern. (Default is Qt::NoBrush)
489 489 // This prevents theme to override color defined in QML side:
490 490 // BarSet { label: "Bob"; color:"red"; values: [1,2,3] }
491 491 // The color must be obeyed, since user wanted it.
492 492 b.setStyle(Qt::SolidPattern);
493 493 }
494 494 setBrush(b);
495 495 emit colorChanged(color);
496 496 }
497 497 }
498 498
499 499 /*!
500 500 Returns the color of pen of this barset
501 501 */
502 502 QColor QBarSet::borderColor()
503 503 {
504 504 return pen().color();
505 505 }
506 506
507 507 /*!
508 508 Sets the color of pen for this barset
509 509 */
510 510 void QBarSet::setBorderColor(QColor color)
511 511 {
512 512 QPen p = pen();
513 513 if (p.color() != color) {
514 514 p.setColor(color);
515 515 setPen(p);
516 516 emit borderColorChanged(color);
517 517 }
518 518 }
519 519
520 520 /*!
521 521 Returns the color of labels of this barset
522 522 */
523 523 QColor QBarSet::labelColor()
524 524 {
525 525 return labelBrush().color();
526 526 }
527 527
528 528 /*!
529 529 Sets the color of labels for this barset
530 530 */
531 531 void QBarSet::setLabelColor(QColor color)
532 532 {
533 533 QBrush b = labelBrush();
534 534 if (b == QBrush())
535 535 b.setStyle(Qt::SolidPattern);
536 536
537 537 if (b.color() != color) {
538 538 b.setColor(color);
539 539 setLabelBrush(b);
540 540 emit labelColorChanged(color);
541 541 }
542 542 }
543 543
544 544 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
545 545
546 546 QBarSetPrivate::QBarSetPrivate(const QString label, QBarSet *parent) : QObject(parent),
547 547 q_ptr(parent),
548 548 m_label(label)
549 549 {
550 550 }
551 551
552 552 QBarSetPrivate::~QBarSetPrivate()
553 553 {
554 554 }
555 555
556 556 void QBarSetPrivate::append(QPointF value)
557 557 {
558 m_values.append(value);
559 emit restructuredBars();
558 if (isValidValue(value)) {
559 m_values.append(value);
560 emit restructuredBars();
561 }
560 562 }
561 563
562 564 void QBarSetPrivate::append(QList<QPointF> values)
563 565 {
564 for (int i = 0; i < values.count(); i++)
565 m_values.append(values.at(i));
566 for (int i = 0; i < values.count(); i++) {
567 if (isValidValue(values.at(i)))
568 m_values.append(values.at(i));
569 }
566 570 emit restructuredBars();
567 571 }
568 572
569 573 void QBarSetPrivate::append(QList<qreal> values)
570 574 {
571 575 int index = m_values.count();
572 576 for (int i = 0; i < values.count(); i++) {
573 m_values.append(QPointF(index, values.at(i)));
574 index++;
577 if (isValidValue(values.at(i))) {
578 m_values.append(QPointF(index, values.at(i)));
579 index++;
580 }
575 581 }
576 582 emit restructuredBars();
577 583 }
578 584
579 585 void QBarSetPrivate::insert(const int index, const qreal value)
580 586 {
581 587 m_values.insert(index, QPointF(index, value));
582 588 emit restructuredBars();
583 589 }
584 590
585 591 void QBarSetPrivate::insert(const int index, const QPointF value)
586 592 {
587 593 m_values.insert(index, value);
588 594 emit restructuredBars();
589 595 }
590 596
591 597 int QBarSetPrivate::remove(const int index, const int count)
592 598 {
593 599 int removeCount = count;
594 600
595 601 if ((index < 0) || (m_values.count() == 0))
596 602 return 0; // Invalid index or not values in list, remove nothing.
597 603 else if ((index + count) > m_values.count())
598 604 removeCount = m_values.count() - index; // Trying to remove more items than list has. Limit amount to be removed.
599 605
600 606 int c = 0;
601 607 while (c < removeCount) {
602 608 m_values.removeAt(index);
603 609 c++;
604 610 }
605 611 emit restructuredBars();
606 612 return removeCount;
607 613 }
608 614
609 615 void QBarSetPrivate::replace(const int index, const qreal value)
610 616 {
611 617 m_values.replace(index, QPointF(index, value));
612 618 emit updatedLayout();
613 619 }
614 620
615 621 void QBarSetPrivate::replace(const int index, const QPointF value)
616 622 {
617 623 m_values.replace(index, value);
618 624 emit updatedLayout();
619 625 }
620 626
621 627 qreal QBarSetPrivate::pos(const int index)
622 628 {
623 629 if (index < 0 || index >= m_values.count())
624 630 return 0;
625 631 return m_values.at(index).x();
626 632 }
627 633
628 634 qreal QBarSetPrivate::value(const int index)
629 635 {
630 636 if (index < 0 || index >= m_values.count())
631 637 return 0;
632 638 return m_values.at(index).y();
633 639 }
634 640
635 641 #include "moc_qbarset.cpp"
636 642 #include "moc_qbarset_p.cpp"
637 643
638 644 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,118 +1,119
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 #ifndef QBARSET_H
22 22 #define QBARSET_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QPen>
26 26 #include <QBrush>
27 27 #include <QFont>
28 #include "charthelpers_p.h"
28 29
29 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 31 class QBarSetPrivate;
31 32
32 33 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
33 34 {
34 35 Q_OBJECT
35 36 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
36 37 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
37 38 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
38 39 Q_PROPERTY(QBrush labelBrush READ labelBrush WRITE setLabelBrush NOTIFY labelBrushChanged)
39 40 Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont NOTIFY labelFontChanged)
40 41 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
41 42 Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
42 43 Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor NOTIFY labelColorChanged)
43 44
44 45 public:
45 46 explicit QBarSet(const QString label, QObject *parent = 0);
46 47 virtual ~QBarSet();
47 48
48 49 void setLabel(const QString label);
49 50 QString label() const;
50 51
51 52 void append(const qreal value);
52 53 void append(const QList<qreal> &values);
53 54
54 55 QBarSet &operator << (const qreal &value);
55 56
56 57 void insert(const int index, const qreal value);
57 58 void remove(const int index, const int count = 1);
58 59 void replace(const int index, const qreal value);
59 60 qreal at(const int index) const;
60 61 qreal operator [](const int index) const;
61 62 int count() const;
62 63 qreal sum() const;
63 64
64 65 void setPen(const QPen &pen);
65 66 QPen pen() const;
66 67
67 68 void setBrush(const QBrush &brush);
68 69 QBrush brush() const;
69 70
70 71 void setLabelBrush(const QBrush &brush);
71 72 QBrush labelBrush() const;
72 73
73 74 void setLabelFont(const QFont &font);
74 75 QFont labelFont() const;
75 76
76 77 QColor color();
77 78 void setColor(QColor color);
78 79
79 80 QColor borderColor();
80 81 void setBorderColor(QColor color);
81 82
82 83 QColor labelColor();
83 84 void setLabelColor(QColor color);
84 85
85 86 Q_SIGNALS:
86 87 void clicked(int index);
87 88 void hovered(bool status);
88 89 void penChanged();
89 90 void brushChanged();
90 91 void labelChanged();
91 92 void labelBrushChanged();
92 93 void labelFontChanged();
93 94 void colorChanged(QColor color);
94 95 void borderColorChanged(QColor color);
95 96 void labelColorChanged(QColor color);
96 97
97 98 void valuesAdded(int index, int count);
98 99 void valuesRemoved(int index, int count);
99 100 void valueChanged(int index);
100 101
101 102 private:
102 103 QScopedPointer<QBarSetPrivate> d_ptr;
103 104 Q_DISABLE_COPY(QBarSet)
104 105 friend class QAbstractBarSeries;
105 106 friend class BarLegendMarker;
106 107 friend class AbstractBarChartItem;
107 108 friend class QAbstractBarSeriesPrivate;
108 109 friend class StackedBarChartItem;
109 110 friend class PercentBarChartItem;
110 111 friend class BarChartItem;
111 112 friend class HorizontalBarChartItem;
112 113 friend class HorizontalStackedBarChartItem;
113 114 friend class HorizontalPercentBarChartItem;
114 115 };
115 116
116 117 QTCOMMERCIALCHART_END_NAMESPACE
117 118
118 119 #endif // QBARSET_H
@@ -1,925 +1,936
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 "qpieseries.h"
22 22 #include "qpieseries_p.h"
23 23 #include "qpieslice.h"
24 24 #include "qpieslice_p.h"
25 25 #include "pieslicedata_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "charttheme_p.h"
28 28 #include "qabstractaxis.h"
29 29 #include "pieanimation_p.h"
30 #include "charthelpers_p.h"
30 31
31 32 #include "qpielegendmarker.h"
32 33
33 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 35
35 36 /*!
36 37 \class QPieSeries
37 38 \brief Pie series API for QtCommercial Charts
38 39
39 40 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
40 41 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
41 42 The actual slice size is determined by that relative value.
42 43
43 44 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
44 45 These relate to the actual chart rectangle.
45 46
46 47 By default the pie is defined as a full pie but it can also be a partial pie.
47 48 This can be done by setting a starting angle and angle span to the series.
48 49 Full pie is 360 degrees where 0 is at 12 a'clock.
49 50
50 51 See the \l {PieChart Example} {pie chart example} or \l {DonutChart Example} {donut chart example} to learn how to use QPieSeries.
51 52 \table 100%
52 53 \row
53 54 \o \image examples_piechart.png
54 55 \o \image examples_donutchart.png
55 56 \endtable
56 57 */
57 58 /*!
58 59 \qmlclass PieSeries QPieSeries
59 60 \inherits AbstractSeries
60 61
61 62 The following QML shows how to create a simple pie chart.
62 63
63 64 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
64 65
65 66 \beginfloatleft
66 67 \image demos_qmlchart1.png
67 68 \endfloat
68 69 \clearfloat
69 70 */
70 71
71 72 /*!
72 73 \property QPieSeries::horizontalPosition
73 74 \brief Defines the horizontal position of the pie.
74 75
75 76 The value is a relative value to the chart rectangle where:
76 77
77 78 \list
78 79 \o 0.0 is the absolute left.
79 80 \o 1.0 is the absolute right.
80 81 \endlist
81 82 Default value is 0.5 (center).
82 83 \sa verticalPosition
83 84 */
84 85
85 86 /*!
86 87 \qmlproperty real PieSeries::horizontalPosition
87 88
88 89 Defines the horizontal position of the pie.
89 90
90 91 The value is a relative value to the chart rectangle where:
91 92
92 93 \list
93 94 \o 0.0 is the absolute left.
94 95 \o 1.0 is the absolute right.
95 96 \endlist
96 97 Default value is 0.5 (center).
97 98 \sa verticalPosition
98 99 */
99 100
100 101 /*!
101 102 \property QPieSeries::verticalPosition
102 103 \brief Defines the vertical position of the pie.
103 104
104 105 The value is a relative value to the chart rectangle where:
105 106
106 107 \list
107 108 \o 0.0 is the absolute top.
108 109 \o 1.0 is the absolute bottom.
109 110 \endlist
110 111 Default value is 0.5 (center).
111 112 \sa horizontalPosition
112 113 */
113 114
114 115 /*!
115 116 \qmlproperty real PieSeries::verticalPosition
116 117
117 118 Defines the vertical position of the pie.
118 119
119 120 The value is a relative value to the chart rectangle where:
120 121
121 122 \list
122 123 \o 0.0 is the absolute top.
123 124 \o 1.0 is the absolute bottom.
124 125 \endlist
125 126 Default value is 0.5 (center).
126 127 \sa horizontalPosition
127 128 */
128 129
129 130 /*!
130 131 \property QPieSeries::size
131 132 \brief Defines the pie size.
132 133
133 134 The value is a relative value to the chart rectangle where:
134 135
135 136 \list
136 137 \o 0.0 is the minimum size (pie not drawn).
137 138 \o 1.0 is the maximum size that can fit the chart.
138 139 \endlist
139 140
140 141 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
141 142
142 143 Default value is 0.7.
143 144 */
144 145
145 146 /*!
146 147 \qmlproperty real PieSeries::size
147 148
148 149 Defines the pie size.
149 150
150 151 The value is a relative value to the chart rectangle where:
151 152
152 153 \list
153 154 \o 0.0 is the minimum size (pie not drawn).
154 155 \o 1.0 is the maximum size that can fit the chart.
155 156 \endlist
156 157
157 158 Default value is 0.7.
158 159 */
159 160
160 161 /*!
161 162 \property QPieSeries::holeSize
162 163 \brief Defines the donut hole size.
163 164
164 165 The value is a relative value to the chart rectangle where:
165 166
166 167 \list
167 168 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
168 169 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
169 170 \endlist
170 171
171 172 The value is never greater then size property.
172 173 Default value is 0.0.
173 174 */
174 175
175 176 /*!
176 177 \qmlproperty real PieSeries::holeSize
177 178
178 179 Defines the donut hole size.
179 180
180 181 The value is a relative value to the chart rectangle where:
181 182
182 183 \list
183 184 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
184 185 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
185 186 \endlist
186 187
187 188 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
188 189
189 190 Default value is 0.0.
190 191 */
191 192
192 193 /*!
193 194 \property QPieSeries::startAngle
194 195 \brief Defines the starting angle of the pie.
195 196
196 197 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
197 198
198 199 Default is value is 0.
199 200 */
200 201
201 202 /*!
202 203 \qmlproperty real PieSeries::startAngle
203 204
204 205 Defines the starting angle of the pie.
205 206
206 207 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
207 208
208 209 Default is value is 0.
209 210 */
210 211
211 212 /*!
212 213 \property QPieSeries::endAngle
213 214 \brief Defines the ending angle of the pie.
214 215
215 216 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
216 217
217 218 Default is value is 360.
218 219 */
219 220
220 221 /*!
221 222 \qmlproperty real PieSeries::endAngle
222 223
223 224 Defines the ending angle of the pie.
224 225
225 226 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
226 227
227 228 Default is value is 360.
228 229 */
229 230
230 231 /*!
231 232 \property QPieSeries::count
232 233
233 234 Number of slices in the series.
234 235 */
235 236
236 237 /*!
237 238 \qmlproperty int PieSeries::count
238 239
239 240 Number of slices in the series.
240 241 */
241 242
242 243 /*!
243 244 \fn void QPieSeries::countChanged()
244 245 Emitted when the slice count has changed.
245 246 \sa count
246 247 */
247 248 /*!
248 249 \qmlsignal PieSeries::onCountChanged()
249 250 Emitted when the slice count has changed.
250 251 */
251 252
252 253 /*!
253 254 \property QPieSeries::sum
254 255
255 256 Sum of all slices.
256 257
257 258 The series keeps track of the sum of all slices it holds.
258 259 */
259 260
260 261 /*!
261 262 \qmlproperty real PieSeries::sum
262 263
263 264 Sum of all slices.
264 265
265 266 The series keeps track of the sum of all slices it holds.
266 267 */
267 268
268 269 /*!
269 270 \fn void QPieSeries::sumChanged()
270 271 Emitted when the sum of all slices has changed.
271 272 \sa sum
272 273 */
273 274 /*!
274 275 \qmlsignal PieSeries::onSumChanged()
275 276 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
276 277 change value of a slice.
277 278 */
278 279
279 280 /*!
280 281 \fn void QPieSeries::added(QList<QPieSlice*> slices)
281 282
282 283 This signal is emitted when \a slices have been added to the series.
283 284
284 285 \sa append(), insert()
285 286 */
286 287 /*!
287 288 \qmlsignal PieSeries::onAdded(PieSlice slice)
288 289 Emitted when \a slice has been added to the series.
289 290 */
290 291
291 292 /*!
292 293 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
293 294 This signal is emitted when \a slices have been removed from the series.
294 295 \sa remove()
295 296 */
296 297 /*!
297 298 \qmlsignal PieSeries::onRemoved(PieSlice slice)
298 299 Emitted when \a slice has been removed from the series.
299 300 */
300 301
301 302 /*!
302 303 \fn void QPieSeries::clicked(QPieSlice* slice)
303 304 This signal is emitted when a \a slice has been clicked.
304 305 \sa QPieSlice::clicked()
305 306 */
306 307 /*!
307 308 \qmlsignal PieSeries::onClicked(PieSlice slice)
308 309 This signal is emitted when a \a slice has been clicked.
309 310 */
310 311
311 312 /*!
312 313 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
313 314 This signal is emitted when user has hovered over or away from the \a slice.
314 315 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
315 316 \sa QPieSlice::hovered()
316 317 */
317 318 /*!
318 319 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
319 320 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
320 321 over the slice and false when hover has moved away from the slice.
321 322 */
322 323
323 324 /*!
324 325 \qmlmethod PieSlice PieSeries::at(int index)
325 326 Returns slice at \a index. Returns null if the index is not valid.
326 327 */
327 328
328 329 /*!
329 330 \qmlmethod PieSlice PieSeries::find(string label)
330 331 Returns the first slice with \a label. Returns null if the index is not valid.
331 332 */
332 333
333 334 /*!
334 335 \qmlmethod PieSlice PieSeries::append(string label, real value)
335 336 Adds a new slice with \a label and \a value to the pie.
336 337 */
337 338
338 339 /*!
339 340 \qmlmethod bool PieSeries::remove(PieSlice slice)
340 341 Removes the \a slice from the pie. Returns true if the removal was successful, false otherwise.
341 342 */
342 343
343 344 /*!
344 345 \qmlmethod PieSeries::clear()
345 346 Removes all slices from the pie.
346 347 */
347 348
348 349 /*!
349 350 Constructs a series object which is a child of \a parent.
350 351 */
351 352 QPieSeries::QPieSeries(QObject *parent)
352 353 : QAbstractSeries(*new QPieSeriesPrivate(this), parent)
353 354 {
354 355 Q_D(QPieSeries);
355 356 QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
356 357 }
357 358
358 359 /*!
359 360 Destroys the series and its slices.
360 361 */
361 362 QPieSeries::~QPieSeries()
362 363 {
363 364 // NOTE: d_prt destroyed by QObject
364 365 }
365 366
366 367 /*!
367 368 Returns QChartSeries::SeriesTypePie.
368 369 */
369 370 QAbstractSeries::SeriesType QPieSeries::type() const
370 371 {
371 372 return QAbstractSeries::SeriesTypePie;
372 373 }
373 374
374 375 /*!
375 376 Appends a single \a slice to the series.
376 377 Slice ownership is passed to the series.
377 378
378 379 Returns true if append was succesfull.
379 380 */
380 381 bool QPieSeries::append(QPieSlice *slice)
381 382 {
382 383 return append(QList<QPieSlice *>() << slice);
383 384 }
384 385
385 386 /*!
386 387 Appends an array of \a slices to the series.
387 388 Slice ownership is passed to the series.
388 389
389 390 Returns true if append was successful.
390 391 */
391 392 bool QPieSeries::append(QList<QPieSlice *> slices)
392 393 {
393 394 Q_D(QPieSeries);
394 395
395 396 if (slices.count() == 0)
396 397 return false;
397 398
398 399 foreach (QPieSlice *s, slices) {
399 400 if (!s || d->m_slices.contains(s))
400 401 return false;
401 402 if (s->series()) // already added to some series
402 403 return false;
404 if (!isValidValue(s->value()))
405 return false;
403 406 }
404 407
405 408 foreach (QPieSlice *s, slices) {
406 409 s->setParent(this);
407 410 QPieSlicePrivate::fromSlice(s)->m_series = this;
408 411 d->m_slices << s;
409 412 }
410 413
411 414 d->updateDerivativeData();
412 415
413 416 foreach(QPieSlice * s, slices) {
414 417 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
415 418 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
416 419 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
417 420 }
418 421
419 422 emit added(slices);
420 423 emit countChanged();
421 424
422 425 return true;
423 426 }
424 427
425 428 /*!
426 429 Appends a single \a slice to the series and returns a reference to the series.
427 430 Slice ownership is passed to the series.
428 431 */
429 432 QPieSeries &QPieSeries::operator << (QPieSlice *slice)
430 433 {
431 434 append(slice);
432 435 return *this;
433 436 }
434 437
435 438
436 439 /*!
437 440 Appends a single slice to the series with give \a value and \a label.
438 441 Slice ownership is passed to the series.
442 Returns NULL if value is NaN, Inf or -Inf and no slice is added to the series.
439 443 */
440 444 QPieSlice *QPieSeries::append(QString label, qreal value)
441 445 {
442 QPieSlice *slice = new QPieSlice(label, value);
443 append(slice);
444 return slice;
446 if (isValidValue(value)) {
447 QPieSlice *slice = new QPieSlice(label, value);
448 append(slice);
449 return slice;
450 } else {
451 return 0;
452 }
445 453 }
446 454
447 455 /*!
448 456 Inserts a single \a slice to the series before the slice at \a index position.
449 457 Slice ownership is passed to the series.
450 458
451 459 Returns true if insert was successful.
452 460 */
453 461 bool QPieSeries::insert(int index, QPieSlice *slice)
454 462 {
455 463 Q_D(QPieSeries);
456 464
457 465 if (index < 0 || index > d->m_slices.count())
458 466 return false;
459 467
460 468 if (!slice || d->m_slices.contains(slice))
461 469 return false;
462 470
463 471 if (slice->series()) // already added to some series
464 472 return false;
465 473
474 if (!isValidValue(slice->value()))
475 return false;
476
466 477 slice->setParent(this);
467 478 QPieSlicePrivate::fromSlice(slice)->m_series = this;
468 479 d->m_slices.insert(index, slice);
469 480
470 481 d->updateDerivativeData();
471 482
472 483 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
473 484 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
474 485 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
475 486
476 487 emit added(QList<QPieSlice *>() << slice);
477 488 emit countChanged();
478 489
479 490 return true;
480 491 }
481 492
482 493 /*!
483 494 Removes a single \a slice from the series and deletes the slice.
484 495
485 496 Do not reference the pointer after this call.
486 497
487 498 Returns true if remove was successful.
488 499 */
489 500 bool QPieSeries::remove(QPieSlice *slice)
490 501 {
491 502 Q_D(QPieSeries);
492 503
493 504 if (!d->m_slices.removeOne(slice))
494 505 return false;
495 506
496 507 d->updateDerivativeData();
497 508
498 509 emit removed(QList<QPieSlice *>() << slice);
499 510 emit countChanged();
500 511
501 512 delete slice;
502 513 slice = 0;
503 514
504 515 return true;
505 516 }
506 517
507 518 /*!
508 519 Takes a single \a slice from the series. Does not destroy the slice object.
509 520
510 521 NOTE: The series remains as the slice's parent object. You must set the
511 522 parent object to take full ownership.
512 523
513 524 Returns true if take was successful.
514 525 */
515 526 bool QPieSeries::take(QPieSlice *slice)
516 527 {
517 528 Q_D(QPieSeries);
518 529
519 530 if (!d->m_slices.removeOne(slice))
520 531 return false;
521 532
522 533 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
523 534 slice->disconnect(d);
524 535
525 536 d->updateDerivativeData();
526 537
527 538 emit removed(QList<QPieSlice *>() << slice);
528 539 emit countChanged();
529 540
530 541 return true;
531 542 }
532 543
533 544 /*!
534 545 Clears all slices from the series.
535 546 */
536 547 void QPieSeries::clear()
537 548 {
538 549 Q_D(QPieSeries);
539 550 if (d->m_slices.count() == 0)
540 551 return;
541 552
542 553 QList<QPieSlice *> slices = d->m_slices;
543 554 foreach (QPieSlice *s, d->m_slices)
544 555 d->m_slices.removeOne(s);
545 556
546 557 d->updateDerivativeData();
547 558
548 559 emit removed(slices);
549 560 emit countChanged();
550 561
551 562 foreach (QPieSlice *s, slices)
552 563 delete s;
553 564 }
554 565
555 566 /*!
556 567 Returns a list of slices that belong to this series.
557 568 */
558 569 QList<QPieSlice *> QPieSeries::slices() const
559 570 {
560 571 Q_D(const QPieSeries);
561 572 return d->m_slices;
562 573 }
563 574
564 575 /*!
565 576 returns the number of the slices in this series.
566 577 */
567 578 int QPieSeries::count() const
568 579 {
569 580 Q_D(const QPieSeries);
570 581 return d->m_slices.count();
571 582 }
572 583
573 584 /*!
574 585 Returns true is the series is empty.
575 586 */
576 587 bool QPieSeries::isEmpty() const
577 588 {
578 589 Q_D(const QPieSeries);
579 590 return d->m_slices.isEmpty();
580 591 }
581 592
582 593 /*!
583 594 Returns the sum of all slice values in this series.
584 595
585 596 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
586 597 */
587 598 qreal QPieSeries::sum() const
588 599 {
589 600 Q_D(const QPieSeries);
590 601 return d->m_sum;
591 602 }
592 603
593 604 void QPieSeries::setHoleSize(qreal holeSize)
594 605 {
595 606 Q_D(QPieSeries);
596 607 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
597 608 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
598 609 }
599 610
600 611 qreal QPieSeries::holeSize() const
601 612 {
602 613 Q_D(const QPieSeries);
603 614 return d->m_holeRelativeSize;
604 615 }
605 616
606 617 void QPieSeries::setHorizontalPosition(qreal relativePosition)
607 618 {
608 619 Q_D(QPieSeries);
609 620
610 621 if (relativePosition < 0.0)
611 622 relativePosition = 0.0;
612 623 if (relativePosition > 1.0)
613 624 relativePosition = 1.0;
614 625
615 626 if (!qFuzzyCompare(d->m_pieRelativeHorPos, relativePosition)) {
616 627 d->m_pieRelativeHorPos = relativePosition;
617 628 emit d->horizontalPositionChanged();
618 629 }
619 630 }
620 631
621 632 qreal QPieSeries::horizontalPosition() const
622 633 {
623 634 Q_D(const QPieSeries);
624 635 return d->m_pieRelativeHorPos;
625 636 }
626 637
627 638 void QPieSeries::setVerticalPosition(qreal relativePosition)
628 639 {
629 640 Q_D(QPieSeries);
630 641
631 642 if (relativePosition < 0.0)
632 643 relativePosition = 0.0;
633 644 if (relativePosition > 1.0)
634 645 relativePosition = 1.0;
635 646
636 647 if (!qFuzzyCompare(d->m_pieRelativeVerPos, relativePosition)) {
637 648 d->m_pieRelativeVerPos = relativePosition;
638 649 emit d->verticalPositionChanged();
639 650 }
640 651 }
641 652
642 653 qreal QPieSeries::verticalPosition() const
643 654 {
644 655 Q_D(const QPieSeries);
645 656 return d->m_pieRelativeVerPos;
646 657 }
647 658
648 659 void QPieSeries::setPieSize(qreal relativeSize)
649 660 {
650 661 Q_D(QPieSeries);
651 662 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
652 663 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
653 664
654 665 }
655 666
656 667 qreal QPieSeries::pieSize() const
657 668 {
658 669 Q_D(const QPieSeries);
659 670 return d->m_pieRelativeSize;
660 671 }
661 672
662 673
663 674 void QPieSeries::setPieStartAngle(qreal angle)
664 675 {
665 676 Q_D(QPieSeries);
666 677 if (qFuzzyCompare(d->m_pieStartAngle, angle))
667 678 return;
668 679 d->m_pieStartAngle = angle;
669 680 d->updateDerivativeData();
670 681 emit d->pieStartAngleChanged();
671 682 }
672 683
673 684 qreal QPieSeries::pieStartAngle() const
674 685 {
675 686 Q_D(const QPieSeries);
676 687 return d->m_pieStartAngle;
677 688 }
678 689
679 690 /*!
680 691 Sets the end angle of the pie.
681 692
682 693 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
683 694
684 695 \a angle must be greater than start angle.
685 696
686 697 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
687 698 */
688 699 void QPieSeries::setPieEndAngle(qreal angle)
689 700 {
690 701 Q_D(QPieSeries);
691 702 if (qFuzzyCompare(d->m_pieEndAngle, angle))
692 703 return;
693 704 d->m_pieEndAngle = angle;
694 705 d->updateDerivativeData();
695 706 emit d->pieEndAngleChanged();
696 707 }
697 708
698 709 /*!
699 710 Returns the end angle of the pie.
700 711
701 712 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
702 713
703 714 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
704 715 */
705 716 qreal QPieSeries::pieEndAngle() const
706 717 {
707 718 Q_D(const QPieSeries);
708 719 return d->m_pieEndAngle;
709 720 }
710 721
711 722 /*!
712 723 Sets the all the slice labels \a visible or invisible.
713 724
714 725 Note that this affects only the current slices in the series.
715 726 If user adds a new slice the default label visibility is false.
716 727
717 728 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
718 729 */
719 730 void QPieSeries::setLabelsVisible(bool visible)
720 731 {
721 732 Q_D(QPieSeries);
722 733 foreach (QPieSlice *s, d->m_slices)
723 734 s->setLabelVisible(visible);
724 735 }
725 736
726 737 /*!
727 738 Sets the all the slice labels \a position
728 739
729 740 Note that this affects only the current slices in the series.
730 741 If user adds a new slice the default label position is LabelOutside
731 742
732 743 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
733 744 */
734 745 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
735 746 {
736 747 Q_D(QPieSeries);
737 748 foreach (QPieSlice *s, d->m_slices)
738 749 s->setLabelPosition(position);
739 750 }
740 751
741 752 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
742 753
743 754
744 755 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
745 756 QAbstractSeriesPrivate(parent),
746 757 m_pieRelativeHorPos(0.5),
747 758 m_pieRelativeVerPos(0.5),
748 759 m_pieRelativeSize(0.7),
749 760 m_pieStartAngle(0),
750 761 m_pieEndAngle(360),
751 762 m_sum(0),
752 763 m_holeRelativeSize(0.0)
753 764 {
754 765 }
755 766
756 767 QPieSeriesPrivate::~QPieSeriesPrivate()
757 768 {
758 769 }
759 770
760 771 void QPieSeriesPrivate::updateDerivativeData()
761 772 {
762 773 // calculate sum of all slices
763 774 qreal sum = 0;
764 775 foreach (QPieSlice *s, m_slices)
765 776 sum += s->value();
766 777
767 778 if (!qFuzzyCompare(m_sum, sum)) {
768 779 m_sum = sum;
769 780 emit q_func()->sumChanged();
770 781 }
771 782
772 783 // nothing to show..
773 784 if (qFuzzyCompare(m_sum, 0))
774 785 return;
775 786
776 787 // update slice attributes
777 788 qreal sliceAngle = m_pieStartAngle;
778 789 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
779 790 QVector<QPieSlice *> changed;
780 791 foreach (QPieSlice *s, m_slices) {
781 792 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
782 793 d->setPercentage(s->value() / m_sum);
783 794 d->setStartAngle(sliceAngle);
784 795 d->setAngleSpan(pieSpan * s->percentage());
785 796 sliceAngle += s->angleSpan();
786 797 }
787 798
788 799
789 800 emit calculatedDataChanged();
790 801 }
791 802
792 803 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
793 804 {
794 805 bool changed = false;
795 806
796 807 if (!qFuzzyCompare(m_holeRelativeSize, innerSize)) {
797 808 m_holeRelativeSize = innerSize;
798 809 changed = true;
799 810 }
800 811
801 812 if (!qFuzzyCompare(m_pieRelativeSize, outerSize)) {
802 813 m_pieRelativeSize = outerSize;
803 814 changed = true;
804 815 }
805 816
806 817 if (changed)
807 818 emit pieSizeChanged();
808 819 }
809 820
810 821 QPieSeriesPrivate *QPieSeriesPrivate::fromSeries(QPieSeries *series)
811 822 {
812 823 return series->d_func();
813 824 }
814 825
815 826 void QPieSeriesPrivate::sliceValueChanged()
816 827 {
817 828 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
818 829 updateDerivativeData();
819 830 }
820 831
821 832 void QPieSeriesPrivate::sliceClicked()
822 833 {
823 834 QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
824 835 Q_ASSERT(m_slices.contains(slice));
825 836 Q_Q(QPieSeries);
826 837 emit q->clicked(slice);
827 838 }
828 839
829 840 void QPieSeriesPrivate::sliceHovered(bool state)
830 841 {
831 842 QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
832 843 Q_ASSERT(m_slices.contains(slice));
833 844 Q_Q(QPieSeries);
834 845 emit q->hovered(slice, state);
835 846 }
836 847
837 848 void QPieSeriesPrivate::initializeDomain()
838 849 {
839 850 // does not apply to pie
840 851 }
841 852
842 853 void QPieSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
843 854 {
844 855 Q_Q(QPieSeries);
845 856 PieChartItem *pie = new PieChartItem(q,parent);
846 857 m_item.reset(pie);
847 858 QAbstractSeriesPrivate::initializeGraphics(parent);
848 859 }
849 860
850 861 void QPieSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
851 862 {
852 863 PieChartItem *item = static_cast<PieChartItem *>(m_item.data());
853 864 Q_ASSERT(item);
854 865 if (options.testFlag(QChart::SeriesAnimations)) {
855 866 item->setAnimation(new PieAnimation(item));
856 867 }else{
857 868 item->setAnimation(0);
858 869 }
859 870 QAbstractSeriesPrivate::initializeAnimations(options);
860 871 }
861 872
862 873 QList<QLegendMarker*> QPieSeriesPrivate::createLegendMarkers(QLegend* legend)
863 874 {
864 875 Q_Q(QPieSeries);
865 876 QList<QLegendMarker*> markers;
866 877 foreach(QPieSlice* slice, q->slices()) {
867 878 QPieLegendMarker* marker = new QPieLegendMarker(q,slice,legend);
868 879 markers << marker;
869 880 }
870 881 return markers;
871 882 }
872 883
873 884 void QPieSeriesPrivate::initializeAxes()
874 885 {
875 886
876 887 }
877 888
878 889 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
879 890 {
880 891 Q_UNUSED(orientation);
881 892 return QAbstractAxis::AxisTypeNoAxis;
882 893 }
883 894
884 895 QAbstractAxis* QPieSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
885 896 {
886 897 Q_UNUSED(orientation);
887 898 return 0;
888 899 }
889 900
890 901 void QPieSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
891 902 {
892 903 //Q_Q(QPieSeries);
893 904 //const QList<QColor>& colors = theme->seriesColors();
894 905 const QList<QGradient>& gradients = theme->seriesGradients();
895 906
896 907 for (int i(0); i < m_slices.count(); i++) {
897 908
898 909 QColor penColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0);
899 910
900 911 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
901 912 qreal pos = (qreal)(i + 1) / (qreal) m_slices.count();
902 913 QColor brushColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), pos);
903 914
904 915 QPieSlice *s = m_slices.at(i);
905 916 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
906 917
907 918 if (forced || d->m_data.m_slicePen.isThemed())
908 919 d->setPen(penColor, true);
909 920
910 921 if (forced || d->m_data.m_sliceBrush.isThemed())
911 922 d->setBrush(brushColor, true);
912 923
913 924 if (forced || d->m_data.m_labelBrush.isThemed())
914 925 d->setLabelBrush(theme->labelBrush().color(), true);
915 926
916 927 if (forced || d->m_data.m_labelFont.isThemed())
917 928 d->setLabelFont(theme->labelFont(), true);
918 929 }
919 930 }
920 931
921 932
922 933 #include "moc_qpieseries.cpp"
923 934 #include "moc_qpieseries_p.cpp"
924 935
925 936 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,254 +1,255
1 1 !include( ../config.pri ):error( "Couldn't find the config.pri file!" )
2 2
3 3 ############################# BUILD CONFIG ######################################
4 4
5 5 TARGET = $$LIBRARY_NAME
6 6 DESTDIR = $$CHART_BUILD_LIB_DIR
7 7 TEMPLATE = lib
8 8 QT = core gui
9 9 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 10 DEFINES += QTCOMMERCIALCHART_LIBRARY
11 11 win32:CONFIG += create_prl
12 12 # treat warnings as errors
13 13 win32-msvc*: {
14 14 QMAKE_CXXFLAGS += /WX
15 15 } else {
16 16 # QMAKE_CXXFLAGS += -Werror
17 17 }
18 18
19 19 unix:{
20 20 QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
21 21 }
22 22
23 23 ############################# DEPEDENCES ########################################
24 24
25 25 win32-msvc*: LIBS += User32.lib
26 26 LIBS -= -l$$LIBRARY_NAME
27 27 INCLUDEPATH += ../include .
28 28
29 29 ############################# SOURCES ##########################################
30 30
31 31 SOURCES += \
32 32 $$PWD/chartdataset.cpp \
33 33 $$PWD/chartpresenter.cpp \
34 34 $$PWD/chartthememanager.cpp \
35 35 $$PWD/qchart.cpp \
36 36 $$PWD/qchartview.cpp \
37 37 $$PWD/qabstractseries.cpp \
38 38 $$PWD/chartbackground.cpp \
39 39 $$PWD/chartelement.cpp \
40 40 $$PWD/chartitem.cpp \
41 41 $$PWD/scroller.cpp \
42 42 $$PWD/chartlayout.cpp \
43 43 $$PWD/charttitle.cpp
44 44 PRIVATE_HEADERS += \
45 45 $$PWD/chartdataset_p.h \
46 46 $$PWD/chartitem_p.h \
47 47 $$PWD/chartpresenter_p.h \
48 48 $$PWD/chartthememanager_p.h \
49 49 $$PWD/chartbackground_p.h \
50 50 $$PWD/chartelement_p.h \
51 51 $$PWD/chartconfig_p.h \
52 52 $$PWD/qchart_p.h \
53 53 $$PWD/qchartview_p.h \
54 54 $$PWD/scroller_p.h \
55 55 $$PWD/qabstractseries_p.h \
56 56 $$PWD/chartlayout_p.h \
57 $$PWD/charttitle_p.h
57 $$PWD/charttitle_p.h \
58 $$PWD/charthelpers_p.h
58 59 PUBLIC_HEADERS += \
59 60 $$PWD/qchart.h \
60 61 $$PWD/qchartglobal.h \
61 62 $$PWD/qabstractseries.h \
62 63 $$PWD/qchartview.h \
63 64 $$PWD/chartsnamespace.h
64 65
65 66 include(animations/animations.pri)
66 67 include(areachart/areachart.pri)
67 68 include(axis/axis.pri)
68 69 include(domain/domain.pri)
69 70 include(barchart/barchart.pri)
70 71 include(legend/legend.pri)
71 72 include(linechart/linechart.pri)
72 73 include(piechart/piechart.pri)
73 74 include(scatterchart/scatter.pri)
74 75 include(splinechart/splinechart.pri)
75 76 include(themes/themes.pri)
76 77 include(xychart/xychart.pri)
77 78
78 79 HEADERS += $$PUBLIC_HEADERS
79 80 HEADERS += $$PRIVATE_HEADERS
80 81 HEADERS += $$THEMES
81 82
82 83 ############################# BUILD PATH ##########################################
83 84
84 85 OBJECTS_DIR = $$CHART_BUILD_DIR/lib
85 86 MOC_DIR = $$CHART_BUILD_DIR/lib
86 87 UI_DIR = $$CHART_BUILD_DIR/lib
87 88 RCC_DIR = $$CHART_BUILD_DIR/lib
88 89
89 90 ############################# PUBLIC HEADERS GENERATOR ##########################################
90 91
91 92 !exists($$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal)
92 93 {
93 94 system($$QMAKE_MKDIR $$CHART_BUILD_PUBLIC_HEADER_DIR)
94 95 win32:{
95 96 command = "echo $${LITERAL_HASH}include \"qchartglobal.h\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal"
96 97 }else{
97 98 command = "echo \"$${LITERAL_HASH}include \\\"qchartglobal.h\\\"\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal"
98 99 }
99 100 PUBLIC_QT_HEADERS += $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal
100 101 system($$command)
101 102 }
102 103
103 104 for(file, PUBLIC_HEADERS) {
104 105 name = $$split(file,'/')
105 106 name = $$last(name)
106 107 class = "$$cat($$file)"
107 108 class = $$find(class,class)
108 109 !isEmpty(class){
109 110 class = $$split(class,QTCOMMERCIALCHART_EXPORT)
110 111 class = $$member(class,1)
111 112 class = $$split(class,' ')
112 113 class = $$replace(class,' ','')
113 114 class = $$member(class,0)
114 115 win32:{
115 116 command = "echo $${LITERAL_HASH}include \"$$name\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class"
116 117 }else{
117 118 command = "echo \"$${LITERAL_HASH}include \\\"$$name\\\"\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class"
118 119 }
119 120 PUBLIC_QT_HEADERS += $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class
120 121 system($$command)
121 122 }
122 123 }
123 124
124 125 ############################# INSTALLERS ##########################################
125 126
126 127 public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart
127 128 public_headers.files = $$PUBLIC_HEADERS $$PUBLIC_QT_HEADERS
128 129 INSTALLS += public_headers
129 130
130 131 install_build_public_headers.name = build_public_headers
131 132 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
132 133 install_build_public_headers.input = PUBLIC_HEADERS
133 134 install_build_public_headers.commands = $$QMAKE_COPY \
134 135 ${QMAKE_FILE_NAME} \
135 136 $$CHART_BUILD_PUBLIC_HEADER_DIR
136 137 install_build_public_headers.CONFIG += target_predeps \
137 138 no_link
138 139
139 140 install_build_private_headers.name = build_private_headers
140 141 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
141 142 install_build_private_headers.input = PRIVATE_HEADERS
142 143 install_build_private_headers.commands = $$QMAKE_COPY \
143 144 ${QMAKE_FILE_NAME} \
144 145 $$CHART_BUILD_PRIVATE_HEADER_DIR
145 146 install_build_private_headers.CONFIG += target_predeps \
146 147 no_link
147 148
148 149 QMAKE_EXTRA_COMPILERS += install_build_public_headers \
149 150 install_build_private_headers \
150 151
151 152 win32:{
152 153 bintarget.CONFIG += no_check_exist
153 154 !staticlib: {
154 155 bintarget.files += $$CHART_BUILD_LIB_DIR\\$${TARGET}.dll
155 156 }
156 157 win32-msvc*:CONFIG(debug, debug|release): {
157 158 bintarget.files += $$CHART_BUILD_LIB_DIR\\$${TARGET}.pdb
158 159 }
159 160 bintarget.path = $$[QT_INSTALL_BINS]
160 161
161 162 libtarget.CONFIG += no_check_exist
162 163 libtarget.files = $$CHART_BUILD_LIB_DIR\\$${TARGET}.prl
163 164 win32-msvc*: {
164 165 libtarget.files += $$CHART_BUILD_LIB_DIR\\$${TARGET}.lib
165 166 } else {
166 167 libtarget.files += $$CHART_BUILD_LIB_DIR\\lib$${TARGET}.a
167 168 }
168 169 libtarget.path = $$[QT_INSTALL_LIBS]
169 170
170 171 DLLDESTDIR = $$CHART_BUILD_BIN_DIR
171 172 INSTALLS += bintarget libtarget
172 173 }else{
173 174 target.path=$$[QT_INSTALL_LIBS]
174 175 INSTALLS += target
175 176 }
176 177
177 178 mac: !staticlib: {
178 179 # Update the name (id) of the library on OSX to point to the lib path
179 180 MAC_CHARTS_LIB_NAME = "lib"$$LIBRARY_NAME".1.dylib"
180 181 QMAKE_POST_LINK += "install_name_tool -id $$CHART_BUILD_LIB_DIR"/"$$MAC_CHARTS_LIB_NAME $$CHART_BUILD_LIB_DIR"/"$$MAC_CHARTS_LIB_NAME"
181 182
182 183 # Update the name (id) of the installed library on OSX to point to the installation path
183 184 postinstall.path = $$[QT_INSTALL_LIBS]
184 185 postinstall.extra = "install_name_tool -id $$[QT_INSTALL_LIBS]"/"$$MAC_CHARTS_LIB_NAME $$[QT_INSTALL_LIBS]"/"$$MAC_CHARTS_LIB_NAME"
185 186 INSTALLS += postinstall
186 187 }
187 188
188 189 ################################ DEVELOPMENT BUILD ##########################################
189 190 # There is a problem with jom.exe currently. It does not seem to understand QMAKE_EXTRA_TARGETS properly.
190 191 # This is the case at least with shadow builds.
191 192 # http://qt-project.org/wiki/jom
192 193
193 194 development_build:!win32-msvc*:{
194 195 chartversion.target = $$PWD/qchartversion_p.h
195 196
196 197 unix:{
197 198 chartversion.commands = @echo \
198 199 \" $${LITERAL_HASH}ifndef QCHARTVERSION_P_H\\n\
199 200 $${LITERAL_HASH}define QCHARTVERSION_P_H\\n\
200 201 const char *buildTime = \\\"`date +'%y%m%d%H%M'`\\\" ; \\n\
201 202 const char *gitHead = \\\"`git rev-parse HEAD`\\\" ; \\n \
202 203 $${LITERAL_HASH}endif \" \
203 204 > \
204 205 $$chartversion.target;
205 206 }else{
206 207 chartversion.commands = @echo \
207 208 "const char *buildTime = \"%date%_%time%\" ; \
208 209 const char *gitHead = \"unknown\" ; " \
209 210 > \
210 211 $$chartversion.target
211 212 }
212 213
213 214 chartversion.depends = $$HEADERS \
214 215 $$SOURCES
215 216
216 217 PRE_TARGETDEPS += $$chartversion.target
217 218 QMAKE_CLEAN += $$PWD/qchartversion_p.h
218 219 QMAKE_EXTRA_TARGETS += chartversion
219 220 }
220 221
221 222 ############################### CLEAN ###########################################
222 223
223 224 unix:QMAKE_DISTCLEAN += -r \
224 225 $$CHART_BUILD_HEADER_DIR \
225 226 $$CHART_BUILD_LIB_DIR
226 227 win32:QMAKE_DISTCLEAN += /Q \
227 228 $$CHART_BUILD_HEADER_DIR \
228 229 $$CHART_BUILD_LIB_DIR
229 230
230 231 ############################## COVERAGE #########################################
231 232
232 233 unix:coverage:{
233 234
234 235 QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
235 236 QMAKE_LDFLAGS += -fprofile-arcs -ftest-coverage
236 237
237 238 LIBS += -lgcov
238 239
239 240 QMAKE_CLEAN += $$OBJECTS_DIR/*.gcda $$OBJECTS_DIR/*.gcno $$PWD/*.gcov ../coverage/*.info
240 241 QMAKE_EXTRA_TARGETS += preparecoverage gencoverage
241 242
242 243 preparecoverage.target = prepare_coverage
243 244 preparecoverage.depends = all
244 245 preparecoverage.commands = lcov --directory $$OBJECTS_DIR --zerocounters ;\
245 246 lcov -i -d $$OBJECTS_DIR -c -o ../coverage/base.info -b $$PWD;
246 247
247 248 gencoverage.target = gen_coverage
248 249 gencoverage.depends = all
249 250 gencoverage.commands = lcov -d $$OBJECTS_DIR -c -o ../coverage/src.info -b $$PWD;\
250 251 lcov -e ../coverage/base.info $$PWD/* $$PWD/animations/* $$PWD/areachart/* $$PWD/axis/* $$PWD/barchart/* $$PWD/legend/* $$PWD/linechart/* $$PWD/piechart/* $$PWD/scatterchart/* $$PWD/splinechart/* $$PWD/themes/* $$PWD/xychart/* -o ../coverage/base.info;\
251 252 lcov -e ../coverage/src.info $$PWD/* $$PWD/animations/* $$PWD/areachart/* $$PWD/axis/* $$PWD/barchart/* $$PWD/legend/* $$PWD/linechart/* $$PWD/piechart/* $$PWD/scatterchart/* $$PWD/splinechart/* $$PWD/themes/* $$PWD/xychart/* -o ../coverage/src.info;\
252 253 lcov -a ../coverage/base.info -a ../coverage/src.info -o ../coverage/coverage.info;
253 254 }
254 255
@@ -1,531 +1,539
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 "qxyseries.h"
22 22 #include "qxyseries_p.h"
23 23 #include "abstractdomain_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include "xychart_p.h"
26 26 #include "qxylegendmarker.h"
27 #include "charthelpers_p.h"
27 28
28 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 30
30 31 /*!
31 32 \class QXYSeries
32 33 \brief The QXYSeries class is a base class for line, spline and scatter series.
33 34 */
34 35 /*!
35 36 \qmlclass XYSeries
36 37 \inherits AbstractSeries
37 38 The XYSeries class is a base class for line, spline and scatter series.
38 39
39 40 The class cannot be instantiated directly.
40 41 */
41 42
42 43 /*!
43 44 \qmlproperty AbstractAxis XYSeries::axisX
44 45 The x axis used for the series. If you leave both axisX and axisXTop undefined, a ValueAxis is created for
45 46 the series.
46 47 \sa axisXTop
47 48 */
48 49
49 50 /*!
50 51 \qmlproperty AbstractAxis XYSeries::axisY
51 52 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
52 53 the series.
53 54 \sa axisYRight
54 55 */
55 56
56 57 /*!
57 58 \qmlproperty AbstractAxis XYSeries::axisXTop
58 59 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
59 60 axisXTop, but not both.
60 61 \sa axisX
61 62 */
62 63
63 64 /*!
64 65 \qmlproperty AbstractAxis XYSeries::axisYRight
65 66 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
66 67 or axisYRight, but not both.
67 68 \sa axisY
68 69 */
69 70
70 71 /*!
71 72 \property QXYSeries::pointsVisible
72 73 Controls if the data points are visible and should be drawn.
73 74 */
74 75 /*!
75 76 \qmlproperty bool XYSeries::pointsVisible
76 77 Controls if the data points are visible and should be drawn.
77 78 */
78 79
79 80 /*!
80 81 \fn QPen QXYSeries::pen() const
81 82 \brief Returns pen used to draw points for series.
82 83 \sa setPen()
83 84 */
84 85
85 86 /*!
86 87 \fn QBrush QXYSeries::brush() const
87 88 \brief Returns brush used to draw points for series.
88 89 \sa setBrush()
89 90 */
90 91
91 92 /*!
92 93 \property QXYSeries::color
93 94 The color of the series. This is line (pen) color in case of QLineSeries or QSplineSeries and
94 95 fill (brush) color in case of QScatterSeries or QAreaSeries.
95 96 \sa QXYSeries::pen(), QXYSeries::brush()
96 97 */
97 98 /*!
98 99 \qmlproperty color XYSeries::color
99 100 The color of the series. This is line (pen) color in case of LineSeries or SplineSeries and
100 101 fill (brush) color in case of ScatterSeries or AreaSeries.
101 102 */
102 103
103 104 /*!
104 105 \fn void QXYSeries::clicked(const QPointF& point)
105 106 \brief Signal is emitted when user clicks the \a point on chart.
106 107 */
107 108 /*!
108 109 \qmlsignal XYSeries::onClicked(QPointF point)
109 110 Signal is emitted when user clicks the \a point on chart. For example:
110 111 \code
111 112 LineSeries {
112 113 XYPoint { x: 0; y: 0 }
113 114 XYPoint { x: 1.1; y: 2.1 }
114 115 onClicked: console.log("onClicked: " + point.x + ", " + point.y);
115 116 }
116 117 \endcode
117 118 */
118 119
119 120 /*!
120 121 \fn void QXYSeries::hovered(const QPointF &point, bool state)
121 122 This signal is emitted when user has hovered over or away from the series. \a point shows the origin (coordinate)
122 123 of the hover event. \a state is true when user has hovered over the series and false when hover has moved away from
123 124 the series.
124 125 */
125 126 /*!
126 127 \qmlsignal XYSeries::onHovered(point point, bool state)
127 128 This signal is emitted when user has hovered over or away from the series. \a point shows the origin (coordinate)
128 129 of the hover event. \a state is true when user has hovered over the series and false when hover has moved away from
129 130 the series.
130 131 */
131 132
132 133 /*!
133 134 \fn void QXYSeries::pointReplaced(int index)
134 135 Signal is emitted when a point has been replaced at \a index.
135 136 \sa replace()
136 137 */
137 138 /*!
138 139 \qmlsignal XYSeries::onPointReplaced(int index)
139 140 Signal is emitted when a point has been replaced at \a index.
140 141 */
141 142
142 143 /*!
143 144 \fn void QXYSeries::pointsReplaced()
144 145 Signal is emitted when all points have been replaced with another points.
145 146 \sa replace()
146 147 */
147 148 /*!
148 149 \qmlsignal XYSeries::onPointsReplaced()
149 150 */
150 151
151 152 /*!
152 153 \fn void QXYSeries::pointAdded(int index)
153 154 Signal is emitted when a point has been added at \a index.
154 155 \sa append(), insert()
155 156 */
156 157 /*!
157 158 \qmlsignal XYSeries::onPointAdded(int index)
158 159 Signal is emitted when a point has been added at \a index.
159 160 */
160 161
161 162 /*!
162 163 \fn void QXYSeries::pointRemoved(int index)
163 164 Signal is emitted when a point has been removed from \a index.
164 165 \sa remove()
165 166 */
166 167 /*!
167 168 \qmlsignal XYSeries::onPointRemoved(int index)
168 169 Signal is emitted when a point has been removed from \a index.
169 170 */
170 171
171 172 /*!
172 173 \fn void QXYSeries::colorChanged(QColor color)
173 174 \brief Signal is emitted when the line (pen) color has changed to \a color.
174 175 */
175 176 /*!
176 177 \qmlsignal XYSeries::onColorChanged(color color)
177 178 Signal is emitted when the line (pen) color has changed to \a color.
178 179 */
179 180
180 181 /*!
181 182 \fn void QXYSeriesPrivate::updated()
182 183 \brief \internal
183 184 */
184 185
185 186 /*!
186 187 \qmlmethod XYSeries::append(real x, real y)
187 188 Append point (\a x, \a y) to the series
188 189 */
189 190
190 191 /*!
191 192 \qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY)
192 193 Replaces point (\a oldX, \a oldY) with point (\a newX, \a newY). Does nothing, if point (oldX, oldY) does not
193 194 exist.
194 195 */
195 196
196 197 /*!
197 198 \qmlmethod XYSeries::remove(real x, real y)
198 199 Removes point (\a x, \a y) from the series. Does nothing, if point (x, y) does not exist.
199 200 */
200 201
201 202 /*!
202 203 \qmlmethod XYSeries::insert(int index, real x, real y)
203 204 Inserts point (\a x, \a y) to the \a index. If index is 0 or smaller than 0 the point is prepended to the list of
204 205 points. If index is the same as or bigger than count, the point is appended to the list of points.
205 206 */
206 207
207 208 /*!
208 209 \qmlmethod QPointF XYSeries::at(int index)
209 210 Returns point at \a index. Returns (0, 0) if the index is not valid.
210 211 */
211 212
212 213 /*!
213 214 \internal
214 215
215 216 Constructs empty series object which is a child of \a parent.
216 217 When series object is added to QChartView or QChart instance ownerships is transferred.
217 218 */
218 219 QXYSeries::QXYSeries(QXYSeriesPrivate &d, QObject *parent)
219 220 : QAbstractSeries(d, parent)
220 221 {
221 222 }
222 223
223 224 /*!
224 225 Destroys the object. Series added to QChartView or QChart instances are owned by those,
225 226 and are deleted when mentioned object are destroyed.
226 227 */
227 228 QXYSeries::~QXYSeries()
228 229 {
229 230 }
230 231
231 232 /*!
232 233 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
233 234 */
234 235 void QXYSeries::append(qreal x, qreal y)
235 236 {
236 237 append(QPointF(x, y));
237 238 }
238 239
239 240 /*!
240 241 This is an overloaded function.
241 242 Adds data \a point to the series. Points are connected with lines on the chart.
242 243 */
243 244 void QXYSeries::append(const QPointF &point)
244 245 {
245 246 Q_D(QXYSeries);
246 d->m_points << point;
247 emit pointAdded(d->m_points.count() - 1);
247
248 if (isValidValue(point)) {
249 d->m_points << point;
250 emit pointAdded(d->m_points.count() - 1);
251 }
248 252 }
249 253
250 254 /*!
251 255 This is an overloaded function.
252 256 Adds list of data \a points to the series. Points are connected with lines on the chart.
253 257 */
254 258 void QXYSeries::append(const QList<QPointF> &points)
255 259 {
256 260 foreach (const QPointF &point , points)
257 261 append(point);
258 262 }
259 263
260 264 /*!
261 265 Replaces data point \a oldX \a oldY with data point \a newX \a newY.
262 266 \sa QXYSeries::pointReplaced()
263 267 */
264 268 void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY)
265 269 {
266 270 replace(QPointF(oldX, oldY), QPointF(newX, newY));
267 271 }
268 272
269 273 /*!
270 274 Replaces \a oldPoint with \a newPoint.
271 275 \sa QXYSeries::pointReplaced()
272 276 */
273 277 void QXYSeries::replace(const QPointF &oldPoint, const QPointF &newPoint)
274 278 {
275 279 Q_D(QXYSeries);
276 280 int index = d->m_points.indexOf(oldPoint);
277 281 if (index == -1)
278 282 return;
279 d->m_points[index] = newPoint;
280 emit pointReplaced(index);
283 if (isValidValue(newPoint)) {
284 d->m_points[index] = newPoint;
285 emit pointReplaced(index);
286 }
281 287 }
282 288
283 289 /*!
284 290 Replaces the current points with \a points. This is faster than replacing data points one by one,
285 291 or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced()
286 292 when the points have been replaced.
287 293 \sa QXYSeries::pointsReplaced()
288 294 */
289 295 void QXYSeries::replace(QList<QPointF> points)
290 296 {
291 297 Q_D(QXYSeries);
292 298 d->m_points = points.toVector();
293 299 emit pointsReplaced();
294 300 }
295 301
296 302 /*!
297 303 Removes current \a x and \a y value.
298 304 */
299 305 void QXYSeries::remove(qreal x, qreal y)
300 306 {
301 307 remove(QPointF(x, y));
302 308 }
303 309
304 310 /*!
305 311 Removes current \a point x value.
306 312
307 313 Note: point y value is ignored.
308 314 */
309 315 void QXYSeries::remove(const QPointF &point)
310 316 {
311 317 Q_D(QXYSeries);
312 318 int index = d->m_points.indexOf(point);
313 319 if (index == -1)
314 320 return;
315 321 d->m_points.remove(index);
316 322 emit pointRemoved(index);
317 323 }
318 324
319 325 /*!
320 326 Inserts a \a point in the series at \a index position.
321 327 */
322 328 void QXYSeries::insert(int index, const QPointF &point)
323 329 {
324 330 Q_D(QXYSeries);
325 d->m_points.insert(index, point);
326 emit pointAdded(index);
331 if (isValidValue(point)) {
332 d->m_points.insert(index, point);
333 emit pointAdded(index);
334 }
327 335 }
328 336
329 337 /*!
330 338 Removes all points from the series.
331 339 */
332 340 void QXYSeries::clear()
333 341 {
334 342 Q_D(QXYSeries);
335 343 for (int i = d->m_points.size() - 1; i >= 0; i--)
336 344 remove(d->m_points.at(i));
337 345 }
338 346
339 347 /*!
340 348 Returns list of points in the series.
341 349 */
342 350 QList<QPointF> QXYSeries::points() const
343 351 {
344 352 Q_D(const QXYSeries);
345 353 return d->m_points.toList();
346 354 }
347 355
348 356 /*!
349 357 Returns number of data points within series.
350 358 */
351 359 int QXYSeries::count() const
352 360 {
353 361 Q_D(const QXYSeries);
354 362 return d->m_points.count();
355 363 }
356 364
357 365
358 366 /*!
359 367 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
360 368 pen from chart theme is used.
361 369 \sa QChart::setTheme()
362 370 */
363 371 void QXYSeries::setPen(const QPen &pen)
364 372 {
365 373 Q_D(QXYSeries);
366 374 if (d->m_pen != pen) {
367 375 bool emitColorChanged = d->m_pen.color() != pen.color();
368 376 d->m_pen = pen;
369 377 emit d->updated();
370 378 if (emitColorChanged)
371 379 emit colorChanged(pen.color());
372 380 }
373 381 }
374 382
375 383 QPen QXYSeries::pen() const
376 384 {
377 385 Q_D(const QXYSeries);
378 386 return d->m_pen;
379 387 }
380 388
381 389 /*!
382 390 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
383 391 from chart theme setting is used.
384 392 \sa QChart::setTheme()
385 393 */
386 394 void QXYSeries::setBrush(const QBrush &brush)
387 395 {
388 396 Q_D(QXYSeries);
389 397 if (d->m_brush != brush) {
390 398 d->m_brush = brush;
391 399 emit d->updated();
392 400 }
393 401 }
394 402
395 403 QBrush QXYSeries::brush() const
396 404 {
397 405 Q_D(const QXYSeries);
398 406 return d->m_brush;
399 407 }
400 408
401 409 void QXYSeries::setColor(const QColor &color)
402 410 {
403 411 QPen p = pen();
404 412 if (p.color() != color) {
405 413 p.setColor(color);
406 414 setPen(p);
407 415 }
408 416 }
409 417
410 418 QColor QXYSeries::color() const
411 419 {
412 420 return pen().color();
413 421 }
414 422
415 423 void QXYSeries::setPointsVisible(bool visible)
416 424 {
417 425 Q_D(QXYSeries);
418 426 if (d->m_pointsVisible != visible) {
419 427 d->m_pointsVisible = visible;
420 428 emit d->updated();
421 429 }
422 430 }
423 431
424 432 bool QXYSeries::pointsVisible() const
425 433 {
426 434 Q_D(const QXYSeries);
427 435 return d->m_pointsVisible;
428 436 }
429 437
430 438
431 439 /*!
432 440 Stream operator for adding a data \a point to the series.
433 441 \sa append()
434 442 */
435 443 QXYSeries &QXYSeries::operator<< (const QPointF &point)
436 444 {
437 445 append(point);
438 446 return *this;
439 447 }
440 448
441 449
442 450 /*!
443 451 Stream operator for adding a list of \a points to the series.
444 452 \sa append()
445 453 */
446 454
447 455 QXYSeries &QXYSeries::operator<< (const QList<QPointF>& points)
448 456 {
449 457 append(points);
450 458 return *this;
451 459 }
452 460
453 461 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
454 462
455 463
456 464 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q)
457 465 : QAbstractSeriesPrivate(q),
458 466 m_pointsVisible(false)
459 467 {
460 468 }
461 469
462 470 void QXYSeriesPrivate::initializeDomain()
463 471 {
464 472 qreal minX(0);
465 473 qreal minY(0);
466 474 qreal maxX(1);
467 475 qreal maxY(1);
468 476
469 477 Q_Q(QXYSeries);
470 478
471 479 const QList<QPointF>& points = q->points();
472 480
473 481 if (!points.isEmpty()) {
474 482 minX = points[0].x();
475 483 minY = points[0].y();
476 484 maxX = minX;
477 485 maxY = minY;
478 486
479 487 for (int i = 0; i < points.count(); i++) {
480 488 qreal x = points[i].x();
481 489 qreal y = points[i].y();
482 490 minX = qMin(minX, x);
483 491 minY = qMin(minY, y);
484 492 maxX = qMax(maxX, x);
485 493 maxY = qMax(maxY, y);
486 494 }
487 495 }
488 496
489 497 domain()->setRange(minX, maxX, minY, maxY);
490 498 }
491 499
492 500 QList<QLegendMarker*> QXYSeriesPrivate::createLegendMarkers(QLegend* legend)
493 501 {
494 502 Q_Q(QXYSeries);
495 503 QList<QLegendMarker*> list;
496 504 return list << new QXYLegendMarker(q,legend);
497 505 }
498 506
499 507 void QXYSeriesPrivate::initializeAxes()
500 508 {
501 509
502 510 }
503 511
504 512 QAbstractAxis::AxisType QXYSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
505 513 {
506 514 Q_UNUSED(orientation);
507 515 return QAbstractAxis::AxisTypeValue;
508 516 }
509 517
510 518 QAbstractAxis* QXYSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
511 519 {
512 520 Q_UNUSED(orientation);
513 521 return 0;
514 522 }
515 523
516 524 void QXYSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
517 525 {
518 526 XYChart *item = static_cast<XYChart *>(m_item.data());
519 527 Q_ASSERT(item);
520 528 if (options.testFlag(QChart::SeriesAnimations)) {
521 529 item->setAnimation(new XYAnimation(item));
522 530 }else{
523 531 item->setAnimation(0);
524 532 }
525 533 QAbstractSeriesPrivate::initializeAnimations(options);
526 534 }
527 535
528 536 #include "moc_qxyseries.cpp"
529 537 #include "moc_qxyseries_p.cpp"
530 538
531 539 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now