##// END OF EJS Templates
Added two model related tests to pieseries
Marek Rosa -
r1180:1a2d53d6021f
parent child
Show More
@@ -1,81 +1,82
1 1 #include "qpiemodelmapper.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 QPieModelMapper::QPieModelMapper(QObject *parent) :
6 6 QObject(parent),
7 7 m_first(0),
8 8 m_count(-1),
9 9 m_orientation(Qt::Vertical),
10 10 m_mapValues(-1),
11 11 m_mapLabels(-1)
12 12 {
13 13 }
14 14
15 15 int QPieModelMapper::first() const
16 16 {
17 17 return m_first;
18 18 }
19 19
20 20 void QPieModelMapper::setFirst(int first)
21 21 {
22 22 m_first = qMax(first, 0);
23 23 emit updated();
24 24 }
25 25
26 26 int QPieModelMapper::count() const
27 27 {
28 28 return m_count;
29 29 }
30 30
31 31 void QPieModelMapper::setCount(int count)
32 32 {
33 33 m_count = qMax(count, -1);
34 34 emit updated();
35 35 }
36 36
37 37 Qt::Orientation QPieModelMapper::orientation() const
38 38 {
39 39 return m_orientation;
40 40 }
41 41
42 42 void QPieModelMapper::setOrientation(Qt::Orientation orientation)
43 43 {
44 44 m_orientation = orientation;
45 45 emit updated();
46 46 }
47 47
48 48 int QPieModelMapper::mapValues() const
49 49 {
50 50 return m_mapValues;
51 51 }
52 52
53 53 void QPieModelMapper::setMapValues(int mapValues)
54 54 {
55 55 m_mapValues = mapValues;
56 56 emit updated();
57 57 }
58 58
59 59 int QPieModelMapper::mapLabels() const
60 60 {
61 61 return m_mapLabels;
62 62 }
63 63
64 64 void QPieModelMapper::setMapLabels(int mapLabels)
65 65 {
66 66 m_mapLabels = mapLabels;
67 67 emit updated();
68 68 }
69 69
70 70 void QPieModelMapper::reset()
71 71 {
72 72 m_first = 0;
73 73 m_count = -1;
74 74 m_orientation = Qt::Vertical;
75 75 m_mapValues = -1;
76 76 m_mapLabels = -1;
77 emit updated();
77 78 }
78 79
79 80 #include "moc_qpiemodelmapper.cpp"
80 81
81 82 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,811 +1,815
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 #include "qpiemodelmapper.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QPieSeries
36 36 \brief Pie series API for QtCommercial Charts
37 37
38 38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 40 The actual slice size is determined by that relative value.
41 41
42 42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 43 These relate to the actual chart rectangle.
44 44
45 45 By default the pie is defined as a full pie but it can also be a partial pie.
46 46 This can be done by setting a starting angle and angle span to the series.
47 47 Full pie is 360 degrees where 0 is at 12 a'clock.
48 48
49 49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
50 50 \image examples_piechart.png
51 51 */
52 52
53 53 /*!
54 54 \property QPieSeries::horizontalPosition
55 55 \brief Defines the horizontal position of the pie.
56 56
57 57 The value is a relative value to the chart rectangle where:
58 58
59 59 \list
60 60 \o 0.0 is the absolute left.
61 61 \o 1.0 is the absolute right.
62 62 \endlist
63 63
64 64 Default value is 0.5 (center).
65 65 */
66 66
67 67 /*!
68 68 \property QPieSeries::verticalPosition
69 69 \brief Defines the vertical position of the pie.
70 70
71 71 The value is a relative value to the chart rectangle where:
72 72
73 73 \list
74 74 \o 0.0 is the absolute top.
75 75 \o 1.0 is the absolute bottom.
76 76 \endlist
77 77
78 78 Default value is 0.5 (center).
79 79 */
80 80
81 81 /*!
82 82 \property QPieSeries::size
83 83 \brief Defines the pie size.
84 84
85 85 The value is a relative value to the chart rectangle where:
86 86
87 87 \list
88 88 \o 0.0 is the minimum size (pie not drawn).
89 89 \o 1.0 is the maximum size that can fit the chart.
90 90 \endlist
91 91
92 92 Default value is 0.7.
93 93 */
94 94
95 95 /*!
96 96 \property QPieSeries::startAngle
97 97 \brief Defines the starting angle of the pie.
98 98
99 99 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
100 100
101 101 Default is value is 0.
102 102 */
103 103
104 104 /*!
105 105 \property QPieSeries::endAngle
106 106 \brief Defines the ending angle of the pie.
107 107
108 108 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
109 109
110 110 Default is value is 360.
111 111 */
112 112
113 113
114 114 /*!
115 115 Constructs a series object which is a child of \a parent.
116 116 */
117 117 QPieSeries::QPieSeries(QObject *parent) :
118 118 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
119 119 {
120 120
121 121 }
122 122
123 123 /*!
124 124 Destroys the series and its slices.
125 125 */
126 126 QPieSeries::~QPieSeries()
127 127 {
128 128 // NOTE: d_prt destroyed by QObject
129 129 }
130 130
131 131 /*!
132 132 Returns QChartSeries::SeriesTypePie.
133 133 */
134 134 QAbstractSeries::SeriesType QPieSeries::type() const
135 135 {
136 136 return QAbstractSeries::SeriesTypePie;
137 137 }
138 138
139 139 /*!
140 140 Appends an array of \a slices to the series.
141 141 Slice ownership is passed to the series.
142 142 */
143 143 bool QPieSeries::append(QList<QPieSlice*> slices)
144 144 {
145 145 Q_D(QPieSeries);
146 146
147 147 if (slices.count() == 0)
148 148 return false;
149 149
150 150 foreach (QPieSlice* s, slices) {
151 151 if (!s || d->m_slices.contains(s))
152 152 return false;
153 153 }
154 154
155 155 foreach (QPieSlice* s, slices) {
156 156 s->setParent(this);
157 157 d->m_slices << s;
158 158 }
159 159
160 160 d->updateDerivativeData();
161 161
162 162 foreach (QPieSlice* s, slices) {
163 163 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
164 164 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
165 165 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
166 166 }
167 167
168 168 emit d->added(slices);
169 169
170 170 return true;
171 171 }
172 172
173 173 /*!
174 174 Appends a single \a slice to the series.
175 175 Slice ownership is passed to the series.
176 176 */
177 177 bool QPieSeries::append(QPieSlice* slice)
178 178 {
179 179 return append(QList<QPieSlice*>() << slice);
180 180 }
181 181
182 182 /*!
183 183 Appends a single \a slice to the series and returns a reference to the series.
184 184 Slice ownership is passed to the series.
185 185 */
186 186 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
187 187 {
188 188 append(slice);
189 189 return *this;
190 190 }
191 191
192 192
193 193 /*!
194 194 Appends a single slice to the series with give \a value and \a name.
195 195 Slice ownership is passed to the series.
196 196 */
197 197 QPieSlice* QPieSeries::append(qreal value, QString name)
198 198 {
199 199 QPieSlice* slice = new QPieSlice(value, name);
200 200 append(slice);
201 201 return slice;
202 202 }
203 203
204 204 /*!
205 205 Inserts a single \a slice to the series before the slice at \a index position.
206 206 Slice ownership is passed to the series.
207 207 */
208 208 bool QPieSeries::insert(int index, QPieSlice* slice)
209 209 {
210 210 Q_D(QPieSeries);
211 211
212 212 if (index < 0 || index > d->m_slices.count())
213 213 return false;
214 214
215 215 if (!slice || d->m_slices.contains(slice))
216 216 return false;
217 217
218 218 slice->setParent(this);
219 219 d->m_slices.insert(index, slice);
220 220
221 221 d->updateDerivativeData();
222 222
223 223 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
224 224 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
225 225 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
226 226
227 227 emit d->added(QList<QPieSlice*>() << slice);
228 228
229 229 return true;
230 230 }
231 231
232 232 /*!
233 233 Removes a single \a slice from the series and deletes the slice.
234 234
235 235 Do not reference the pointer after this call.
236 236 */
237 237 bool QPieSeries::remove(QPieSlice* slice)
238 238 {
239 239 Q_D(QPieSeries);
240 240
241 241 if (!d->m_slices.removeOne(slice))
242 242 return false;
243 243
244 244 d->updateDerivativeData();
245 245
246 246 emit d->removed(QList<QPieSlice*>() << slice);
247 247
248 248 delete slice;
249 249 slice = 0;
250 250
251 251 return true;
252 252 }
253 253
254 254 /*!
255 255 Clears all slices from the series.
256 256 */
257 257 void QPieSeries::clear()
258 258 {
259 259 Q_D(QPieSeries);
260 260 if (d->m_slices.count() == 0)
261 261 return;
262 262
263 263 QList<QPieSlice*> slices = d->m_slices;
264 264 foreach (QPieSlice* s, d->m_slices) {
265 265 d->m_slices.removeOne(s);
266 266 delete s;
267 267 }
268 268
269 269 d->updateDerivativeData();
270 270
271 271 emit d->removed(slices);
272 272 }
273 273
274 274 /*!
275 275 returns the number of the slices in this series.
276 276 */
277 277 int QPieSeries::count() const
278 278 {
279 279 Q_D(const QPieSeries);
280 280 return d->m_slices.count();
281 281 }
282 282
283 283 /*!
284 284 Returns true is the series is empty.
285 285 */
286 286 bool QPieSeries::isEmpty() const
287 287 {
288 288 Q_D(const QPieSeries);
289 289 return d->m_slices.isEmpty();
290 290 }
291 291
292 292 /*!
293 293 Returns a list of slices that belong to this series.
294 294 */
295 295 QList<QPieSlice*> QPieSeries::slices() const
296 296 {
297 297 Q_D(const QPieSeries);
298 298 return d->m_slices;
299 299 }
300 300
301 301 void QPieSeries::setHorizontalPosition(qreal relativePosition)
302 302 {
303 303 Q_D(QPieSeries);
304 304 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
305 305 emit d->piePositionChanged();
306 306 }
307 307
308 308 void QPieSeries::setVerticalPosition(qreal relativePosition)
309 309 {
310 310 Q_D(QPieSeries);
311 311 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
312 312 emit d->piePositionChanged();
313 313 }
314 314
315 315 qreal QPieSeries::horizontalPosition() const
316 316 {
317 317 Q_D(const QPieSeries);
318 318 return d->m_pieRelativeHorPos;
319 319 }
320 320
321 321 qreal QPieSeries::verticalPosition() const
322 322 {
323 323 Q_D(const QPieSeries);
324 324 return d->m_pieRelativeVerPos;
325 325 }
326 326
327 327 void QPieSeries::setPieSize(qreal relativeSize)
328 328 {
329 329 Q_D(QPieSeries);
330 330 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
331 331 emit d->pieSizeChanged();
332 332 }
333 333
334 334 qreal QPieSeries::pieSize() const
335 335 {
336 336 Q_D(const QPieSeries);
337 337 return d->m_pieRelativeSize;
338 338 }
339 339
340 340
341 341 void QPieSeries::setPieStartAngle(qreal angle)
342 342 {
343 343 Q_D(QPieSeries);
344 344 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
345 345 d->updateDerivativeData();
346 346 }
347 347
348 348 qreal QPieSeries::pieStartAngle() const
349 349 {
350 350 Q_D(const QPieSeries);
351 351 return d->m_pieStartAngle;
352 352 }
353 353
354 354 /*!
355 355 Sets the end angle of the pie.
356 356
357 357 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
358 358
359 359 \a angle must be greater than start angle.
360 360
361 361 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
362 362 */
363 363 void QPieSeries::setPieEndAngle(qreal angle)
364 364 {
365 365 Q_D(QPieSeries);
366 366
367 367 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
368 368 d->updateDerivativeData();
369 369 }
370 370
371 371 /*!
372 372 Returns the end angle of the pie.
373 373
374 374 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
375 375
376 376 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
377 377 */
378 378 qreal QPieSeries::pieEndAngle() const
379 379 {
380 380 Q_D(const QPieSeries);
381 381 return d->m_pieEndAngle;
382 382 }
383 383
384 384 /*!
385 385 Sets the all the slice labels \a visible or invisible.
386 386
387 387 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
388 388 */
389 389 void QPieSeries::setLabelsVisible(bool visible)
390 390 {
391 391 Q_D(QPieSeries);
392 392 foreach (QPieSlice* s, d->m_slices)
393 393 s->setLabelVisible(visible);
394 394 }
395 395
396 396 /*!
397 397 Returns the sum of all slice values in this series.
398 398
399 399 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
400 400 */
401 401 qreal QPieSeries::sum() const
402 402 {
403 403 Q_D(const QPieSeries);
404 404 return d->m_sum;
405 405 }
406 406
407 407 /*!
408 408 \fn void QPieSeries::clicked(QPieSlice* slice)
409 409
410 410 This signal is emitted when a \a slice has been clicked.
411 411
412 412 \sa QPieSlice::clicked()
413 413 */
414 414
415 415 /*!
416 416 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
417 417
418 418 This signal is emitted when user has hovered over or away from the \a slice.
419 419
420 420 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
421 421
422 422 \sa QPieSlice::hovered()
423 423 */
424 424
425 425 /*!
426 426 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
427 427 Sets the \a model to be used as a data source
428 428 */
429 429 void QPieSeries::setModel(QAbstractItemModel* model)
430 430 {
431 431 Q_D(QPieSeries);
432 432 // disconnect signals from old model
433 433 if(d->m_model)
434 434 {
435 435 disconnect(d->m_model, 0, this, 0);
436 436 }
437 437
438 438 // set new model
439 439 if(model)
440 440 {
441 441 d->m_model = model;
442 442 // connect signals from the model
443 443 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
444 444 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
445 445 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
446 446 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
447 447 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
448 448
449 449 if (d->m_mapper)
450 450 d->initializePieFromModel();
451 451 }
452 452 else
453 453 {
454 454 d->m_model = 0;
455 455 }
456 456 }
457 457
458 458 void QPieSeries::setModelMapper(QPieModelMapper *mapper)
459 459 {
460 460 Q_D(QPieSeries);
461 461 // disconnect signals from old mapper
462 462 if (d->m_mapper) {
463 463 QObject::disconnect(d->m_mapper, 0, this, 0);
464 464 }
465 465
466 466 if (mapper) {
467 467 d->m_mapper = mapper;
468 468 // connect the signal from the mapper
469 469 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
470 470
471 471 if (d->m_model)
472 472 d->initializePieFromModel();
473 473 } else {
474 474 d->m_mapper = 0;
475 475 }
476 476 }
477 477
478 478 QPieModelMapper* QPieSeries::modelMapper() const
479 479 {
480 480 Q_D(const QPieSeries);
481 481 return d->m_mapper;
482 482 }
483 483
484 484 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
485 485
486 486
487 487 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
488 488 QAbstractSeriesPrivate(parent),
489 489 m_pieRelativeHorPos(0.5),
490 490 m_pieRelativeVerPos(0.5),
491 491 m_pieRelativeSize(0.7),
492 492 m_pieStartAngle(0),
493 493 m_pieEndAngle(360),
494 494 m_sum(0),
495 495 m_mapper(0)
496 496 {
497 497
498 498 }
499 499
500 500 QPieSeriesPrivate::~QPieSeriesPrivate()
501 501 {
502 502
503 503 }
504 504
505 505 void QPieSeriesPrivate::updateDerivativeData()
506 506 {
507 507 m_sum = 0;
508 508
509 509 // nothing to do?
510 510 if (m_slices.count() == 0)
511 511 return;
512 512
513 513 // calculate sum of all slices
514 514 foreach (QPieSlice* s, m_slices)
515 515 m_sum += s->value();
516 516
517 517 // nothing to show..
518 518 if (qFuzzyIsNull(m_sum))
519 519 return;
520 520
521 521 // update slice attributes
522 522 qreal sliceAngle = m_pieStartAngle;
523 523 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
524 524 QVector<QPieSlice*> changed;
525 525 foreach (QPieSlice* s, m_slices) {
526 526
527 527 PieSliceData data = PieSliceData::data(s);
528 528 data.m_percentage = s->value() / m_sum;
529 529 data.m_angleSpan = pieSpan * data.m_percentage;
530 530 data.m_startAngle = sliceAngle;
531 531 sliceAngle += data.m_angleSpan;
532 532
533 533 if (PieSliceData::data(s) != data) {
534 534 PieSliceData::data(s) = data;
535 535 changed << s;
536 536 }
537 537 }
538 538
539 539 // emit signals
540 540 foreach (QPieSlice* s, changed)
541 541 PieSliceData::data(s).emitChangedSignal(s);
542 542 }
543 543
544 544 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
545 545 {
546 546 return series.d_func();
547 547 }
548 548
549 549 void QPieSeriesPrivate::sliceChanged()
550 550 {
551 551 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
552 552 updateDerivativeData();
553 553 }
554 554
555 555 void QPieSeriesPrivate::sliceClicked()
556 556 {
557 557 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
558 558 Q_ASSERT(m_slices.contains(slice));
559 559 Q_Q(QPieSeries);
560 560 emit q->clicked(slice);
561 561 }
562 562
563 563 void QPieSeriesPrivate::sliceHovered(bool state)
564 564 {
565 565 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
566 566 Q_ASSERT(m_slices.contains(slice));
567 567 Q_Q(QPieSeries);
568 568 emit q->hovered(slice, state);
569 569 }
570 570
571 571 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
572 572 {
573 573 if (m_mapper) {
574 574 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
575 575 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
576 576 if (m_mapper->orientation() == Qt::Vertical)
577 577 {
578 578 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
579 579 if (topLeft.column() == m_mapper->mapValues())
580 580 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
581 581 if (topLeft.column() == m_mapper->mapLabels())
582 582 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
583 583 }
584 584 }
585 585 else
586 586 {
587 587 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
588 588 if (topLeft.row() == m_mapper->mapValues())
589 589 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
590 590 if (topLeft.row() == m_mapper->mapLabels())
591 591 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
592 592 }
593 593 }
594 594 }
595 595 }
596 596 }
597 597 }
598 598
599 599
600 600 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
601 601 {
602 602 Q_UNUSED(parent);
603 603 if (m_mapper) {
604 604 if (m_mapper->orientation() == Qt::Vertical)
605 605 insertData(start, end);
606 606 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
607 607 initializePieFromModel();
608 608 }
609 609 }
610 610
611 611 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
612 612 {
613 613 Q_UNUSED(parent);
614 614 if (m_mapper) {
615 615 if (m_mapper->orientation() == Qt::Vertical)
616 616 removeData(start, end);
617 617 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
618 618 initializePieFromModel();
619 619 }
620 620 }
621 621
622 622 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
623 623 {
624 624 Q_UNUSED(parent);
625 625 if (m_mapper) {
626 626 if (m_mapper->orientation() == Qt::Horizontal)
627 627 insertData(start, end);
628 628 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
629 629 initializePieFromModel();
630 630 }
631 631 }
632 632
633 633 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
634 634 {
635 635 Q_UNUSED(parent);
636 636 if (m_mapper) {
637 637 if (m_mapper->orientation() == Qt::Horizontal)
638 638 removeData(start, end);
639 639 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
640 640 initializePieFromModel();
641 641 }
642 642 }
643 643
644 644 void QPieSeriesPrivate::insertData(int start, int end)
645 645 {
646 646 Q_Q(QPieSeries);
647 647 if (m_mapper) {
648 648 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
649 649 return;
650 650 } else {
651 651 int addedCount = end - start + 1;
652 652 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
653 653 addedCount = m_mapper->count();
654 654 int first = qMax(start, m_mapper->first());
655 655 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
656 656 for (int i = first; i <= last; i++) {
657 657 QPieSlice *slice = new QPieSlice;
658 658 if (m_mapper->orientation() == Qt::Vertical) {
659 659 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
660 660 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
661 661 } else {
662 662 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
663 663 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
664 664 }
665 665 slice->setLabelVisible();
666 666 q->insert(i - m_mapper->first(), slice);
667 667 }
668 668 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
669 669 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
670 670 q->remove(q->slices().at(i));
671 671 }
672 672 }
673 673 }
674 674
675 675 void QPieSeriesPrivate::removeData(int start, int end)
676 676 {
677 677 Q_Q(QPieSeries);
678 678 if (m_mapper) {
679 679 int removedCount = end - start + 1;
680 680 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
681 681 return;
682 682 } else {
683 683 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
684 684 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
685 685 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
686 686 for (int i = last; i >= first; i--)
687 687 q->remove(q->slices().at(i - m_mapper->first()));
688 688
689 689 if (m_mapper->count() != -1) {
690 690 int itemsAvailable; // check how many are available to be added
691 691 if (m_mapper->orientation() == Qt::Vertical)
692 692 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
693 693 else
694 694 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
695 695 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
696 696 int currentSize = m_slices.size();
697 697 if (toBeAdded > 0)
698 698 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
699 699 QPieSlice *slice = new QPieSlice;
700 700 if (m_mapper->orientation() == Qt::Vertical) {
701 701 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
702 702 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
703 703 } else {
704 704 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
705 705 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
706 706 }
707 707 slice->setLabelVisible();
708 708 q->insert(i, slice);
709 709 }
710 710 }
711 711 }
712 712 }
713 713 }
714 714
715 715 void QPieSeriesPrivate::initializePieFromModel()
716 716 {
717 717 Q_Q(QPieSeries);
718 718
719 719 if (m_model == 0 || m_mapper == 0)
720 720 return;
721 721
722 722 // clear current content
723 723 q->clear();
724 724
725 // check if mappings are set
726 if (m_mapper->mapValues() == -1 || m_mapper->mapLabels() == -1)
727 return;
728
725 729 // create the initial slices set
726 730 if (m_mapper->orientation() == Qt::Vertical) {
727 731 if (m_mapper->mapValues() >= m_model->columnCount() || m_mapper->mapLabels() >= m_model->columnCount())
728 732 return; // mapped columns are not existing
729 733
730 734 int sliceCount = 0;
731 735 if(m_mapper->count() == -1)
732 736 sliceCount = m_model->rowCount() - m_mapper->first();
733 737 else
734 738 sliceCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
735 739 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
736 740 q->append(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
737 741 } else {
738 742 if (m_mapper->mapValues() >= m_model->rowCount() || m_mapper->mapLabels() >= m_model->rowCount())
739 743 return; // mapped columns are not existing
740 744
741 745 int sliceCount = 0;
742 746 if(m_mapper->count() == -1)
743 747 sliceCount = m_model->columnCount() - m_mapper->first();
744 748 else
745 749 sliceCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
746 750 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
747 751 q->append(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
748 752 }
749 753 q->setLabelsVisible(true);
750 754 }
751 755
752 756 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
753 757 {
754 758 // Remove rounding errors
755 759 qreal roundedValue = newValue;
756 760 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
757 761 roundedValue = 0.0;
758 762 else if (qFuzzyCompare(newValue, max))
759 763 roundedValue = max;
760 764 else if (qFuzzyCompare(newValue, min))
761 765 roundedValue = min;
762 766
763 767 // Check if the position is valid after removing the rounding errors
764 768 if (roundedValue < min || roundedValue > max) {
765 769 qWarning("QPieSeries: Illegal value");
766 770 return false;
767 771 }
768 772
769 773 if (!qFuzzyIsNull(value - roundedValue)) {
770 774 value = roundedValue;
771 775 return true;
772 776 }
773 777
774 778 // The change was so small it is considered a rounding error
775 779 return false;
776 780 }
777 781
778 782 void QPieSeriesPrivate::scaleDomain(Domain& domain)
779 783 {
780 784 Q_UNUSED(domain);
781 785 #ifndef QT_NO_DEBUG
782 786 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
783 787 #endif
784 788 }
785 789
786 790 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
787 791 {
788 792 Q_Q(QPieSeries);
789 793 PieChartItem* pie = new PieChartItem(q,presenter);
790 794 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
791 795 presenter->animator()->addAnimation(pie);
792 796 }
793 797 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
794 798 return pie;
795 799 }
796 800
797 801 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
798 802 {
799 803 Q_Q(QPieSeries);
800 804 QList<LegendMarker*> markers;
801 805 foreach(QPieSlice* slice, q->slices()) {
802 806 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
803 807 markers << marker;
804 808 }
805 809 return markers;
806 810 }
807 811
808 812 #include "moc_qpieseries.cpp"
809 813 #include "moc_qpieseries_p.cpp"
810 814
811 815 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,326 +1,398
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 #include <qpiemodelmapper.h>
27 #include <QStandardItemModel>
26 28 #include <tst_definitions.h>
27 29
28 30 QTCOMMERCIALCHART_USE_NAMESPACE
29 31
30 32 Q_DECLARE_METATYPE(QPieSlice*)
31 33
32 34 class tst_qpieseries : public QObject
33 35 {
34 36 Q_OBJECT
35 37
36 38 public slots:
37 39 void initTestCase();
38 40 void cleanupTestCase();
39 41 void init();
40 42 void cleanup();
41 43
42 44 private slots:
43 45 void construction();
44 46 void append();
45 47 void insert();
46 48 void remove();
47 49 void calculatedValues();
48 50 void clickedSignal();
49 51 void hoverSignal();
52 void model();
53 void modelCustomMap();
50 54
51 55 private:
52 56 void verifyCalculatedData(const QPieSeries &series, bool *ok);
53 57
54 58 private:
55 59
56 60 };
57 61
58 62 void tst_qpieseries::initTestCase()
59 63 {
60 64 qRegisterMetaType<QPieSlice*>("QPieSlice*");
61 65 }
62 66
63 67 void tst_qpieseries::cleanupTestCase()
64 68 {
65 69 }
66 70
67 71 void tst_qpieseries::init()
68 72 {
69 73
70 74 }
71 75
72 76 void tst_qpieseries::cleanup()
73 77 {
74 78
75 79 }
76 80
77 81 void tst_qpieseries::construction()
78 82 {
79 83 // verify default values
80 84 QPieSeries s;
81 85 QVERIFY(s.type() == QAbstractSeries::SeriesTypePie);
82 86 QVERIFY(s.count() == 0);
83 87 QVERIFY(s.isEmpty());
84 88 QCOMPARE(s.sum(), 0.0);
85 89 QCOMPARE(s.horizontalPosition(), 0.5);
86 90 QCOMPARE(s.verticalPosition(), 0.5);
87 91 QCOMPARE(s.pieSize(), 0.7);
88 92 QCOMPARE(s.pieStartAngle(), 0.0);
89 93 QCOMPARE(s.pieEndAngle(), 360.0);
90 94 }
91 95
92 96 void tst_qpieseries::append()
93 97 {
94 98 QPieSeries s;
95 99
96 100 // append pointer
97 101 QPieSlice *slice1 = 0;
98 102 QVERIFY(!s.append(slice1));
99 103 slice1 = new QPieSlice(1, "slice 1");
100 104 QVERIFY(s.append(slice1));
101 105 QVERIFY(!s.append(slice1));
102 106 QCOMPARE(s.count(), 1);
103 107
104 108 // append pointer list
105 109 QList<QPieSlice *> list;
106 110 QVERIFY(!s.append(list));
107 111 list << (QPieSlice *) 0;
108 112 QVERIFY(!s.append(list));
109 113 list.clear();
110 114 list << new QPieSlice(2, "slice 2");
111 115 list << new QPieSlice(3, "slice 3");
112 116 QVERIFY(s.append(list));
113 117 QVERIFY(!s.append(list));
114 118 QCOMPARE(s.count(), 3);
115 119
116 120 // append operator
117 121 s << new QPieSlice(4, "slice 4");
118 122 s << slice1; // fails because already added
119 123 QCOMPARE(s.count(), 4);
120 124
121 125 // append with params
122 126 QPieSlice *slice5 = s.append(5, "slice 5");
123 127 QVERIFY(slice5 != 0);
124 128 QCOMPARE(slice5->value(), 5.0);
125 129 QCOMPARE(slice5->label(), QString("slice 5"));
126 130 QCOMPARE(s.count(), 5);
127 131
128 132 // check slices
129 133 QVERIFY(!s.isEmpty());
130 134 for (int i=0; i<s.count(); i++) {
131 135 QCOMPARE(s.slices().at(i)->value(), (qreal) i+1);
132 136 QCOMPARE(s.slices().at(i)->label(), QString("slice ") + QString::number(i+1));
133 137 }
134 138 }
135 139
136 140 void tst_qpieseries::insert()
137 141 {
138 142 QPieSeries s;
139 143
140 144 // insert one slice
141 145 QPieSlice *slice1 = 0;
142 146 QVERIFY(!s.insert(0, slice1));
143 147 slice1 = new QPieSlice(1, "slice 1");
144 148 QVERIFY(!s.insert(-1, slice1));
145 149 QVERIFY(!s.insert(5, slice1));
146 150 QVERIFY(s.insert(0, slice1));
147 151 QVERIFY(!s.insert(0, slice1));
148 152 QCOMPARE(s.count(), 1);
149 153
150 154 // add some more slices
151 155 s.append(2, "slice 2");
152 156 s.append(4, "slice 4");
153 157 QCOMPARE(s.count(), 3);
154 158
155 159 // insert between slices
156 160 s.insert(2, new QPieSlice(3, "slice 3"));
157 161 QCOMPARE(s.count(), 4);
158 162
159 163 // check slices
160 164 for (int i=0; i<s.count(); i++) {
161 165 QCOMPARE(s.slices().at(i)->value(), (qreal) i+1);
162 166 QCOMPARE(s.slices().at(i)->label(), QString("slice ") + QString::number(i+1));
163 167 }
164 168 }
165 169
166 170 void tst_qpieseries::remove()
167 171 {
168 172 QPieSeries s;
169 173
170 174 // add some slices
171 175 QPieSlice *slice1 = s.append(1, "slice 1");
172 176 QPieSlice *slice2 = s.append(2, "slice 2");
173 177 QPieSlice *slice3 = s.append(3, "slice 3");
174 178 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
175 179 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
176 180 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
177 181 QCOMPARE(s.count(), 3);
178 182
179 183 // null pointer remove
180 184 QVERIFY(!s.remove(0));
181 185
182 186 // remove first
183 187 QVERIFY(s.remove(slice1));
184 188 QVERIFY(!s.remove(slice1));
185 189 QCOMPARE(s.count(), 2);
186 190 QCOMPARE(s.slices().at(0)->label(), slice2->label());
187 191
188 192 // remove all
189 193 s.clear();
190 194 QVERIFY(s.isEmpty());
191 195 QVERIFY(s.slices().isEmpty());
192 196 QCOMPARE(s.count(), 0);
193 197
194 198 // check that slices were actually destroyed
195 199 TRY_COMPARE(spy1.count(), 1);
196 200 TRY_COMPARE(spy2.count(), 1);
197 201 TRY_COMPARE(spy3.count(), 1);
198 202 }
199 203
200 204 void tst_qpieseries::calculatedValues()
201 205 {
202 206 bool ok;
203 207 QPieSeries s;
204 208
205 209 // add a slice
206 210 QPieSlice *slice1 = s.append(1, "slice 1");
207 211 verifyCalculatedData(s, &ok);
208 212 if (!ok)
209 213 return;
210 214
211 215 // add some more slices
212 216 QList<QPieSlice *> list;
213 217 list << new QPieSlice(2, "slice 2");
214 218 list << new QPieSlice(3, "slice 3");
215 219 s.append(list);
216 220 verifyCalculatedData(s, &ok);
217 221 if (!ok)
218 222 return;
219 223
220 224 // remove a slice
221 225 s.remove(slice1);
222 226 verifyCalculatedData(s, &ok);
223 227 if (!ok)
224 228 return;
225 229
226 230 // insert a slice
227 231 s.insert(0, new QPieSlice(1, "Slice 4"));
228 232 verifyCalculatedData(s, &ok);
229 233 if (!ok)
230 234 return;
231 235
232 236 // clear all
233 237 s.clear();
234 238 verifyCalculatedData(s, &ok);
235 239 }
236 240
237 241 void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
238 242 {
239 243 *ok = false;
240 244
241 245 qreal sum = 0;
242 246 foreach (const QPieSlice *slice, series.slices())
243 247 sum += slice->value();
244 248 QCOMPARE(series.sum(), sum);
245 249
246 250 qreal startAngle = series.pieStartAngle();
247 251 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
248 252 foreach (const QPieSlice *slice, series.slices()) {
249 253 qreal ratio = slice->value() / sum;
250 254 qreal sliceSpan = pieAngleSpan * ratio;
251 255 QCOMPARE(slice->startAngle(), startAngle);
252 256 QCOMPARE(slice->endAngle(), startAngle + sliceSpan);
253 257 QCOMPARE(slice->percentage(), ratio);
254 258 startAngle += sliceSpan;
255 259 }
256 260
257 261 if (!series.isEmpty())
258 262 QCOMPARE(series.slices().last()->endAngle(), series.pieEndAngle());
259 263
260 264 *ok = true;
261 265 }
262 266
263 267
264 268 void tst_qpieseries::clickedSignal()
265 269 {
266 270 // create a pie series
267 271 QPieSeries *series = new QPieSeries();
268 272 series->setPieSize(1.0);
269 273 QPieSlice *s1 = series->append(1, "slice 1");
270 274 series->append(2, "slice 2");
271 275 series->append(3, "slice 3");
272 276 QSignalSpy clickSpy1(series, SIGNAL(clicked(QPieSlice*)));
273 277
274 278 // add series to the chart
275 279 QChartView view(new QChart());
276 280 view.resize(200, 200);
277 281 view.chart()->addSeries(series);
278 282 view.show();
279 283 QTest::qWaitForWindowShown(&view);
280 284
281 285 // simulate clicks
282 286 // pie rectangle: QRectF(60,60 121x121)
283 287 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(139, 85)); // inside slice 1
284 288 TRY_COMPARE(clickSpy1.count(), 1);
285 289 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy1.at(0).at(0)), s1);
286 290 }
287 291
288 292 void tst_qpieseries::hoverSignal()
289 293 {
290 294 // create a pie series
291 295 QPieSeries *series = new QPieSeries();
292 296 series->setPieSize(1.0);
293 297 QPieSlice *s1 = series->append(1, "slice 1");
294 298 series->append(2, "slice 2");
295 299 series->append(3, "slice 3");
296 300
297 301 // add series to the chart
298 302 QChartView view(new QChart());
299 303 view.resize(200, 200);
300 304 view.chart()->addSeries(series);
301 305 view.show();
302 306 QTest::qWaitForWindowShown(&view);
303 307
304 308 // first move to right top corner
305 309 QTest::mouseMove(view.viewport(), QPoint(200, 0));
306 310 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
307 311
308 312 // move inside the slice
309 313 // pie rectangle: QRectF(60,60 121x121)
310 314 QSignalSpy hoverSpy(series, SIGNAL(hovered(QPieSlice*,bool)));
311 315 QTest::mouseMove(view.viewport(), QPoint(139, 85));
312 316 TRY_COMPARE(hoverSpy.count(), 1);
313 317 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(0).at(0)), s1);
314 318 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(0).at(1)), true);
315 319
316 320 // move outside the slice
317 321 QTest::mouseMove(view.viewport(), QPoint(200, 0));
318 322 TRY_COMPARE(hoverSpy.count(), 2);
319 323 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(1).at(0)), s1);
320 324 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(1).at(1)), false);
321 325 }
322 326
327 void tst_qpieseries::model()
328 {
329 QPieSeries *series = new QPieSeries;
330 QStandardItemModel *stdModel = new QStandardItemModel(0, 2);
331 series->setModel(stdModel);
332 QVERIFY2((series->model()) == stdModel, "Model should be stdModel");
333
334 int rowCount = 3;
335 for (int row = 0; row < rowCount; ++row) {
336 for (int column = 0; column < 2; column++) {
337 QStandardItem *item = new QStandardItem(row * column);
338 stdModel->setItem(row, column, item);
339 }
340 }
341
342 // data has been added to the model, but mapper is not set the number of slices should still be 0
343 QVERIFY2(series->slices().count() == 0, "Mapper has not been set, so the number of slices should be 0");
344
345 // set the mapper
346 QPieModelMapper *mapper = new QPieModelMapper;
347 mapper->setMapValues(0);
348 mapper->setMapLabels(0);
349 series->setModelMapper(mapper); // this should cause the Pie to get initialized from the model, since there is now both the model and the mapper defined
350 QCOMPARE(series->slices().count(), rowCount);
351
352 // reset the mappings
353 mapper->reset();
354 QCOMPARE(series->slices().count(), 0); // Mappings have been reset and are invalid, so the number of slices should be 0
355
356 // unset the model and the mapper
357 series->setModel(0);
358 series->setModelMapper(0);
359 QVERIFY(series->model() == 0); // Model should be unset
360 QVERIFY(series->modelMapper() == 0); // Model mapper should be unset
361 }
362
363 void tst_qpieseries::modelCustomMap()
364 {
365 int rowCount = 12;
366 QStandardItemModel *stdModel = new QStandardItemModel(0, 2);
367 for (int row = 0; row < rowCount; ++row) {
368 for (int column = 0; column < 2; column++) {
369 QStandardItem *item = new QStandardItem(row * column);
370 stdModel->setItem(row, column, item);
371 }
372 }
373
374 QPieSeries *series = new QPieSeries;
375 series->setModel(stdModel);
376
377 QPieModelMapper *mapper = new QPieModelMapper;
378 mapper->setMapValues(0);
379 mapper->setMapLabels(0);
380 series->setModelMapper(mapper);
381 QCOMPARE(series->slices().count(), rowCount);
382
383 // lets customize the mapping
384 int first = 3;
385 mapper->setFirst(first);
386 QCOMPARE(series->slices().count(), rowCount - first);
387 int count = 7;
388 mapper->setCount(count);
389 QCOMPARE(series->slices().count(), count);
390 first = 9;
391 mapper->setFirst(first);
392 QCOMPARE(series->slices().count(), qMin(count, rowCount - first));
393 }
394
323 395 QTEST_MAIN(tst_qpieseries)
324 396
325 397 #include "tst_qpieseries.moc"
326 398
General Comments 0
You need to be logged in to leave comments. Login now