##// END OF EJS Templates
Add QPieSlice::series() and tests
Jani Honkonen -
r1323:f354dfd88f13
parent child
Show More
@@ -1,665 +1,667
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 "chartanimator_p.h"
29 29 #include "legendmarker_p.h"
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \class QPieSeries
35 35 \brief Pie series API for QtCommercial Charts
36 36
37 37 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 38 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 39 The actual slice size is determined by that relative value.
40 40
41 41 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 42 These relate to the actual chart rectangle.
43 43
44 44 By default the pie is defined as a full pie but it can also be a partial pie.
45 45 This can be done by setting a starting angle and angle span to the series.
46 46 Full pie is 360 degrees where 0 is at 12 a'clock.
47 47
48 48 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
49 49 \image examples_piechart.png
50 50 */
51 51
52 52 /*!
53 53 \property QPieSeries::horizontalPosition
54 54 \brief Defines the horizontal position of the pie.
55 55
56 56 The value is a relative value to the chart rectangle where:
57 57
58 58 \list
59 59 \o 0.0 is the absolute left.
60 60 \o 1.0 is the absolute right.
61 61 \endlist
62 62
63 63 Default value is 0.5 (center).
64 64
65 65 \sa verticalPosition
66 66 */
67 67
68 68 /*!
69 69 \fn void QPieSeries::horizontalPositionChanged()
70 70
71 71 Emitted then the horizontal position of the pie has changed.
72 72
73 73 \sa horizontalPosition
74 74 */
75 75
76 76 /*!
77 77 \property QPieSeries::verticalPosition
78 78 \brief Defines the vertical position of the pie.
79 79
80 80 The value is a relative value to the chart rectangle where:
81 81
82 82 \list
83 83 \o 0.0 is the absolute top.
84 84 \o 1.0 is the absolute bottom.
85 85 \endlist
86 86
87 87 Default value is 0.5 (center).
88 88
89 89 \sa horizontalPosition
90 90 */
91 91
92 92 /*!
93 93 \fn void QPieSeries::verticalPositionChanged()
94 94
95 95 Emitted then the vertical position of the pie has changed.
96 96
97 97 \sa verticalPosition
98 98 */
99 99
100 100 /*!
101 101 \property QPieSeries::size
102 102 \brief Defines the pie size.
103 103
104 104 The value is a relative value to the chart rectangle where:
105 105
106 106 \list
107 107 \o 0.0 is the minimum size (pie not drawn).
108 108 \o 1.0 is the maximum size that can fit the chart.
109 109 \endlist
110 110
111 111 Default value is 0.7.
112 112 */
113 113
114 114 /*!
115 115 \fn void QPieSeries::pieSizeChanged()
116 116
117 117 Emitted when the pie size has changed.
118 118
119 119 \sa size
120 120 */
121 121
122 122 /*!
123 123 \property QPieSeries::startAngle
124 124 \brief Defines the starting angle of the pie.
125 125
126 126 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
127 127
128 128 Default is value is 0.
129 129 */
130 130
131 131 /*!
132 132 \fn void QPieSeries::pieStartAngleChanged()
133 133
134 134 Emitted when the starting angle of the pie has changed.
135 135
136 136 \sa startAngle
137 137 */
138 138
139 139 /*!
140 140 \property QPieSeries::endAngle
141 141 \brief Defines the ending angle of the pie.
142 142
143 143 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
144 144
145 145 Default is value is 360.
146 146 */
147 147
148 148 /*!
149 149 \fn void QPieSeries::pieEndAngleChanged()
150 150
151 151 Emitted when the ending angle of the pie has changed.
152 152
153 153 \sa endAngle
154 154 */
155 155
156 156 /*!
157 157 \property QPieSeries::count
158 158
159 159 Number of slices in the series.
160 160 */
161 161
162 162 /*!
163 163 \fn void QPieSeries::countChanged()
164 164
165 165 Emitted when the slice count has changed.
166 166
167 167 \sa count
168 168 */
169 169
170 170 /*!
171 171 \property QPieSeries::sum
172 172
173 173 Sum of all slices.
174 174
175 175 The series keeps track of the sum of all slices it holds.
176 176 */
177 177
178 178 /*!
179 179 \fn void QPieSeries::sumChanged()
180 180
181 181 Emitted when the sum of all slices has changed.
182 182
183 183 \sa sum
184 184 */
185 185
186 186 /*!
187 187 \fn void QPieSeries::added(QList<QPieSlice*> slices)
188 188
189 189 This signal is emitted when \a slices have been added to the series.
190 190
191 191 \sa append(), insert()
192 192 */
193 193
194 194 /*!
195 195 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
196 196
197 197 This signal is emitted when \a slices have been removed from the series.
198 198
199 199 \sa remove()
200 200 */
201 201
202 202 /*!
203 203 \fn void QPieSeries::clicked(QPieSlice* slice)
204 204
205 205 This signal is emitted when a \a slice has been clicked.
206 206
207 207 \sa QPieSlice::clicked()
208 208 */
209 209
210 210 /*!
211 211 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
212 212
213 213 This signal is emitted when user has hovered over or away from the \a slice.
214 214
215 215 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
216 216
217 217 \sa QPieSlice::hovered()
218 218 */
219 219
220 220 /*!
221 221 Constructs a series object which is a child of \a parent.
222 222 */
223 223 QPieSeries::QPieSeries(QObject *parent) :
224 224 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
225 225 {
226 226
227 227 }
228 228
229 229 /*!
230 230 Destroys the series and its slices.
231 231 */
232 232 QPieSeries::~QPieSeries()
233 233 {
234 234 // NOTE: d_prt destroyed by QObject
235 235 }
236 236
237 237 /*!
238 238 Returns QChartSeries::SeriesTypePie.
239 239 */
240 240 QAbstractSeries::SeriesType QPieSeries::type() const
241 241 {
242 242 return QAbstractSeries::SeriesTypePie;
243 243 }
244 244
245 245 /*!
246 246 Appends a single \a slice to the series.
247 247 Slice ownership is passed to the series.
248 248
249 249 Returns true if append was succesfull.
250 250 */
251 251 bool QPieSeries::append(QPieSlice* slice)
252 252 {
253 253 return append(QList<QPieSlice*>() << slice);
254 254 }
255 255
256 256 /*!
257 257 Appends an array of \a slices to the series.
258 258 Slice ownership is passed to the series.
259 259
260 260 Returns true if append was successfull.
261 261 */
262 262 bool QPieSeries::append(QList<QPieSlice*> slices)
263 263 {
264 264 Q_D(QPieSeries);
265 265
266 266 if (slices.count() == 0)
267 267 return false;
268 268
269 269 foreach (QPieSlice* s, slices) {
270 270 if (!s || d->m_slices.contains(s))
271 271 return false;
272 272 }
273 273
274 274 foreach (QPieSlice* s, slices) {
275 275 s->setParent(this);
276 QPieSlicePrivate::fromSlice(s)->m_series = this;
276 277 d->m_slices << s;
277 278 }
278 279
279 280 d->updateDerivativeData();
280 281
281 282 foreach (QPieSlice* s, slices) {
282 283 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
283 284 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
284 285 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
285 286 }
286 287
287 288 emit added(slices);
288 289 emit countChanged();
289 290
290 291 return true;
291 292 }
292 293
293 294 /*!
294 295 Appends a single \a slice to the series and returns a reference to the series.
295 296 Slice ownership is passed to the series.
296 297 */
297 298 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
298 299 {
299 300 append(slice);
300 301 return *this;
301 302 }
302 303
303 304
304 305 /*!
305 306 Appends a single slice to the series with give \a value and \a label.
306 307 Slice ownership is passed to the series.
307 308 */
308 309 QPieSlice* QPieSeries::append(QString label, qreal value)
309 310 {
310 311 QPieSlice* slice = new QPieSlice(label, value);
311 312 append(slice);
312 313 return slice;
313 314 }
314 315
315 316 /*!
316 317 Inserts a single \a slice to the series before the slice at \a index position.
317 318 Slice ownership is passed to the series.
318 319
319 320 Returns true if insert was successfull.
320 321 */
321 322 bool QPieSeries::insert(int index, QPieSlice* slice)
322 323 {
323 324 Q_D(QPieSeries);
324 325
325 326 if (index < 0 || index > d->m_slices.count())
326 327 return false;
327 328
328 329 if (!slice || d->m_slices.contains(slice))
329 330 return false;
330 331
331 332 slice->setParent(this);
333 QPieSlicePrivate::fromSlice(slice)->m_series = this;
332 334 d->m_slices.insert(index, slice);
333 335
334 336 d->updateDerivativeData();
335 337
336 338 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
337 339 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
338 340 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
339 341
340 342 emit added(QList<QPieSlice*>() << slice);
341 343 emit countChanged();
342 344
343 345 return true;
344 346 }
345 347
346 348 /*!
347 349 Removes a single \a slice from the series and deletes the slice.
348 350
349 351 Do not reference the pointer after this call.
350 352
351 353 Returns true if remove was successfull.
352 354 */
353 355 bool QPieSeries::remove(QPieSlice* slice)
354 356 {
355 357 Q_D(QPieSeries);
356 358
357 359 if (!d->m_slices.removeOne(slice))
358 360 return false;
359 361
360 362 d->updateDerivativeData();
361 363
362 364 emit removed(QList<QPieSlice*>() << slice);
363 365 emit countChanged();
364 366
365 367 delete slice;
366 368 slice = 0;
367 369
368 370 return true;
369 371 }
370 372
371 373 /*!
372 374 Clears all slices from the series.
373 375 */
374 376 void QPieSeries::clear()
375 377 {
376 378 Q_D(QPieSeries);
377 379 if (d->m_slices.count() == 0)
378 380 return;
379 381
380 382 QList<QPieSlice*> slices = d->m_slices;
381 383 foreach (QPieSlice* s, d->m_slices) {
382 384 d->m_slices.removeOne(s);
383 385 delete s;
384 386 }
385 387
386 388 d->updateDerivativeData();
387 389
388 390 emit removed(slices);
389 391 emit countChanged();
390 392 }
391 393
392 394 /*!
393 395 Returns a list of slices that belong to this series.
394 396 */
395 397 QList<QPieSlice*> QPieSeries::slices() const
396 398 {
397 399 Q_D(const QPieSeries);
398 400 return d->m_slices;
399 401 }
400 402
401 403 /*!
402 404 returns the number of the slices in this series.
403 405 */
404 406 int QPieSeries::count() const
405 407 {
406 408 Q_D(const QPieSeries);
407 409 return d->m_slices.count();
408 410 }
409 411
410 412 /*!
411 413 Returns true is the series is empty.
412 414 */
413 415 bool QPieSeries::isEmpty() const
414 416 {
415 417 Q_D(const QPieSeries);
416 418 return d->m_slices.isEmpty();
417 419 }
418 420
419 421 /*!
420 422 Returns the sum of all slice values in this series.
421 423
422 424 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
423 425 */
424 426 qreal QPieSeries::sum() const
425 427 {
426 428 Q_D(const QPieSeries);
427 429 return d->m_sum;
428 430 }
429 431
430 432 void QPieSeries::setHorizontalPosition(qreal relativePosition)
431 433 {
432 434 Q_D(QPieSeries);
433 435
434 436 if (relativePosition < 0.0)
435 437 relativePosition = 0.0;
436 438 if (relativePosition > 1.0)
437 439 relativePosition = 1.0;
438 440
439 441 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
440 442 d->m_pieRelativeHorPos = relativePosition;
441 443 emit horizontalPositionChanged();
442 444 }
443 445 }
444 446
445 447 qreal QPieSeries::horizontalPosition() const
446 448 {
447 449 Q_D(const QPieSeries);
448 450 return d->m_pieRelativeHorPos;
449 451 }
450 452
451 453 void QPieSeries::setVerticalPosition(qreal relativePosition)
452 454 {
453 455 Q_D(QPieSeries);
454 456
455 457 if (relativePosition < 0.0)
456 458 relativePosition = 0.0;
457 459 if (relativePosition > 1.0)
458 460 relativePosition = 1.0;
459 461
460 462 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
461 463 d->m_pieRelativeVerPos = relativePosition;
462 464 emit verticalPositionChanged();
463 465 }
464 466 }
465 467
466 468 qreal QPieSeries::verticalPosition() const
467 469 {
468 470 Q_D(const QPieSeries);
469 471 return d->m_pieRelativeVerPos;
470 472 }
471 473
472 474 void QPieSeries::setPieSize(qreal relativeSize)
473 475 {
474 476 Q_D(QPieSeries);
475 477
476 478 if (relativeSize < 0.0)
477 479 relativeSize = 0.0;
478 480 if (relativeSize > 1.0)
479 481 relativeSize = 1.0;
480 482
481 483 if (!qFuzzyIsNull(d->m_pieRelativeSize - relativeSize)) {
482 484 d->m_pieRelativeSize = relativeSize;
483 485 emit pieSizeChanged();
484 486 }
485 487 }
486 488
487 489 qreal QPieSeries::pieSize() const
488 490 {
489 491 Q_D(const QPieSeries);
490 492 return d->m_pieRelativeSize;
491 493 }
492 494
493 495
494 496 void QPieSeries::setPieStartAngle(qreal angle)
495 497 {
496 498 Q_D(QPieSeries);
497 499 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
498 500 return;
499 501 d->m_pieStartAngle = angle;
500 502 d->updateDerivativeData();
501 503 emit pieStartAngleChanged();
502 504 }
503 505
504 506 qreal QPieSeries::pieStartAngle() const
505 507 {
506 508 Q_D(const QPieSeries);
507 509 return d->m_pieStartAngle;
508 510 }
509 511
510 512 /*!
511 513 Sets the end angle of the pie.
512 514
513 515 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
514 516
515 517 \a angle must be greater than start angle.
516 518
517 519 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
518 520 */
519 521 void QPieSeries::setPieEndAngle(qreal angle)
520 522 {
521 523 Q_D(QPieSeries);
522 524 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
523 525 return;
524 526 d->m_pieEndAngle = angle;
525 527 d->updateDerivativeData();
526 528 emit pieEndAngleChanged();
527 529 }
528 530
529 531 /*!
530 532 Returns the end angle of the pie.
531 533
532 534 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
533 535
534 536 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
535 537 */
536 538 qreal QPieSeries::pieEndAngle() const
537 539 {
538 540 Q_D(const QPieSeries);
539 541 return d->m_pieEndAngle;
540 542 }
541 543
542 544 /*!
543 545 Sets the all the slice labels \a visible or invisible.
544 546
545 547 Note that this affects only the current slices in the series.
546 548 If user adds a new slice the default label visibility is false.
547 549
548 550 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
549 551 */
550 552 void QPieSeries::setLabelsVisible(bool visible)
551 553 {
552 554 Q_D(QPieSeries);
553 555 foreach (QPieSlice* s, d->m_slices)
554 556 s->setLabelVisible(visible);
555 557 }
556 558
557 559 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
558 560
559 561
560 562 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
561 563 QAbstractSeriesPrivate(parent),
562 564 m_pieRelativeHorPos(0.5),
563 565 m_pieRelativeVerPos(0.5),
564 566 m_pieRelativeSize(0.7),
565 567 m_pieStartAngle(0),
566 568 m_pieEndAngle(360),
567 569 m_sum(0)
568 570 {
569 571 }
570 572
571 573 QPieSeriesPrivate::~QPieSeriesPrivate()
572 574 {
573 575 }
574 576
575 577 void QPieSeriesPrivate::updateDerivativeData()
576 578 {
577 579 // calculate sum of all slices
578 580 qreal sum = 0;
579 581 foreach (QPieSlice* s, m_slices)
580 582 sum += s->value();
581 583
582 584 if (!qFuzzyIsNull(m_sum - sum)) {
583 585 m_sum = sum;
584 586 emit q_func()->sumChanged();
585 587 }
586 588
587 589 // nothing to show..
588 590 if (qFuzzyIsNull(m_sum))
589 591 return;
590 592
591 593 // update slice attributes
592 594 qreal sliceAngle = m_pieStartAngle;
593 595 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
594 596 QVector<QPieSlice*> changed;
595 597 foreach (QPieSlice* s, m_slices) {
596 598 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
597 599 d->setPercentage(s->value() / m_sum);
598 600 d->setStartAngle(sliceAngle);
599 601 d->setAngleSpan(pieSpan * s->percentage());
600 602 sliceAngle += s->angleSpan();
601 603 }
602 604
603 605
604 606 emit calculatedDataChanged();
605 607 }
606 608
607 609 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
608 610 {
609 611 return series->d_func();
610 612 }
611 613
612 614 void QPieSeriesPrivate::sliceValueChanged()
613 615 {
614 616 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
615 617 updateDerivativeData();
616 618 }
617 619
618 620 void QPieSeriesPrivate::sliceClicked()
619 621 {
620 622 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
621 623 Q_ASSERT(m_slices.contains(slice));
622 624 Q_Q(QPieSeries);
623 625 emit q->clicked(slice);
624 626 }
625 627
626 628 void QPieSeriesPrivate::sliceHovered(bool state)
627 629 {
628 630 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
629 631 Q_ASSERT(m_slices.contains(slice));
630 632 Q_Q(QPieSeries);
631 633 emit q->hovered(slice, state);
632 634 }
633 635
634 636 void QPieSeriesPrivate::scaleDomain(Domain& domain)
635 637 {
636 638 Q_UNUSED(domain);
637 639 // does not apply to pie
638 640 }
639 641
640 642 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
641 643 {
642 644 Q_Q(QPieSeries);
643 645 PieChartItem* pie = new PieChartItem(q,presenter);
644 646 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
645 647 presenter->animator()->addAnimation(pie);
646 648 }
647 649 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
648 650 return pie;
649 651 }
650 652
651 653 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
652 654 {
653 655 Q_Q(QPieSeries);
654 656 QList<LegendMarker*> markers;
655 657 foreach(QPieSlice* slice, q->slices()) {
656 658 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
657 659 markers << marker;
658 660 }
659 661 return markers;
660 662 }
661 663
662 664 #include "moc_qpieseries.cpp"
663 665 #include "moc_qpieseries_p.cpp"
664 666
665 667 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,536 +1,547
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 "qpieslice.h"
22 22 #include "qpieslice_p.h"
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 /*!
27 27 \class QPieSlice
28 28 \brief Defines a slice in pie series.
29 29
30 30 This object defines the properties of a single slice in a QPieSeries.
31 31
32 32 In addition to the obvious value and label properties the user can also control
33 33 the visual appearance of a slice. By modifying the visual appearance also means that
34 34 the user is overriding the default appearance set by the theme.
35 35
36 36 Note that if the user has customized slices and theme is changed all customizations will be lost.
37 37
38 38 To enable user interaction with the pie some basic signals are provided about clicking and hovering.
39 39 */
40 40
41 41 /*!
42 42 \property QPieSlice::label
43 43
44 44 Label of the slice.
45 45
46 46 \sa labelVisible, labelBrush, labelFont, labelArmLengthFactor
47 47 */
48 48
49 49 /*!
50 50 \fn void QPieSlice::labelChanged()
51 51
52 52 This signal emitted when the slice label has been changed.
53 53
54 54 \sa label
55 55 */
56 56
57 57 /*!
58 58 \property QPieSlice::value
59 59
60 60 Value of the slice.
61 61
62 62 Note that if users sets a negative value it is converted to a positive value.
63 63
64 64 \sa percentage(), QPieSeries::sum()
65 65 */
66 66
67 67 /*!
68 68 \fn void QPieSlice::valueChanged()
69 69
70 70 This signal is emitted when the slice value changes.
71 71
72 72 \sa value
73 73 */
74 74
75 75 /*!
76 76 \property QPieSlice::labelVisible
77 77
78 78 Defienes the visibility of the slice label.
79 79
80 80 Default is not visible.
81 81
82 82 \sa label, labelBrush, labelFont, labelArmLengthFactor
83 83 */
84 84
85 85 /*!
86 86 \fn void QPieSlice::labelVisibleChanged()
87 87
88 88 This signal emitted when visibility of the slice label has changed.
89 89
90 90 \sa labelVisible
91 91 */
92 92
93 93 /*!
94 94 \property QPieSlice::exploded
95 95
96 96 Defines if the slice is exploded from the pie.
97 97
98 98 \sa explodeDistanceFactor
99 99 */
100 100
101 101 /*!
102 102 \fn void QPieSlice::explodedChanged()
103 103
104 104 This signal is emitted the the slice has been exploded from the pie or is returned back to the pie.
105 105
106 106 \sa exploded
107 107 */
108 108
109 109 /*!
110 110 \property QPieSlice::pen
111 111
112 112 Pen used to draw the slice border.
113 113 */
114 114
115 115 /*!
116 116 \fn void QPieSlice::penChanged()
117 117
118 118 This signal is emitted when the pen of the slice has changed.
119 119
120 120 \sa pen
121 121 */
122 122
123 123 /*!
124 124 \property QPieSlice::brush
125 125
126 126 Brush used to draw the slice.
127 127 */
128 128
129 129 /*!
130 130 \fn void QPieSlice::brushChanged()
131 131
132 132 This signal is emitted when the brush of the slice has changed.
133 133
134 134 \sa brush
135 135 */
136 136
137 137 /*!
138 138 \property QPieSlice::labelBrush
139 139
140 140 Pen used to draw label and label arm of the slice.
141 141
142 142 \sa label, labelVisible, labelFont, labelArmLengthFactor
143 143 */
144 144
145 145 /*!
146 146 \fn void QPieSlice::labelBrushChanged()
147 147
148 148 This signal is emitted when the label pen of the slice has changed.
149 149
150 150 \sa labelBrush
151 151 */
152 152
153 153 /*!
154 154 \property QPieSlice::labelFont
155 155
156 156 Font used for drawing label text.
157 157
158 158 \sa label, labelVisible, labelArmLengthFactor
159 159 */
160 160
161 161 /*!
162 162 \fn void QPieSlice::labelFontChanged()
163 163
164 164 This signal is emitted when the label font of the slice has changed.
165 165
166 166 \sa labelFont
167 167 */
168 168
169 169 /*!
170 170 \property QPieSlice::labelArmLengthFactor
171 171
172 172 Defines the length of the label arm.
173 173
174 174 The factor is relative to pie radius. For example:
175 175 1.0 means the length is the same as the radius.
176 176 0.5 means the length is half of the radius.
177 177
178 178 Default value is 0.15
179 179
180 180 \sa label, labelVisible, labelBrush, labelFont
181 181 */
182 182
183 183 /*!
184 184 \fn void QPieSlice::labelArmLengthFactorChanged()
185 185
186 186 This signal is emitted when the label arm factor of the slice has changed.
187 187
188 188 \sa labelArmLengthFactor
189 189 */
190 190
191 191 /*!
192 192 \property QPieSlice::explodeDistanceFactor
193 193
194 194 When the slice is exploded this factor defines how far the slice is exploded away from the pie.
195 195
196 196 The factor is relative to pie radius. For example:
197 197 1.0 means the distance is the same as the radius.
198 198 0.5 means the distance is half of the radius.
199 199
200 200 Default value is 0.15
201 201
202 202 \sa exploded
203 203 */
204 204
205 205 /*!
206 206 \fn void QPieSlice::explodeDistanceFactorChanged()
207 207
208 208 This signal is emitted when the explode distance factor of the slice has changed.
209 209
210 210 \sa explodeDistanceFactor
211 211 */
212 212
213 213 /*!
214 214 \property QPieSlice::percentage
215 215
216 216 Percentage of the slice compared to the sum of all slices in the series.
217 217
218 218 The actual value ranges from 0.0 to 1.0.
219 219
220 220 Updated automatically once the slice is added to the series.
221 221
222 222 \sa value, QPieSeries::sum
223 223 */
224 224
225 225 /*!
226 226 \fn void QPieSlice::percentageChanged()
227 227
228 228 This signal is emitted when the percentage of the slice has changed.
229 229
230 230 \sa percentage
231 231 */
232 232
233 233 /*!
234 234 \property QPieSlice::startAngle
235 235
236 236 Defines the starting angle of this slice in the series it belongs to.
237 237
238 238 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
239 239
240 240 Updated automatically once the slice is added to the series.
241 241 */
242 242
243 243 /*!
244 244 \fn void QPieSlice::startAngleChanged()
245 245
246 246 This signal is emitted when the starting angle f the slice has changed.
247 247
248 248 \sa startAngle
249 249 */
250 250
251 251 /*!
252 252 \property QPieSlice::angleSpan
253 253
254 254 Span of the slice in degrees.
255 255
256 256 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
257 257
258 258 Updated automatically once the slice is added to the series.
259 259 */
260 260
261 261 /*!
262 262 \fn void QPieSlice::angleSpanChanged()
263 263
264 264 This signal is emitted when the angle span of the slice has changed.
265 265
266 266 \sa angleSpan
267 267 */
268 268
269 269
270 270 /*!
271 271 \fn void QPieSlice::clicked()
272 272
273 273 This signal is emitted when user has clicked the slice.
274 274
275 275 \sa QPieSeries::clicked()
276 276 */
277 277
278 278 /*!
279 279 \fn void QPieSlice::hovered(bool state)
280 280
281 281 This signal is emitted when user has hovered over or away from the slice.
282 282
283 283 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
284 284
285 285 \sa QPieSeries::hovered()
286 286 */
287 287
288 288 /*!
289 289 Constructs an empty slice with a \a parent.
290 290
291 291 \sa QPieSeries::append(), QPieSeries::insert()
292 292 */
293 293 QPieSlice::QPieSlice(QObject *parent)
294 294 :QObject(parent),
295 295 d_ptr(new QPieSlicePrivate(this))
296 296 {
297 297
298 298 }
299 299
300 300 /*!
301 301 Constructs an empty slice with given \a value, \a label and a \a parent.
302 302 \sa QPieSeries::append(), QPieSeries::insert()
303 303 */
304 304 QPieSlice::QPieSlice(QString label, qreal value, QObject *parent)
305 305 :QObject(parent),
306 306 d_ptr(new QPieSlicePrivate(this))
307 307 {
308 308 setValue(value);
309 309 setLabel(label);
310 310 }
311 311
312 312 /*!
313 313 Destroys the slice.
314 314 User should not delete the slice if it has been added to the series.
315 315 */
316 316 QPieSlice::~QPieSlice()
317 317 {
318 318
319 319 }
320 320
321 321 void QPieSlice::setLabel(QString label)
322 322 {
323 323 if (d_ptr->m_data.m_labelText != label) {
324 324 d_ptr->m_data.m_labelText = label;
325 325 emit labelChanged();
326 326 }
327 327 }
328 328
329 329 QString QPieSlice::label() const
330 330 {
331 331 return d_ptr->m_data.m_labelText;
332 332 }
333 333
334 334 void QPieSlice::setValue(qreal value)
335 335 {
336 336 value = qAbs(value); // negative values not allowed
337 337 if (!qFuzzyIsNull(d_ptr->m_data.m_value - value)) {
338 338 d_ptr->m_data.m_value = value;
339 339 emit valueChanged();
340 340 }
341 341 }
342 342
343 343 qreal QPieSlice::value() const
344 344 {
345 345 return d_ptr->m_data.m_value;
346 346 }
347 347
348 348 void QPieSlice::setLabelVisible(bool visible)
349 349 {
350 350 if (d_ptr->m_data.m_isLabelVisible != visible) {
351 351 d_ptr->m_data.m_isLabelVisible = visible;
352 352 emit labelVisibleChanged();
353 353 }
354 354 }
355 355
356 356 bool QPieSlice::isLabelVisible() const
357 357 {
358 358 return d_ptr->m_data.m_isLabelVisible;
359 359 }
360 360
361 361 void QPieSlice::setExploded(bool exploded)
362 362 {
363 363 if (d_ptr->m_data.m_isExploded != exploded) {
364 364 d_ptr->m_data.m_isExploded = exploded;
365 365 emit explodedChanged();
366 366 }
367 367 }
368 368
369 369 bool QPieSlice::isExploded() const
370 370 {
371 371 return d_ptr->m_data.m_isExploded;
372 372 }
373 373
374 374 void QPieSlice::setPen(const QPen &pen)
375 375 {
376 376 d_ptr->setPen(pen, false);
377 377 }
378 378
379 379 QPen QPieSlice::pen() const
380 380 {
381 381 return d_ptr->m_data.m_slicePen;
382 382 }
383 383
384 384 void QPieSlice::setBrush(const QBrush &brush)
385 385 {
386 386 d_ptr->setBrush(brush, false);
387 387 }
388 388
389 389 QBrush QPieSlice::brush() const
390 390 {
391 391 return d_ptr->m_data.m_sliceBrush;
392 392 }
393 393
394 394 void QPieSlice::setLabelBrush(const QBrush &brush)
395 395 {
396 396 d_ptr->setLabelBrush(brush, false);
397 397 }
398 398
399 399 QBrush QPieSlice::labelBrush() const
400 400 {
401 401 return d_ptr->m_data.m_labelBrush;
402 402 }
403 403
404 404 void QPieSlice::setLabelFont(const QFont &font)
405 405 {
406 406 d_ptr->setLabelFont(font, false);
407 407 }
408 408
409 409 QFont QPieSlice::labelFont() const
410 410 {
411 411 return d_ptr->m_data.m_labelFont;
412 412 }
413 413
414 414 void QPieSlice::setLabelArmLengthFactor(qreal factor)
415 415 {
416 416 if (!qFuzzyIsNull(d_ptr->m_data.m_labelArmLengthFactor - factor)) {
417 417 d_ptr->m_data.m_labelArmLengthFactor = factor;
418 418 emit labelArmLengthFactorChanged();
419 419 }
420 420 }
421 421
422 422 qreal QPieSlice::labelArmLengthFactor() const
423 423 {
424 424 return d_ptr->m_data.m_labelArmLengthFactor;
425 425 }
426 426
427 427 void QPieSlice::setExplodeDistanceFactor(qreal factor)
428 428 {
429 429 if (!qFuzzyIsNull(d_ptr->m_data.m_explodeDistanceFactor - factor)) {
430 430 d_ptr->m_data.m_explodeDistanceFactor = factor;
431 431 emit explodeDistanceFactorChanged();
432 432 }
433 433 }
434 434
435 435 qreal QPieSlice::explodeDistanceFactor() const
436 436 {
437 437 return d_ptr->m_data.m_explodeDistanceFactor;
438 438 }
439 439
440 440 qreal QPieSlice::percentage() const
441 441 {
442 442 return d_ptr->m_data.m_percentage;
443 443 }
444 444
445 445 qreal QPieSlice::startAngle() const
446 446 {
447 447 return d_ptr->m_data.m_startAngle;
448 448 }
449 449
450 450 qreal QPieSlice::angleSpan() const
451 451 {
452 452 return d_ptr->m_data.m_angleSpan;
453 453 }
454 454
455 /*!
456 Returns the series that this slice belongs to.
457
458 \sa QPieSeries::append()
459 */
460 QPieSeries *QPieSlice::series() const
461 {
462 return d_ptr->m_series;
463 }
464
455 465 QPieSlicePrivate::QPieSlicePrivate(QPieSlice *parent)
456 466 :QObject(parent),
457 q_ptr(parent)
467 q_ptr(parent),
468 m_series(0)
458 469 {
459 470
460 471 }
461 472
462 473 QPieSlicePrivate::~QPieSlicePrivate()
463 474 {
464 475
465 476 }
466 477
467 478 QPieSlicePrivate *QPieSlicePrivate::fromSlice(QPieSlice *slice)
468 479 {
469 480 return slice->d_func();
470 481 }
471 482
472 483 void QPieSlicePrivate::setPen(const QPen &pen, bool themed)
473 484 {
474 485 if (m_data.m_slicePen != pen) {
475 486 m_data.m_slicePen = pen;
476 487 m_data.m_slicePen.setThemed(themed);
477 488 emit q_ptr->penChanged();
478 489 }
479 490 }
480 491
481 492 void QPieSlicePrivate::setBrush(const QBrush &brush, bool themed)
482 493 {
483 494 if (m_data.m_sliceBrush != brush) {
484 495 m_data.m_sliceBrush = brush;
485 496 m_data.m_sliceBrush.setThemed(themed);
486 497 emit q_ptr->brushChanged();
487 498 }
488 499 }
489 500
490 501 void QPieSlicePrivate::setLabelBrush(const QBrush &brush, bool themed)
491 502 {
492 503 if (m_data.m_labelBrush != brush) {
493 504 m_data.m_labelBrush = brush;
494 505 m_data.m_labelBrush.setThemed(themed);
495 506 emit q_ptr->labelBrushChanged();
496 507 }
497 508 }
498 509
499 510 void QPieSlicePrivate::setLabelFont(const QFont &font, bool themed)
500 511 {
501 512 if (m_data.m_labelFont != font) {
502 513 m_data.m_labelFont = font;
503 514 m_data.m_labelFont.setThemed(themed);
504 515 emit q_ptr->labelFontChanged();
505 516 }
506 517 }
507 518
508 519 void QPieSlicePrivate::setPercentage(qreal percentage)
509 520 {
510 521 if (!qFuzzyIsNull(m_data.m_percentage - percentage)) {
511 522 m_data.m_percentage = percentage;
512 523 emit q_ptr->percentageChanged();
513 524 }
514 525 }
515 526
516 527 void QPieSlicePrivate::setStartAngle(qreal angle)
517 528 {
518 529 if (!qFuzzyIsNull(m_data.m_startAngle - angle)) {
519 530 m_data.m_startAngle = angle;
520 531 emit q_ptr->startAngleChanged();
521 532 }
522 533 }
523 534
524 535 void QPieSlicePrivate::setAngleSpan(qreal span)
525 536 {
526 537 if (!qFuzzyIsNull(m_data.m_angleSpan - span)) {
527 538 m_data.m_angleSpan = span;
528 539 emit q_ptr->angleSpanChanged();
529 540 }
530 541 }
531 542
532 543 QTCOMMERCIALCHART_END_NAMESPACE
533 544
534 545 QTCOMMERCIALCHART_USE_NAMESPACE
535 546 #include "moc_qpieslice.cpp"
536 547 #include "moc_qpieslice_p.cpp"
@@ -1,114 +1,117
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 QPIESLICE_H
22 22 #define QPIESLICE_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QObject>
26 26 #include <QPen>
27 27 #include <QBrush>
28 28 #include <QFont>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31 class QPieSlicePrivate;
32 class QPieSeries;
32 33
33 34 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
34 35 {
35 36 Q_OBJECT
36 37 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
37 38 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
38 39 Q_PROPERTY(bool labelVisible READ isLabelVisible WRITE setLabelVisible NOTIFY labelVisibleChanged)
39 40 Q_PROPERTY(bool exploded READ isExploded WRITE setExploded NOTIFY explodedChanged)
40 41 Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
41 42 Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
42 43 Q_PROPERTY(QBrush labelBrush READ labelBrush WRITE setLabelBrush NOTIFY labelBrushChanged)
43 44 Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont NOTIFY labelFontChanged)
44 45 Q_PROPERTY(qreal labelArmLengthFactor READ labelArmLengthFactor WRITE setLabelArmLengthFactor)
45 46 Q_PROPERTY(qreal explodeDistanceFactor READ explodeDistanceFactor WRITE setExplodeDistanceFactor)
46 47 Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
47 48 Q_PROPERTY(qreal startAngle READ startAngle NOTIFY startAngleChanged)
48 49 Q_PROPERTY(qreal angleSpan READ angleSpan NOTIFY angleSpanChanged)
49 50
50 51 public:
51 52 explicit QPieSlice(QObject *parent = 0);
52 53 QPieSlice(QString label, qreal value, QObject *parent = 0);
53 54 virtual ~QPieSlice();
54 55
55 56 void setLabel(QString label);
56 57 QString label() const;
57 58
58 59 void setValue(qreal value);
59 60 qreal value() const;
60 61
61 62 void setLabelVisible(bool visible = true);
62 63 bool isLabelVisible() const;
63 64
64 65 void setExploded(bool exploded = true);
65 66 bool isExploded() const;
66 67
67 68 void setPen(const QPen &pen);
68 69 QPen pen() const;
69 70
70 71 void setBrush(const QBrush &brush);
71 72 QBrush brush() const;
72 73
73 74 void setLabelBrush(const QBrush &brush);
74 75 QBrush labelBrush() const;
75 76
76 77 void setLabelFont(const QFont &font);
77 78 QFont labelFont() const;
78 79
79 80 void setLabelArmLengthFactor(qreal factor);
80 81 qreal labelArmLengthFactor() const;
81 82
82 83 void setExplodeDistanceFactor(qreal factor);
83 84 qreal explodeDistanceFactor() const;
84 85
85 86 qreal percentage() const;
86 87 qreal startAngle() const;
87 88 qreal angleSpan() const;
88 89
90 QPieSeries *series() const;
91
89 92 Q_SIGNALS:
90 93 void labelChanged();
91 94 void valueChanged();
92 95 void labelVisibleChanged();
93 96 void explodedChanged();
94 97 void penChanged();
95 98 void brushChanged();
96 99 void labelBrushChanged();
97 100 void labelFontChanged();
98 101 void labelArmLengthFactorChanged();
99 102 void explodeDistanceFactorChanged();
100 103 void percentageChanged();
101 104 void startAngleChanged();
102 105 void angleSpanChanged();
103 106 void clicked();
104 107 void hovered(bool state);
105 108
106 109 private:
107 110 QPieSlicePrivate * const d_ptr;
108 111 Q_DECLARE_PRIVATE(QPieSlice)
109 112 Q_DISABLE_COPY(QPieSlice)
110 113 };
111 114
112 115 QTCOMMERCIALCHART_END_NAMESPACE
113 116
114 117 #endif // QPIESLICE_H
@@ -1,43 +1,45
1 1 #ifndef QPIESLICE_P_H
2 2 #define QPIESLICE_P_H
3 3
4 4 #include <QObject>
5 5 #include "qpieslice.h"
6 6 #include "pieslicedata_p.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 class QPieSeries;
9 10
10 11 class QPieSlicePrivate : public QObject
11 12 {
12 13 Q_OBJECT
13 14
14 15 public:
15 16 QPieSlicePrivate(QPieSlice *parent);
16 17 ~QPieSlicePrivate();
17 18
18 19 static QPieSlicePrivate* fromSlice(QPieSlice *slice);
19 20
20 21 void setPen(const QPen &pen, bool themed);
21 22 void setBrush(const QBrush &brush, bool themed);
22 23 void setLabelBrush(const QBrush &brush, bool themed);
23 24 void setLabelFont(const QFont &font, bool themed);
24 25
25 26 void setPercentage(qreal percentage);
26 27 void setStartAngle(qreal angle);
27 28 void setAngleSpan(qreal span);
28 29
29 30 private:
30 PieSliceData m_data;
31
32 private:
31 friend class QPieSeries;
33 32 friend class QPieSeriesPrivate;
34 33 friend class ChartTheme;
35 34 friend class PieChartItem;
36 35
37 36 QPieSlice * const q_ptr;
38 37 Q_DECLARE_PUBLIC(QPieSlice)
38
39 PieSliceData m_data;
40 QPieSeries *m_series;
39 41 };
40 42
41 43 QTCOMMERCIALCHART_END_NAMESPACE
42 44
43 45 #endif // QPIESLICE_P_H
@@ -1,537 +1,555
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 <QtTest/QtTest>
22 22 #include <qchartview.h>
23 23 #include <qchart.h>
24 24 #include <qpieseries.h>
25 25 #include <qpieslice.h>
26 26 #include <qpiemodelmapper.h>
27 27 #include <QStandardItemModel>
28 28 #include <tst_definitions.h>
29 29
30 30 QTCOMMERCIALCHART_USE_NAMESPACE
31 31
32 32 Q_DECLARE_METATYPE(QPieSlice*)
33 33 Q_DECLARE_METATYPE(QList<QPieSlice*>)
34 34
35 35 class tst_qpieseries : public QObject
36 36 {
37 37 Q_OBJECT
38 38
39 39 public slots:
40 40 void initTestCase();
41 41 void cleanupTestCase();
42 42 void init();
43 43 void cleanup();
44 44
45 45 private slots:
46 46 void properties();
47 47 void append();
48 48 void appendAnimated();
49 49 void insert();
50 50 void insertAnimated();
51 51 void remove();
52 52 void removeAnimated();
53 53 void calculatedValues();
54 54 void clickedSignal();
55 55 void hoverSignal();
56 void sliceSeries();
56 57
57 58 private:
58 59 void verifyCalculatedData(const QPieSeries &series, bool *ok);
59 60
60 61 private:
61 62 QChartView *m_view;
62 63 QPieSeries *m_series;
63 64 };
64 65
65 66 void tst_qpieseries::initTestCase()
66 67 {
67 68 qRegisterMetaType<QPieSlice*>("QPieSlice*");
68 69 qRegisterMetaType<QList<QPieSlice*> >("QList<QPieSlice*>");
69 70 }
70 71
71 72 void tst_qpieseries::cleanupTestCase()
72 73 {
73 74 }
74 75
75 76 void tst_qpieseries::init()
76 77 {
77 78 m_view = new QChartView();
78 79 m_series = new QPieSeries(m_view);
79 80 }
80 81
81 82 void tst_qpieseries::cleanup()
82 83 {
83 84 delete m_view;
84 85 m_view = 0;
85 86 m_series = 0;
86 87 }
87 88
88 89 void tst_qpieseries::properties()
89 90 {
90 91 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
91 92 QSignalSpy sumSpy(m_series, SIGNAL(sumChanged()));
92 93 QSignalSpy sizeSpy(m_series, SIGNAL(pieSizeChanged()));
93 94 QSignalSpy startAngleSpy(m_series, SIGNAL(pieStartAngleChanged()));
94 95 QSignalSpy endAngleSpy(m_series, SIGNAL(pieEndAngleChanged()));
95 96 QSignalSpy horPosSpy(m_series, SIGNAL(horizontalPositionChanged()));
96 97 QSignalSpy verPosSpy(m_series, SIGNAL(verticalPositionChanged()));
97 98
98 99 QVERIFY(m_series->type() == QAbstractSeries::SeriesTypePie);
99 100 QVERIFY(m_series->count() == 0);
100 101 QVERIFY(m_series->isEmpty());
101 102 QCOMPARE(m_series->sum(), 0.0);
102 103 QCOMPARE(m_series->horizontalPosition(), 0.5);
103 104 QCOMPARE(m_series->verticalPosition(), 0.5);
104 105 QCOMPARE(m_series->pieSize(), 0.7);
105 106 QCOMPARE(m_series->pieStartAngle(), 0.0);
106 107 QCOMPARE(m_series->pieEndAngle(), 360.0);
107 108
108 109 m_series->append("s1", 1);
109 110 m_series->append("s2", 1);
110 111 m_series->append("s3", 1);
111 112 m_series->insert(1, new QPieSlice("s4", 1));
112 113 m_series->remove(m_series->slices().first());
113 114 QCOMPARE(m_series->count(), 3);
114 115 QCOMPARE(m_series->sum(), 3.0);
115 116 m_series->clear();
116 117 QCOMPARE(m_series->count(), 0);
117 118 QCOMPARE(m_series->sum(), 0.0);
118 119 QCOMPARE(countSpy.count(), 6);
119 120 QCOMPARE(sumSpy.count(), 6);
120 121
121 122 m_series->setPieSize(-1.0);
122 123 QCOMPARE(m_series->pieSize(), 0.0);
123 124 m_series->setPieSize(0.0);
124 125 m_series->setPieSize(0.9);
125 126 m_series->setPieSize(2.0);
126 127 QCOMPARE(m_series->pieSize(), 1.0);
127 128 QCOMPARE(sizeSpy.count(), 3);
128 129
129 130 m_series->setPieStartAngle(0);
130 131 m_series->setPieStartAngle(-180);
131 132 m_series->setPieStartAngle(180);
132 133 QCOMPARE(startAngleSpy.count(), 2);
133 134
134 135 m_series->setPieEndAngle(360);
135 136 m_series->setPieEndAngle(-180);
136 137 m_series->setPieEndAngle(180);
137 138 QCOMPARE(endAngleSpy.count(), 2);
138 139
139 140 m_series->setHorizontalPosition(0.5);
140 141 m_series->setHorizontalPosition(-1.0);
141 142 QCOMPARE(m_series->horizontalPosition(), 0.0);
142 143 m_series->setHorizontalPosition(1.0);
143 144 m_series->setHorizontalPosition(2.0);
144 145 QCOMPARE(m_series->horizontalPosition(), 1.0);
145 146 QCOMPARE(horPosSpy.count(), 2);
146 147
147 148 m_series->setVerticalPosition(0.5);
148 149 m_series->setVerticalPosition(-1.0);
149 150 QCOMPARE(m_series->verticalPosition(), 0.0);
150 151 m_series->setVerticalPosition(1.0);
151 152 m_series->setVerticalPosition(2.0);
152 153 QCOMPARE(m_series->verticalPosition(), 1.0);
153 154 QCOMPARE(verPosSpy.count(), 2);
154 155 }
155 156
156 157 void tst_qpieseries::append()
157 158 {
158 159 m_view->chart()->addSeries(m_series);
159 160 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
160 161
161 162 // append pointer
162 163 QPieSlice *slice1 = 0;
163 164 QVERIFY(!m_series->append(slice1));
164 165 slice1 = new QPieSlice("slice 1", 1);
165 166 QVERIFY(m_series->append(slice1));
166 167 QVERIFY(!m_series->append(slice1));
167 168 QCOMPARE(m_series->count(), 1);
168 169 QCOMPARE(addedSpy.count(), 1);
169 170 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(0).at(0));
170 171 QCOMPARE(added.count(), 1);
171 172 QCOMPARE(added.first(), slice1);
172 173
173 174 // append pointer list
174 175 QList<QPieSlice *> list;
175 176 QVERIFY(!m_series->append(list));
176 177 list << (QPieSlice *) 0;
177 178 QVERIFY(!m_series->append(list));
178 179 list.clear();
179 180 list << new QPieSlice("slice 2", 2);
180 181 list << new QPieSlice("slice 3", 3);
181 182 QVERIFY(m_series->append(list));
182 183 QVERIFY(!m_series->append(list));
183 184 QCOMPARE(m_series->count(), 3);
184 185 QCOMPARE(addedSpy.count(), 2);
185 186 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(1).at(0));
186 187 QCOMPARE(added.count(), 2);
187 188 QCOMPARE(added, list);
188 189
189 190 // append operator
190 191 QPieSlice *slice4 = new QPieSlice("slice 4", 4);
191 192 *m_series << slice4;
192 193 *m_series << slice1; // fails because already added
193 194 QCOMPARE(m_series->count(), 4);
194 195 QCOMPARE(addedSpy.count(), 3);
195 196 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(2).at(0));
196 197 QCOMPARE(added.count(), 1);
197 198 QCOMPARE(added.first(), slice4);
198 199
199 200 // append with params
200 201 QPieSlice *slice5 = m_series->append("slice 5", 5);
201 202 QVERIFY(slice5 != 0);
202 203 QCOMPARE(slice5->value(), 5.0);
203 204 QCOMPARE(slice5->label(), QString("slice 5"));
204 205 QCOMPARE(m_series->count(), 5);
205 206 QCOMPARE(addedSpy.count(), 4);
206 207 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(3).at(0));
207 208 QCOMPARE(added.count(), 1);
208 209 QCOMPARE(added.first(), slice5);
209 210
210 211 // check slices
211 212 QVERIFY(!m_series->isEmpty());
212 213 for (int i=0; i<m_series->count(); i++) {
213 214 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
214 215 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
215 216 }
216 217 }
217 218
218 219 void tst_qpieseries::appendAnimated()
219 220 {
220 221 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
221 222 }
222 223
223 224 void tst_qpieseries::insert()
224 225 {
225 226 m_view->chart()->addSeries(m_series);
226 227 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
227 228
228 229 // insert one slice
229 230 QPieSlice *slice1 = 0;
230 231 QVERIFY(!m_series->insert(0, slice1));
231 232 slice1 = new QPieSlice("slice 1", 1);
232 233 QVERIFY(!m_series->insert(-1, slice1));
233 234 QVERIFY(!m_series->insert(5, slice1));
234 235 QVERIFY(m_series->insert(0, slice1));
235 236 QVERIFY(!m_series->insert(0, slice1));
236 237 QCOMPARE(m_series->count(), 1);
237 238 QCOMPARE(addedSpy.count(), 1);
238 239 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(0).at(0));
239 240 QCOMPARE(added.count(), 1);
240 241 QCOMPARE(added.first(), slice1);
241 242
242 243 // add some more slices
243 244 QPieSlice *slice2 = m_series->append("slice 2", 2);
244 245 QPieSlice *slice4 = m_series->append("slice 4", 4);
245 246 QCOMPARE(m_series->count(), 3);
246 247 QCOMPARE(addedSpy.count(), 3);
247 248 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(1).at(0));
248 249 QCOMPARE(added.count(), 1);
249 250 QCOMPARE(added.first(), slice2);
250 251 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(2).at(0));
251 252 QCOMPARE(added.count(), 1);
252 253 QCOMPARE(added.first(), slice4);
253 254
254 255 // insert between slices
255 256 QPieSlice *slice3 = new QPieSlice("slice 3", 3);
256 257 m_series->insert(2, slice3);
257 258 QCOMPARE(m_series->count(), 4);
258 259 QCOMPARE(addedSpy.count(), 4);
259 260 added = qvariant_cast<QList<QPieSlice*> >(addedSpy.at(3).at(0));
260 261 QCOMPARE(added.count(), 1);
261 262 QCOMPARE(added.first(), slice3);
262 263
263 264 // check slices
264 265 for (int i=0; i<m_series->count(); i++) {
265 266 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
266 267 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
267 268 }
268 269 }
269 270
270 271 void tst_qpieseries::insertAnimated()
271 272 {
272 273 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
273 274 }
274 275
275 276 void tst_qpieseries::remove()
276 277 {
277 278 m_view->chart()->addSeries(m_series);
278 279 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
279 280
280 281 // add some slices
281 282 QPieSlice *slice1 = m_series->append("slice 1", 1);
282 283 QPieSlice *slice2 = m_series->append("slice 2", 2);
283 284 QPieSlice *slice3 = m_series->append("slice 3", 3);
284 285 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
285 286 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
286 287 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
287 288 QCOMPARE(m_series->count(), 3);
288 289
289 290 // null pointer remove
290 291 QVERIFY(!m_series->remove(0));
291 292
292 293 // remove first
293 294 QVERIFY(m_series->remove(slice1));
294 295 QVERIFY(!m_series->remove(slice1));
295 296 QCOMPARE(m_series->count(), 2);
296 297 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
297 298 QCOMPARE(removedSpy.count(), 1);
298 299 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(0).at(0));
299 300 QCOMPARE(removed.count(), 1);
300 301 QCOMPARE(removed.first(), slice1);
301 302
302 303 // remove all
303 304 m_series->clear();
304 305 QVERIFY(m_series->isEmpty());
305 306 QVERIFY(m_series->slices().isEmpty());
306 307 QCOMPARE(m_series->count(), 0);
307 308 QCOMPARE(removedSpy.count(), 2);
308 309 removed = qvariant_cast<QList<QPieSlice*> >(removedSpy.at(1).at(0));
309 310 QCOMPARE(removed.count(), 2);
310 311 QCOMPARE(removed.first(), slice2);
311 312 QCOMPARE(removed.last(), slice3);
312 313
313 314 // check that slices were actually destroyed
314 315 TRY_COMPARE(spy1.count(), 1);
315 316 TRY_COMPARE(spy2.count(), 1);
316 317 TRY_COMPARE(spy3.count(), 1);
317 318 }
318 319
319 320 void tst_qpieseries::removeAnimated()
320 321 {
321 322 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
322 323 }
323 324
324 325 void tst_qpieseries::calculatedValues()
325 326 {
326 327 m_view->chart()->addSeries(m_series);
327 328
328 329 QPieSlice *slice1 = new QPieSlice("slice 1", 1);
329 330 QSignalSpy percentageSpy(slice1, SIGNAL(percentageChanged()));
330 331 QSignalSpy startAngleSpy(slice1, SIGNAL(startAngleChanged()));
331 332 QSignalSpy angleSpanSpy(slice1, SIGNAL(angleSpanChanged()));
332 333
333 334 // add a slice
334 335 m_series->append(slice1);
335 336 bool ok;
336 337 verifyCalculatedData(*m_series, &ok);
337 338 if (!ok)
338 339 return;
339 340 QCOMPARE(percentageSpy.count(), 1);
340 341 QCOMPARE(startAngleSpy.count(), 0);
341 342 QCOMPARE(angleSpanSpy.count(), 1);
342 343
343 344 // add some more slices
344 345 QList<QPieSlice *> list;
345 346 list << new QPieSlice("slice 2", 2);
346 347 list << new QPieSlice("slice 3", 3);
347 348 m_series->append(list);
348 349 verifyCalculatedData(*m_series, &ok);
349 350 if (!ok)
350 351 return;
351 352 QCOMPARE(percentageSpy.count(), 2);
352 353 QCOMPARE(startAngleSpy.count(), 0);
353 354 QCOMPARE(angleSpanSpy.count(), 2);
354 355
355 356 // remove a slice
356 357 m_series->remove(list.first()); // remove slice 2
357 358 verifyCalculatedData(*m_series, &ok);
358 359 if (!ok)
359 360 return;
360 361 QCOMPARE(percentageSpy.count(), 3);
361 362 QCOMPARE(startAngleSpy.count(), 0);
362 363 QCOMPARE(angleSpanSpy.count(), 3);
363 364
364 365 // insert a slice
365 366 m_series->insert(0, new QPieSlice("Slice 4", 4));
366 367 verifyCalculatedData(*m_series, &ok);
367 368 if (!ok)
368 369 return;
369 370 QCOMPARE(percentageSpy.count(), 4);
370 371 QCOMPARE(startAngleSpy.count(), 1);
371 372 QCOMPARE(angleSpanSpy.count(), 4);
372 373
373 374 // modify pie angles
374 375 m_series->setPieStartAngle(-90);
375 376 m_series->setPieEndAngle(90);
376 377 verifyCalculatedData(*m_series, &ok);
377 378 if (!ok)
378 379 return;
379 380 QCOMPARE(percentageSpy.count(), 4);
380 381 QCOMPARE(startAngleSpy.count(), 3);
381 382 QCOMPARE(angleSpanSpy.count(), 6);
382 383
383 384 // clear all
384 385 m_series->clear();
385 386 verifyCalculatedData(*m_series, &ok);
386 387 if (!ok)
387 388 return;
388 389 QCOMPARE(percentageSpy.count(), 4);
389 390 QCOMPARE(startAngleSpy.count(), 3);
390 391 QCOMPARE(angleSpanSpy.count(), 6);
391 392 }
392 393
393 394 void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
394 395 {
395 396 *ok = false;
396 397
397 398 qreal sum = 0;
398 399 foreach (const QPieSlice *slice, series.slices())
399 400 sum += slice->value();
400 401 QCOMPARE(series.sum(), sum);
401 402
402 403 qreal startAngle = series.pieStartAngle();
403 404 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
404 405 foreach (const QPieSlice *slice, series.slices()) {
405 406 qreal ratio = slice->value() / sum;
406 407 qreal sliceSpan = pieAngleSpan * ratio;
407 408 QCOMPARE(slice->startAngle(), startAngle);
408 409 QCOMPARE(slice->angleSpan(), sliceSpan);
409 410 QCOMPARE(slice->percentage(), ratio);
410 411 startAngle += sliceSpan;
411 412 }
412 413
413 414 if (!series.isEmpty())
414 415 QCOMPARE(series.slices().last()->startAngle() + series.slices().last()->angleSpan(), series.pieEndAngle());
415 416
416 417 *ok = true;
417 418 }
418 419
419 420
420 421 void tst_qpieseries::clickedSignal()
421 422 {
422 423 // add some slices
423 424 QPieSlice *s1 = m_series->append("slice 1", 1);
424 425 QPieSlice *s2 = m_series->append("slice 2", 1);
425 426 QPieSlice *s3 = m_series->append("slice 3", 1);
426 427 QPieSlice *s4 = m_series->append("slice 4", 1);
427 428 QSignalSpy clickSpy(m_series, SIGNAL(clicked(QPieSlice*)));
428 429
429 430 // add series to the chart
430 431 m_view->chart()->legend()->setVisible(false);
431 432 m_view->resize(200, 200);
432 433 m_view->chart()->addSeries(m_series);
433 434 m_view->show();
434 435 QTest::qWaitForWindowShown(m_view);
435 436
436 437 // if you devide the chart in four equal tiles these
437 438 // are the center points of those tiles
438 439 QPoint p1(90.25, 90);
439 440 QPoint p2(150, 90);
440 441 QPoint p3(90, 150);
441 442 QPoint p4(150, 150);
442 443
443 444 QPoint center(120, 120);
444 445
445 446 m_series->setPieSize(1.0);
446 447 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
447 448 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
448 449 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
449 450 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
450 451 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
451 452 TRY_COMPARE(clickSpy.count(), 5); // all hit
452 453 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s4);
453 454 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s1);
454 455 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
455 456 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s2);
456 457 clickSpy.clear();
457 458
458 459 m_series->setPieSize(0.5);
459 460 m_series->setVerticalPosition(0.25);
460 461 m_series->setHorizontalPosition(0.25);
461 462 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1); // hits
462 463 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
463 464 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
464 465 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
465 466 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
466 467 TRY_COMPARE(clickSpy.count(), 1);
467 468 clickSpy.clear();
468 469
469 470 m_series->setVerticalPosition(0.25);
470 471 m_series->setHorizontalPosition(0.75);
471 472 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
472 473 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2); // hits
473 474 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
474 475 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
475 476 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
476 477 TRY_COMPARE(clickSpy.count(), 1);
477 478 clickSpy.clear();
478 479
479 480 m_series->setVerticalPosition(0.75);
480 481 m_series->setHorizontalPosition(0.25);
481 482 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
482 483 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
483 484 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3); // hits
484 485 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4);
485 486 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
486 487 TRY_COMPARE(clickSpy.count(), 1);
487 488 clickSpy.clear();
488 489
489 490 m_series->setVerticalPosition(0.75);
490 491 m_series->setHorizontalPosition(0.75);
491 492 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p1);
492 493 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p2);
493 494 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p3);
494 495 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, p4); // hits
495 496 QTest::mouseClick(m_view->viewport(), Qt::LeftButton, 0, center);
496 497 TRY_COMPARE(clickSpy.count(), 1);
497 498 clickSpy.clear();
498 499 }
499 500
500 501 void tst_qpieseries::hoverSignal()
501 502 {
502 503 // add some slices
503 504 m_series->setPieSize(1.0);
504 505 QPieSlice *s1 = m_series->append("slice 1", 1);
505 506 m_series->append("slice 2", 2);
506 507 m_series->append("slice 3", 3);
507 508
508 509 // add series to the chart
509 510 m_view->chart()->legend()->setVisible(false);
510 511 m_view->resize(200, 200);
511 512 m_view->chart()->addSeries(m_series);
512 513 m_view->show();
513 514 QTest::qWaitForWindowShown(m_view);
514 515
515 516 // first move to right top corner
516 517 QTest::mouseMove(m_view->viewport(), QPoint(200, 0));
517 518 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
518 519
519 520 // move inside the slice
520 521 // pie rectangle: QRectF(60,60 121x121)
521 522 QSignalSpy hoverSpy(m_series, SIGNAL(hovered(QPieSlice*,bool)));
522 523 QTest::mouseMove(m_view->viewport(), QPoint(139, 85));
523 524 TRY_COMPARE(hoverSpy.count(), 1);
524 525 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(0).at(0)), s1);
525 526 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(0).at(1)), true);
526 527
527 528 // move outside the slice
528 529 QTest::mouseMove(m_view->viewport(), QPoint(200, 0));
529 530 TRY_COMPARE(hoverSpy.count(), 2);
530 531 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(1).at(0)), s1);
531 532 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(1).at(1)), false);
532 533 }
533 534
535 void tst_qpieseries::sliceSeries()
536 {
537 QPieSlice *slice = new QPieSlice();
538 QVERIFY(!slice->series());
539 delete slice;
540
541 slice = new QPieSlice(m_series);
542 QVERIFY(!slice->series());
543
544 m_series->append(slice);
545 QCOMPARE(slice->series(), m_series);
546
547 slice = new QPieSlice();
548 m_series->insert(0, slice);
549 QCOMPARE(slice->series(), m_series);
550 }
551
534 552 QTEST_MAIN(tst_qpieseries)
535 553
536 554 #include "tst_qpieseries.moc"
537 555
General Comments 0
You need to be logged in to leave comments. Login now