##// END OF EJS Templates
Remove QPieSeries::replace(). The function does not really make sense with the pie.
Jani Honkonen -
r1013:bd5d49d1f7af
parent child
Show More
@@ -1,697 +1,687
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 "pieslicedata_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 27 #include "chartanimator_p.h"
28 28 #include "legendmarker_p.h"
29 29 #include <QAbstractItemModel>
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
66 66 /*!
67 67 \property QPieSeries::verticalPosition
68 68 \brief Defines the vertical position of the pie.
69 69
70 70 The value is a relative value to the chart rectangle where:
71 71
72 72 \list
73 73 \o 0.0 is the absolute top.
74 74 \o 1.0 is the absolute bottom.
75 75 \endlist
76 76
77 77 Default value is 0.5 (center).
78 78 */
79 79
80 80 /*!
81 81 \property QPieSeries::size
82 82 \brief Defines the pie size.
83 83
84 84 The value is a relative value to the chart rectangle where:
85 85
86 86 \list
87 87 \o 0.0 is the minimum size (pie not drawn).
88 88 \o 1.0 is the maximum size that can fit the chart.
89 89 \endlist
90 90
91 91 Default value is 0.7.
92 92 */
93 93
94 94 /*!
95 95 \property QPieSeries::startAngle
96 96 \brief Defines the starting angle of the pie.
97 97
98 98 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
99 99
100 100 Default is value is 0.
101 101 */
102 102
103 103 /*!
104 104 \property QPieSeries::endAngle
105 105 \brief Defines the ending angle of the pie.
106 106
107 107 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
108 108
109 109 Default is value is 360.
110 110 */
111 111
112 112
113 113 /*!
114 114 Constructs a series object which is a child of \a parent.
115 115 */
116 116 QPieSeries::QPieSeries(QObject *parent) :
117 117 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
118 118 {
119 119
120 120 }
121 121
122 122 /*!
123 123 Destroys the series and its slices.
124 124 */
125 125 QPieSeries::~QPieSeries()
126 126 {
127 127 // NOTE: d_prt destroyed by QObject
128 128 }
129 129
130 130 /*!
131 131 Returns QChartSeries::SeriesTypePie.
132 132 */
133 133 QAbstractSeries::QSeriesType QPieSeries::type() const
134 134 {
135 135 return QAbstractSeries::SeriesTypePie;
136 136 }
137 137
138 138 /*!
139 Sets an array of \a slices to the series replacing the existing slices.
140 Slice ownership is passed to the series.
141 */
142 void QPieSeries::replace(QList<QPieSlice*> slices)
143 {
144 clear();
145 append(slices);
146 }
147
148 /*!
149 139 Appends an array of \a slices to the series.
150 140 Slice ownership is passed to the series.
151 141 */
152 142 void QPieSeries::append(QList<QPieSlice*> slices)
153 143 {
154 144 Q_D(QPieSeries);
155 145
156 146 foreach (QPieSlice* s, slices) {
157 147 s->setParent(this);
158 148 d->m_slices << s;
159 149 }
160 150
161 151 d->updateDerivativeData();
162 152
163 153 foreach (QPieSlice* s, slices) {
164 154 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
165 155 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
166 156 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
167 157 }
168 158
169 159 emit d->added(slices);
170 160 }
171 161
172 162 /*!
173 163 Appends a single \a slice to the series.
174 164 Slice ownership is passed to the series.
175 165 */
176 166 void QPieSeries::append(QPieSlice* slice)
177 167 {
178 168 append(QList<QPieSlice*>() << slice);
179 169 }
180 170
181 171 /*!
182 172 Appends a single \a slice to the series and returns a reference to the series.
183 173 Slice ownership is passed to the series.
184 174 */
185 175 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
186 176 {
187 177 append(slice);
188 178 return *this;
189 179 }
190 180
191 181
192 182 /*!
193 183 Appends a single slice to the series with give \a value and \a name.
194 184 Slice ownership is passed to the series.
195 185 */
196 186 QPieSlice* QPieSeries::append(qreal value, QString name)
197 187 {
198 188 QPieSlice* slice = new QPieSlice(value, name);
199 189 append(slice);
200 190 return slice;
201 191 }
202 192
203 193 /*!
204 194 Inserts a single \a slice to the series before the slice at \a index position.
205 195 Slice ownership is passed to the series.
206 196 */
207 197 void QPieSeries::insert(int index, QPieSlice* slice)
208 198 {
209 199 Q_D(QPieSeries);
210 200 Q_ASSERT(index <= d->m_slices.count());
211 201 slice->setParent(this);
212 202 d->m_slices.insert(index, slice);
213 203
214 204 d->updateDerivativeData();
215 205
216 206 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
217 207 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
218 208 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
219 209
220 210 emit d->added(QList<QPieSlice*>() << slice);
221 211 }
222 212
223 213 /*!
224 214 Removes a single \a slice from the series and deletes the slice.
225 215
226 216 Do not reference the pointer after this call.
227 217 */
228 218 void QPieSeries::remove(QPieSlice* slice)
229 219 {
230 220 Q_D(QPieSeries);
231 221 if (!d->m_slices.removeOne(slice)) {
232 222 Q_ASSERT(0); // TODO: how should this be reported?
233 223 return;
234 224 }
235 225
236 226 d->updateDerivativeData();
237 227
238 228 emit d->removed(QList<QPieSlice*>() << slice);
239 229
240 230 delete slice;
241 231 slice = 0;
242 232 }
243 233
244 234 /*!
245 235 Clears all slices from the series.
246 236 */
247 237 void QPieSeries::clear()
248 238 {
249 239 Q_D(QPieSeries);
250 240 if (d->m_slices.count() == 0)
251 241 return;
252 242
253 243 QList<QPieSlice*> slices = d->m_slices;
254 244 foreach (QPieSlice* s, d->m_slices) {
255 245 d->m_slices.removeOne(s);
256 246 delete s;
257 247 }
258 248
259 249 d->updateDerivativeData();
260 250
261 251 emit d->removed(slices);
262 252 }
263 253
264 254 /*!
265 255 returns the number of the slices in this series.
266 256 */
267 257 int QPieSeries::count() const
268 258 {
269 259 Q_D(const QPieSeries);
270 260 return d->m_slices.count();
271 261 }
272 262
273 263 /*!
274 264 Returns true is the series is empty.
275 265 */
276 266 bool QPieSeries::isEmpty() const
277 267 {
278 268 Q_D(const QPieSeries);
279 269 return d->m_slices.isEmpty();
280 270 }
281 271
282 272 /*!
283 273 Returns a list of slices that belong to this series.
284 274 */
285 275 QList<QPieSlice*> QPieSeries::slices() const
286 276 {
287 277 Q_D(const QPieSeries);
288 278 return d->m_slices;
289 279 }
290 280
291 281 void QPieSeries::setHorizontalPosition(qreal relativePosition)
292 282 {
293 283 Q_D(QPieSeries);
294 284 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
295 285 emit d->piePositionChanged();
296 286 }
297 287
298 288 void QPieSeries::setVerticalPosition(qreal relativePosition)
299 289 {
300 290 Q_D(QPieSeries);
301 291 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
302 292 emit d->piePositionChanged();
303 293 }
304 294
305 295 qreal QPieSeries::horizontalPosition() const
306 296 {
307 297 Q_D(const QPieSeries);
308 298 return d->m_pieRelativeHorPos;
309 299 }
310 300
311 301 qreal QPieSeries::verticalPosition() const
312 302 {
313 303 Q_D(const QPieSeries);
314 304 return d->m_pieRelativeVerPos;
315 305 }
316 306
317 307 void QPieSeries::setPieSize(qreal relativeSize)
318 308 {
319 309 Q_D(QPieSeries);
320 310 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
321 311 emit d->pieSizeChanged();
322 312 }
323 313
324 314 qreal QPieSeries::pieSize() const
325 315 {
326 316 Q_D(const QPieSeries);
327 317 return d->m_pieRelativeSize;
328 318 }
329 319
330 320
331 321 void QPieSeries::setPieStartAngle(qreal angle)
332 322 {
333 323 Q_D(QPieSeries);
334 324 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
335 325 d->updateDerivativeData();
336 326 }
337 327
338 328 qreal QPieSeries::pieStartAngle() const
339 329 {
340 330 Q_D(const QPieSeries);
341 331 return d->m_pieStartAngle;
342 332 }
343 333
344 334 /*!
345 335 Sets the end angle of the pie.
346 336
347 337 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
348 338
349 339 \a angle must be greater than start angle.
350 340
351 341 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
352 342 */
353 343 void QPieSeries::setPieEndAngle(qreal angle)
354 344 {
355 345 Q_D(QPieSeries);
356 346
357 347 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
358 348 d->updateDerivativeData();
359 349 }
360 350
361 351 /*!
362 352 Returns the end angle of the pie.
363 353
364 354 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
365 355
366 356 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
367 357 */
368 358 qreal QPieSeries::pieEndAngle() const
369 359 {
370 360 Q_D(const QPieSeries);
371 361 return d->m_pieEndAngle;
372 362 }
373 363
374 364 /*!
375 365 Sets the all the slice labels \a visible or invisible.
376 366
377 367 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
378 368 */
379 369 void QPieSeries::setLabelsVisible(bool visible)
380 370 {
381 371 Q_D(QPieSeries);
382 372 foreach (QPieSlice* s, d->m_slices)
383 373 s->setLabelVisible(visible);
384 374 }
385 375
386 376 /*!
387 377 Returns the sum of all slice values in this series.
388 378
389 379 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
390 380 */
391 381 qreal QPieSeries::sum() const
392 382 {
393 383 Q_D(const QPieSeries);
394 384 return d->m_sum;
395 385 }
396 386
397 387 /*!
398 388 \fn void QPieSeries::clicked(QPieSlice* slice)
399 389
400 390 This signal is emitted when a \a slice has been clicked.
401 391
402 392 \sa QPieSlice::clicked()
403 393 */
404 394
405 395 /*!
406 396 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
407 397
408 398 This signal is emitted when user has hovered over or away from the \a slice.
409 399
410 400 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
411 401
412 402 \sa QPieSlice::hovered()
413 403 */
414 404
415 405 /*!
416 406 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
417 407 Sets the \a model to be used as a data source
418 408 */
419 409 bool QPieSeries::setModel(QAbstractItemModel* model)
420 410 {
421 411 Q_D(QPieSeries);
422 412 // disconnect signals from old model
423 413 if(d->m_model)
424 414 {
425 415 disconnect(d->m_model, 0, this, 0);
426 416 d->m_mapValues = -1;
427 417 d->m_mapLabels = -1;
428 418 d->m_mapOrientation = Qt::Vertical;
429 419 }
430 420
431 421 // set new model
432 422 if(model)
433 423 {
434 424 d->m_model = model;
435 425 return true;
436 426 }
437 427 else
438 428 {
439 429 d->m_model = 0;
440 430 return false;
441 431 }
442 432 }
443 433
444 434 /*!
445 435 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
446 436 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
447 437 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
448 438 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
449 439 The \a orientation parameter specifies whether the data is in columns or in rows.
450 440 */
451 441 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
452 442 {
453 443 Q_D(QPieSeries);
454 444
455 445 if (d->m_model == 0)
456 446 return;
457 447
458 448 d->m_mapValues = modelValuesLine;
459 449 d->m_mapLabels = modelLabelsLine;
460 450 d->m_mapOrientation = orientation;
461 451
462 452 // connect the signals
463 453 if (d->m_mapOrientation == Qt::Vertical) {
464 454 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
465 455 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
466 456 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
467 457 } else {
468 458 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
469 459 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
470 460 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
471 461 }
472 462
473 463 // create the initial slices set
474 464 if (d->m_mapOrientation == Qt::Vertical) {
475 465 for (int i = 0; i < d->m_model->rowCount(); i++)
476 466 append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
477 467 } else {
478 468 for (int i = 0; i < d->m_model->columnCount(); i++)
479 469 append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
480 470 }
481 471 }
482 472
483 473 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
484 474
485 475
486 476 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
487 477 QAbstractSeriesPrivate(parent),
488 478 m_pieRelativeHorPos(0.5),
489 479 m_pieRelativeVerPos(0.5),
490 480 m_pieRelativeSize(0.7),
491 481 m_pieStartAngle(0),
492 482 m_pieEndAngle(360),
493 483 m_sum(0),
494 484 m_mapValues(0),
495 485 m_mapLabels(0),
496 486 m_mapOrientation(Qt::Horizontal)
497 487 {
498 488
499 489 }
500 490
501 491 QPieSeriesPrivate::~QPieSeriesPrivate()
502 492 {
503 493
504 494 }
505 495
506 496 void QPieSeriesPrivate::updateDerivativeData()
507 497 {
508 498 m_sum = 0;
509 499
510 500 // nothing to do?
511 501 if (m_slices.count() == 0)
512 502 return;
513 503
514 504 // calculate sum of all slices
515 505 foreach (QPieSlice* s, m_slices)
516 506 m_sum += s->value();
517 507
518 508 // nothing to show..
519 509 if (qFuzzyIsNull(m_sum))
520 510 return;
521 511
522 512 // update slice attributes
523 513 qreal sliceAngle = m_pieStartAngle;
524 514 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
525 515 QVector<QPieSlice*> changed;
526 516 foreach (QPieSlice* s, m_slices) {
527 517
528 518 PieSliceData data = PieSliceData::data(s);
529 519 data.m_percentage = s->value() / m_sum;
530 520 data.m_angleSpan = pieSpan * data.m_percentage;
531 521 data.m_startAngle = sliceAngle;
532 522 sliceAngle += data.m_angleSpan;
533 523
534 524 if (PieSliceData::data(s) != data) {
535 525 PieSliceData::data(s) = data;
536 526 changed << s;
537 527 }
538 528 }
539 529
540 530 // emit signals
541 531 foreach (QPieSlice* s, changed)
542 532 PieSliceData::data(s).emitChangedSignal(s);
543 533 }
544 534
545 535 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
546 536 {
547 537 return series.d_func();
548 538 }
549 539
550 540 void QPieSeriesPrivate::sliceChanged()
551 541 {
552 542 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
553 543 updateDerivativeData();
554 544 }
555 545
556 546 void QPieSeriesPrivate::sliceClicked()
557 547 {
558 548 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
559 549 Q_ASSERT(m_slices.contains(slice));
560 550 Q_Q(QPieSeries);
561 551 emit q->clicked(slice);
562 552 }
563 553
564 554 void QPieSeriesPrivate::sliceHovered(bool state)
565 555 {
566 556 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
567 557 Q_ASSERT(m_slices.contains(slice));
568 558 Q_Q(QPieSeries);
569 559 emit q->hovered(slice, state);
570 560 }
571 561
572 562 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
573 563 {
574 564 Q_UNUSED(bottomRight)
575 565
576 566 if (m_mapOrientation == Qt::Vertical)
577 567 {
578 568 if (topLeft.column() == m_mapValues)
579 569 if (m_mapValues == m_mapLabels)
580 570 {
581 571 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
582 572 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
583 573 }
584 574 else
585 575 {
586 576 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
587 577 }
588 578 else if (topLeft.column() == m_mapLabels)
589 579 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
590 580 }
591 581 else
592 582 {
593 583 if (topLeft.row() == m_mapValues)
594 584 if (m_mapValues == m_mapLabels)
595 585 {
596 586 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
597 587 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
598 588 }
599 589 else
600 590 {
601 591 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
602 592 }
603 593 else if (topLeft.row() == m_mapLabels)
604 594 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
605 595 }
606 596 }
607 597
608 598 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
609 599 {
610 600 Q_UNUSED(parent)
611 601 Q_UNUSED(end)
612 602 Q_Q(QPieSeries);
613 603
614 604 QPieSlice* newSlice = new QPieSlice;
615 605 newSlice->setLabelVisible(true);
616 606 if (m_mapOrientation == Qt::Vertical)
617 607 {
618 608 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
619 609 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
620 610 }
621 611 else
622 612 {
623 613 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
624 614 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
625 615 }
626 616
627 617 q->insert(start, newSlice);
628 618 }
629 619
630 620 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
631 621 {
632 622 Q_UNUSED(parent)
633 623 Q_UNUSED(end)
634 624 Q_Q(QPieSeries);
635 625 q->remove(m_slices.at(start));
636 626 }
637 627
638 628 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
639 629 {
640 630 // Remove rounding errors
641 631 qreal roundedValue = newValue;
642 632 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
643 633 roundedValue = 0.0;
644 634 else if (qFuzzyCompare(newValue, max))
645 635 roundedValue = max;
646 636 else if (qFuzzyCompare(newValue, min))
647 637 roundedValue = min;
648 638
649 639 // Check if the position is valid after removing the rounding errors
650 640 if (roundedValue < min || roundedValue > max) {
651 641 qWarning("QPieSeries: Illegal value");
652 642 return false;
653 643 }
654 644
655 645 if (!qFuzzyIsNull(value - roundedValue)) {
656 646 value = roundedValue;
657 647 return true;
658 648 }
659 649
660 650 // The change was so small it is considered a rounding error
661 651 return false;
662 652 }
663 653
664 654 void QPieSeriesPrivate::scaleDomain(Domain& domain)
665 655 {
666 656 Q_UNUSED(domain);
667 657 #ifndef QT_NO_DEBUG
668 658 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
669 659 #endif
670 660 }
671 661
672 662 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
673 663 {
674 664 Q_Q(QPieSeries);
675 665 PieChartItem* pie = new PieChartItem(q,presenter);
676 666 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
677 667 presenter->animator()->addAnimation(pie);
678 668 }
679 669 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
680 670 return pie;
681 671 }
682 672
683 673 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
684 674 {
685 675 Q_Q(QPieSeries);
686 676 QList<LegendMarker*> markers;
687 677 foreach(QPieSlice* slice, q->slices()) {
688 678 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
689 679 markers << marker;
690 680 }
691 681 return markers;
692 682 }
693 683
694 684 #include "moc_qpieseries.cpp"
695 685 #include "moc_qpieseries_p.cpp"
696 686
697 687 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,89 +1,88
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 PIESERIES_H
22 22 #define PIESERIES_H
23 23
24 24 #include <qabstractseries.h>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27 class QPieSeriesPrivate;
28 28 class QPieSlice;
29 29
30 30 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
31 31 {
32 32 Q_OBJECT
33 33 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
34 34 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
35 35 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
36 36 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
37 37 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
38 38
39 39 public:
40 40 explicit QPieSeries(QObject *parent = 0);
41 41 virtual ~QPieSeries();
42 42
43 43 QSeriesType type() const;
44 44
45 45 void append(QPieSlice* slice);
46 46 void append(QList<QPieSlice*> slices);
47 47 QPieSeries& operator << (QPieSlice* slice);
48 48 QPieSlice* append(qreal value, QString name);
49 49 void insert(int index, QPieSlice* slice);
50 void replace(QList<QPieSlice*> slices);
51 50 void remove(QPieSlice* slice);
52 51 void clear();
53 52
54 53 QList<QPieSlice*> slices() const;
55 54 int count() const;
56 55 bool isEmpty() const;
57 56
58 57 qreal sum() const;
59 58
60 59 void setHorizontalPosition(qreal relativePosition);
61 60 qreal horizontalPosition() const;
62 61 void setVerticalPosition(qreal relativePosition);
63 62 qreal verticalPosition() const;
64 63
65 64 void setPieSize(qreal relativeSize);
66 65 qreal pieSize() const;
67 66
68 67 void setPieStartAngle(qreal startAngle);
69 68 qreal pieStartAngle() const;
70 69 void setPieEndAngle(qreal endAngle);
71 70 qreal pieEndAngle() const;
72 71
73 72 void setLabelsVisible(bool visible = true);
74 73
75 74 bool setModel(QAbstractItemModel* model);
76 75 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
77 76
78 77 Q_SIGNALS:
79 78 void clicked(QPieSlice* slice);
80 79 void hovered(QPieSlice* slice, bool state);
81 80
82 81 private:
83 82 Q_DECLARE_PRIVATE(QPieSeries)
84 83 Q_DISABLE_COPY(QPieSeries)
85 84 };
86 85
87 86 QTCOMMERCIALCHART_END_NAMESPACE
88 87
89 88 #endif // PIESERIES_H
@@ -1,410 +1,410
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 "pieslicedata_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. Even if the theme is
35 35 changed users settings will persist.
36 36
37 37 To enable user interaction customization with the slices some basic signals
38 38 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
47 47 /*!
48 48 \property QPieSlice::value
49 49
50 50 Value of the slice.
51 51
52 52 \sa percentage(), QPieSeries::sum()
53 53 */
54 54
55 55 /*!
56 56 Constructs an empty slice with a \a parent.
57 57
58 \sa QPieSeries::append(), QPieSeries::insert(), QPieSeries::replace()
58 \sa QPieSeries::append(), QPieSeries::insert()
59 59 */
60 60 QPieSlice::QPieSlice(QObject *parent)
61 61 :QObject(parent),
62 62 d(new PieSliceData())
63 63 {
64 64
65 65 }
66 66
67 67 /*!
68 68 Constructs an empty slice with given \a value, \a label and a \a parent.
69 \sa QPieSeries::append(), QPieSeries::insert(), QPieSeries::replace()
69 \sa QPieSeries::append(), QPieSeries::insert()
70 70 */
71 71 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
72 72 :QObject(parent),
73 73 d(new PieSliceData())
74 74 {
75 75 d->m_value = value;
76 76 d->m_labelText = label;
77 77 }
78 78
79 79 /*!
80 80 Destroys the slice.
81 81 User should not delete the slice if it has been added to the series.
82 82 */
83 83 QPieSlice::~QPieSlice()
84 84 {
85 85 delete d;
86 86 }
87 87
88 88 /*!
89 89 Gets the value of the slice.
90 90 Note that all values in the series
91 91 \sa setValue()
92 92 */
93 93 qreal QPieSlice::value() const
94 94 {
95 95 return d->m_value;
96 96 }
97 97
98 98 /*!
99 99 Gets the label of the slice.
100 100 \sa setLabel()
101 101 */
102 102 QString QPieSlice::label() const
103 103 {
104 104 return d->m_labelText;
105 105 }
106 106
107 107 /*!
108 108 Returns true if label is set as visible.
109 109 \sa setLabelVisible()
110 110 */
111 111 bool QPieSlice::isLabelVisible() const
112 112 {
113 113 return d->m_isLabelVisible;
114 114 }
115 115
116 116 /*!
117 117 Returns true if slice is exloded from the pie.
118 118 \sa setExploded(), explodeDistanceFactor(), setExplodeDistanceFactor()
119 119 */
120 120 bool QPieSlice::isExploded() const
121 121 {
122 122 return d->m_isExploded;
123 123 }
124 124
125 125 /*!
126 126 Returns the explode distance factor.
127 127
128 128 The factor is relative to pie radius. For example:
129 129 1.0 means the distance is the same as the radius.
130 130 0.5 means the distance is half of the radius.
131 131
132 132 Default value is 0.15.
133 133
134 134 \sa setExplodeDistanceFactor(), isExploded(), setExploded()
135 135 */
136 136 qreal QPieSlice::explodeDistanceFactor() const
137 137 {
138 138 return d->m_explodeDistanceFactor;
139 139 }
140 140
141 141 /*!
142 142 Returns the percentage of this slice compared to the sum of all slices in the same series.
143 143 The returned value ranges from 0 to 1.0.
144 144
145 145 Updated internally after the slice is added to the series.
146 146
147 147 \sa QPieSeries::sum()
148 148 */
149 149 qreal QPieSlice::percentage() const
150 150 {
151 151 return d->m_percentage;
152 152 }
153 153
154 154 /*!
155 155 Returns the starting angle of this slice in the series it belongs to.
156 156
157 157 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
158 158
159 159 Updated internally after the slice is added to the series.
160 160 */
161 161 qreal QPieSlice::startAngle() const
162 162 {
163 163 return d->m_startAngle;
164 164 }
165 165
166 166 /*!
167 167 Returns the end angle of this slice in the series it belongs to.
168 168
169 169 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
170 170
171 171 Updated internally after the slice is added to the series.
172 172 */
173 173 qreal QPieSlice::endAngle() const
174 174 {
175 175 return d->m_startAngle + d->m_angleSpan;
176 176 }
177 177
178 178 /*!
179 179 Returns the pen used to draw this slice.
180 180 \sa setPen()
181 181 */
182 182 QPen QPieSlice::pen() const
183 183 {
184 184 return d->m_slicePen;
185 185 }
186 186
187 187 /*!
188 188 Returns the brush used to draw this slice.
189 189 \sa setBrush()
190 190 */
191 191 QBrush QPieSlice::brush() const
192 192 {
193 193 return d->m_sliceBrush;
194 194 }
195 195
196 196 /*!
197 197 Returns the pen used to draw the label in this slice.
198 198 \sa setLabelPen()
199 199 */
200 200 QPen QPieSlice::labelPen() const
201 201 {
202 202 return d->m_labelPen;
203 203 }
204 204
205 205 /*!
206 206 Returns the font used to draw label in this slice.
207 207 \sa setLabelFont()
208 208 */
209 209 QFont QPieSlice::labelFont() const
210 210 {
211 211 return d->m_labelFont;
212 212 }
213 213
214 214 /*!
215 215 Gets the label arm length factor.
216 216
217 217 The factor is relative to pie radius. For example:
218 218 1.0 means the length is the same as the radius.
219 219 0.5 means the length is half of the radius.
220 220
221 221 Default value is 0.15
222 222
223 223 \sa setLabelArmLengthFactor()
224 224 */
225 225 qreal QPieSlice::labelArmLengthFactor() const
226 226 {
227 227 return d->m_labelArmLengthFactor;
228 228 }
229 229
230 230 /*!
231 231 \fn void QPieSlice::clicked()
232 232
233 233 This signal is emitted when user has clicked the slice.
234 234
235 235 \sa QPieSeries::clicked()
236 236 */
237 237
238 238 /*!
239 239 \fn void QPieSlice::hovered(bool state)
240 240
241 241 This signal is emitted when user has hovered over or away from the slice.
242 242
243 243 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
244 244
245 245 \sa QPieSeries::hovered()
246 246 */
247 247
248 248 /*!
249 249 \fn void QPieSlice::changed()
250 250
251 251 This signal emitted when something has changed in the slice.
252 252 */
253 253
254 254 /*!
255 255 Sets the \a value of this slice.
256 256 \sa value()
257 257 */
258 258 void QPieSlice::setValue(qreal value)
259 259 {
260 260 if (!qFuzzyIsNull(d->m_value - value)) {
261 261 d->m_value = value;
262 262 emit changed();
263 263 }
264 264 }
265 265
266 266 /*!
267 267 Sets the \a label of the slice.
268 268 \sa label()
269 269 */
270 270 void QPieSlice::setLabel(QString label)
271 271 {
272 272 if (d->m_labelText != label) {
273 273 d->m_labelText = label;
274 274 emit changed();
275 275 }
276 276 }
277 277
278 278 /*!
279 279 Sets the label \a visible in this slice.
280 280 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
281 281 */
282 282 void QPieSlice::setLabelVisible(bool visible)
283 283 {
284 284 if (d->m_isLabelVisible != visible) {
285 285 d->m_isLabelVisible = visible;
286 286 emit changed();
287 287 }
288 288 }
289 289
290 290 /*!
291 291 Sets this slices \a exploded state.
292 292
293 293 If the slice is exploded it is moved away from the pie center. The distance is defined by the explode distance factor.
294 294
295 295 \sa isExploded(), explodeDistanceFactor(), setExplodeDistanceFactor()
296 296 */
297 297 void QPieSlice::setExploded(bool exploded)
298 298 {
299 299 if (d->m_isExploded != exploded) {
300 300 d->m_isExploded = exploded;
301 301 emit changed();
302 302 }
303 303 }
304 304
305 305 /*!
306 306 Sets the explode distance \a factor.
307 307
308 308 The factor is relative to pie radius. For example:
309 309 1.0 means the distance is the same as the radius.
310 310 0.5 means the distance is half of the radius.
311 311
312 312 Default value is 0.15
313 313
314 314 \sa explodeDistanceFactor(), isExploded(), setExploded()
315 315 */
316 316 void QPieSlice::setExplodeDistanceFactor(qreal factor)
317 317 {
318 318 if (!qFuzzyIsNull(d->m_explodeDistanceFactor - factor)) {
319 319 d->m_explodeDistanceFactor = factor;
320 320 emit changed();
321 321 }
322 322 }
323 323
324 324 /*!
325 325 Sets the \a pen used to draw this slice.
326 326
327 327 Overrides the pen set by the theme.
328 328
329 329 \sa pen()
330 330 */
331 331 void QPieSlice::setPen(const QPen &pen)
332 332 {
333 333 if (d->m_slicePen != pen) {
334 334 d->m_slicePen = pen;
335 335 d->m_slicePen.setThemed(false);
336 336 emit changed();
337 337 }
338 338 }
339 339
340 340 /*!
341 341 Sets the \a brush used to draw this slice.
342 342
343 343 Overrides the brush set by the theme.
344 344
345 345 \sa brush()
346 346 */
347 347 void QPieSlice::setBrush(const QBrush &brush)
348 348 {
349 349 if (d->m_sliceBrush != brush) {
350 350 d->m_sliceBrush = brush;
351 351 d->m_sliceBrush.setThemed(false);
352 352 emit changed();
353 353 }
354 354 }
355 355
356 356 /*!
357 357 Sets the \a pen used to draw the label in this slice.
358 358
359 359 Overrides the pen set by the theme.
360 360
361 361 \sa labelPen()
362 362 */
363 363 void QPieSlice::setLabelPen(const QPen &pen)
364 364 {
365 365 if (d->m_labelPen != pen) {
366 366 d->m_labelPen = pen;
367 367 d->m_labelPen.setThemed(false);
368 368 emit changed();
369 369 }
370 370 }
371 371
372 372 /*!
373 373 Sets the \a font used to draw the label in this slice.
374 374
375 375 Overrides the font set by the theme.
376 376
377 377 \sa labelFont()
378 378 */
379 379 void QPieSlice::setLabelFont(const QFont &font)
380 380 {
381 381 if (d->m_labelFont != font) {
382 382 d->m_labelFont = font;
383 383 d->m_labelFont.setThemed(false);
384 384 emit changed();
385 385 }
386 386 }
387 387
388 388 /*!
389 389 Sets the label arm length \a factor.
390 390
391 391 The factor is relative to pie radius. For example:
392 392 1.0 means the length is the same as the radius.
393 393 0.5 means the length is half of the radius.
394 394
395 395 Default value is 0.15
396 396
397 397 \sa labelArmLengthFactor()
398 398 */
399 399 void QPieSlice::setLabelArmLengthFactor(qreal factor)
400 400 {
401 401 if (!qFuzzyIsNull(d->m_labelArmLengthFactor - factor)) {
402 402 d->m_labelArmLengthFactor = factor;
403 403 emit changed();
404 404 }
405 405 }
406 406
407 407 QTCOMMERCIALCHART_END_NAMESPACE
408 408
409 409 QTCOMMERCIALCHART_USE_NAMESPACE
410 410 #include "moc_qpieslice.cpp"
General Comments 0
You need to be logged in to leave comments. Login now