##// END OF EJS Templates
fix barseries remove return value with empty list
sauimone -
r1371:3e1a815a432d
parent child
Show More
@@ -1,654 +1,657
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 "qbarseries.h"
22 22 #include "qbarseries_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "domain_p.h"
26 26 #include "legendmarker_p.h"
27 27 #include "chartdataset_p.h"
28 28 #include "charttheme_p.h"
29 29 #include "chartanimator_p.h"
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \class QBarSeries
35 35 \brief part of QtCommercial chart API.
36 36 \mainclass
37 37
38 38 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
39 39 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
40 40 and y-value is the height of the bar. The category names are ignored with this series and x-axis
41 41 shows the x-values.
42 42
43 43 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
44 44 \image examples_barchart.png
45 45
46 46 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
47 47 */
48 48
49 49 /*!
50 50 \property QBarSeries::barMargin
51 51 \brief Defines the margin around bars.
52 52
53 53 Value is from 0 to 1 and represents
54 54 percentage of margin compared to bars
55 55 */
56 56
57 57 /*!
58 58 \property QBarSeries::count
59 59 \brief Holds the number of sets in series.
60 60 */
61 61
62 62 /*!
63 63 \property QBarSeries::labelsVisible
64 64 \brief Defines the visibility of the labels in series
65 65 */
66 66
67 67 /*!
68 68 \fn void QBarSeries::clicked(QBarSet *barset, int index)
69 69
70 70 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
71 71 Clicked bar inside set is indexed by \a index
72 72 */
73 73
74 74 /*!
75 75 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
76 76
77 77 The signal is emitted if mouse is hovered on top of series.
78 78 Parameter \a barset is the pointer of barset, where hover happened.
79 79 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
80 80 */
81 81
82 82 /*!
83 83 \fn void QBarSeries::visibleChanged()
84 84 */
85 85
86 86 /*!
87 87 \fn void QBarSeries::labelsVisibleChanged()
88 88
89 89 This signal is emitted when labels visibility have changed.
90 90
91 91 \sa isLabelsVisible(), setLabelsVisible()
92 92 */
93 93
94 94 /*!
95 95 \fn void QBarSeries::barsetsAdded(QList<QBarSet*> sets)
96 96
97 97 This signal is emitted when \a sets have been added to the series.
98 98
99 99 \sa append(), insert()
100 100 */
101 101
102 102 /*!
103 103 \fn void QBarSeries::barsetsRemoved(QList<QBarSet*> sets)
104 104
105 105 This signal is emitted when \a sets have been removed from the series.
106 106
107 107 \sa remove()
108 108 */
109 109
110 110 /*!
111 111 Constructs empty QBarSeries.
112 112 QBarSeries is QObject which is a child of a \a parent.
113 113 */
114 114 QBarSeries::QBarSeries(QObject *parent) :
115 115 QAbstractSeries(*new QBarSeriesPrivate(this),parent)
116 116 {
117 117 }
118 118
119 119 /*!
120 120 Destructs barseries and owned barsets.
121 121 */
122 122 QBarSeries::~QBarSeries()
123 123 {
124 124 Q_D(QBarSeries);
125 125 if(d->m_dataset){
126 126 d->m_dataset->removeSeries(this);
127 127 }
128 128 }
129 129
130 130 /*!
131 131 \internal
132 132 */
133 133 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
134 134 QAbstractSeries(d,parent)
135 135 {
136 136 }
137 137
138 138 /*!
139 139 Returns the type of series. Derived classes override this.
140 140 */
141 141 QAbstractSeries::SeriesType QBarSeries::type() const
142 142 {
143 143 return QAbstractSeries::SeriesTypeBar;
144 144 }
145 145
146 146 /*!
147 147 Sets the margin around bars. Parameter \a margin is from 0 to 1 and represents
148 148 percentage of margin compared to bars
149 149 */
150 150 void QBarSeries::setBarMargin(qreal margin)
151 151 {
152 152 Q_D(QBarSeries);
153 153 d->setBarMargin(margin);
154 154 }
155 155
156 156 /*!
157 157 Returns the margin around bars
158 158 */
159 159 qreal QBarSeries::barMargin() const
160 160 {
161 161 Q_D(const QBarSeries);
162 162 return d->barMargin();
163 163 }
164 164
165 165 /*!
166 166 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
167 167 Returns true, if appending succeeded.
168 168
169 169 */
170 170 bool QBarSeries::append(QBarSet *set)
171 171 {
172 172 Q_D(QBarSeries);
173 173 bool success = d->append(set);
174 174 if (success) {
175 175 QList<QBarSet*> sets;
176 176 sets.append(set);
177 177 emit barsetsAdded(sets);
178 178 }
179 179 return success;
180 180 }
181 181
182 182 /*!
183 183 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
184 184 Returns true, if set was removed.
185 185 */
186 186 bool QBarSeries::remove(QBarSet *set)
187 187 {
188 188 Q_D(QBarSeries);
189 189 bool success = d->remove(set);
190 190 if (success) {
191 191 QList<QBarSet*> sets;
192 192 sets.append(set);
193 193 emit barsetsRemoved(sets);
194 194 }
195 195 return success;
196 196 }
197 197
198 198 /*!
199 199 Adds a list of barsets to series. Takes ownership of \a sets.
200 200 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
201 201 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
202 202 and function returns false.
203 203 */
204 204 bool QBarSeries::append(QList<QBarSet* > sets)
205 205 {
206 206 Q_D(QBarSeries);
207 207 bool success = d->append(sets);
208 208 if (success) {
209 209 emit barsetsAdded(sets);
210 210 }
211 211 return success;
212 212 }
213 213
214 214 /*!
215 215 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
216 216 */
217 217 bool QBarSeries::remove(QList<QBarSet* > sets)
218 218 {
219 219 Q_D(QBarSeries);
220 220 bool success = d->remove(sets);
221 221 if (success) {
222 222 emit barsetsRemoved(sets);
223 223 }
224 224 return success;
225 225 }
226 226
227 227 /*!
228 228 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
229 229 Returns true, if inserting succeeded.
230 230
231 231 */
232 232 bool QBarSeries::insert(int index, QBarSet *set)
233 233 {
234 234 Q_D(QBarSeries);
235 235 bool success = d->insert(index, set);
236 236 if (success) {
237 237 QList<QBarSet*> sets;
238 238 sets.append(set);
239 239 emit barsetsAdded(sets);
240 240 }
241 241 return success;
242 242 }
243 243
244 244 /*!
245 245 Removes all of the bar sets from the series
246 246 */
247 247 void QBarSeries::clear()
248 248 {
249 249 Q_D(QBarSeries);
250 250 QList<QBarSet *> sets = barSets();
251 251 bool success = d->remove(sets);
252 252 if (success) {
253 253 emit barsetsRemoved(sets);
254 254 }
255 255 }
256 256
257 257 /*!
258 258 Returns number of sets in series.
259 259 */
260 260 int QBarSeries::barsetCount() const
261 261 {
262 262 Q_D(const QBarSeries);
263 263 return d->m_barSets.count();
264 264 }
265 265
266 266 /*!
267 267 Returns a list of sets in series. Keeps ownership of sets.
268 268 */
269 269 QList<QBarSet*> QBarSeries::barSets() const
270 270 {
271 271 Q_D(const QBarSeries);
272 272 return d->m_barSets;
273 273 }
274 274
275 275 /*!
276 276 Sets the visibility of labels in series to \a visible
277 277 */
278 278 void QBarSeries::setLabelsVisible(bool visible)
279 279 {
280 280 Q_D(QBarSeries);
281 281 if (d->m_labelsVisible != visible) {
282 282 d->setLabelsVisible(visible);
283 283 emit labelsVisibleChanged();
284 284 }
285 285 }
286 286
287 287 /*!
288 288 Returns the visibility of labels
289 289 */
290 290 bool QBarSeries::isLabelsVisible() const
291 291 {
292 292 Q_D(const QBarSeries);
293 293 return d->m_labelsVisible;
294 294 }
295 295
296 296 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
297 297
298 298 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
299 299 QAbstractSeriesPrivate(q),
300 300 m_barMargin(0.5), // Default value is 50% of category width
301 301 m_labelsVisible(false),
302 302 m_visible(true)
303 303 {
304 304 }
305 305
306 306 void QBarSeriesPrivate::setCategories(QStringList categories)
307 307 {
308 308 m_categories = categories;
309 309 }
310 310
311 311 void QBarSeriesPrivate::insertCategory(int index, const QString category)
312 312 {
313 313 m_categories.insert(index, category);
314 314 emit categoriesUpdated();
315 315 }
316 316
317 317 void QBarSeriesPrivate::removeCategory(int index)
318 318 {
319 319 m_categories.removeAt(index);
320 320 emit categoriesUpdated();
321 321 }
322 322
323 323 int QBarSeriesPrivate::categoryCount() const
324 324 {
325 325 if (m_categories.count() > 0) {
326 326 return m_categories.count();
327 327 }
328 328
329 329 // No categories defined. return count of longest set.
330 330 int count = 0;
331 331 for (int i=0; i<m_barSets.count(); i++) {
332 332 if (m_barSets.at(i)->count() > count) {
333 333 count = m_barSets.at(i)->count();
334 334 }
335 335 }
336 336
337 337 return count;
338 338 }
339 339
340 340 QStringList QBarSeriesPrivate::categories() const
341 341 {
342 342 if (m_categories.count() > 0) {
343 343 return m_categories;
344 344 }
345 345
346 346 // No categories defined. retun list of indices.
347 347 QStringList categories;
348 348
349 349 int count = categoryCount();
350 350 for (int i = 0; i < count; i++) {
351 351 categories.append(QString::number(i));
352 352 }
353 353 return categories;
354 354 }
355 355
356 356 void QBarSeriesPrivate::setBarMargin(qreal margin)
357 357 {
358 358 if (margin > 1.0) {
359 359 margin = 1.0;
360 360 } else if (margin < 0.0) {
361 361 margin = 0.0;
362 362 }
363 363
364 364 m_barMargin = margin;
365 365 emit updatedBars();
366 366 }
367 367
368 368 qreal QBarSeriesPrivate::barMargin() const
369 369 {
370 370 return m_barMargin;
371 371 }
372 372
373 373 QBarSet* QBarSeriesPrivate::barsetAt(int index)
374 374 {
375 375 return m_barSets.at(index);
376 376 }
377 377
378 378 void QBarSeriesPrivate::setVisible(bool visible)
379 379 {
380 380 m_visible = visible;
381 381 emit updatedBars();
382 382 }
383 383
384 384 void QBarSeriesPrivate::setLabelsVisible(bool visible)
385 385 {
386 386 m_labelsVisible = visible;
387 387 emit labelsVisibleChanged(visible);
388 388 }
389 389
390 390 QString QBarSeriesPrivate::categoryName(int category)
391 391 {
392 392 if ((category >= 0) && (category < m_categories.count())) {
393 393 return m_categories.at(category);
394 394 }
395 395
396 396 return QString::number(category);
397 397 }
398 398
399 399 qreal QBarSeriesPrivate::min()
400 400 {
401 401 if (m_barSets.count() <= 0) {
402 402 return 0;
403 403 }
404 404 qreal min = INT_MAX;
405 405
406 406 for (int i = 0; i < m_barSets.count(); i++) {
407 407 int categoryCount = m_barSets.at(i)->count();
408 408 for (int j = 0; j < categoryCount; j++) {
409 409 qreal temp = m_barSets.at(i)->at(j).y();
410 410 if (temp < min)
411 411 min = temp;
412 412 }
413 413 }
414 414 return min;
415 415 }
416 416
417 417 qreal QBarSeriesPrivate::max()
418 418 {
419 419 if (m_barSets.count() <= 0) {
420 420 return 0;
421 421 }
422 422 qreal max = INT_MIN;
423 423
424 424 for (int i = 0; i < m_barSets.count(); i++) {
425 425 int categoryCount = m_barSets.at(i)->count();
426 426 for (int j = 0; j < categoryCount; j++) {
427 427 qreal temp = m_barSets.at(i)->at(j).y();
428 428 if (temp > max)
429 429 max = temp;
430 430 }
431 431 }
432 432
433 433 return max;
434 434 }
435 435
436 436 qreal QBarSeriesPrivate::valueAt(int set, int category)
437 437 {
438 438 if ((set < 0) || (set >= m_barSets.count())) {
439 439 // No set, no value.
440 440 return 0;
441 441 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
442 442 // No category, no value.
443 443 return 0;
444 444 }
445 445
446 446 return m_barSets.at(set)->at(category).y();
447 447 }
448 448
449 449 qreal QBarSeriesPrivate::percentageAt(int set, int category)
450 450 {
451 451 if ((set < 0) || (set >= m_barSets.count())) {
452 452 // No set, no value.
453 453 return 0;
454 454 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
455 455 // No category, no value.
456 456 return 0;
457 457 }
458 458
459 459 qreal value = m_barSets.at(set)->at(category).y();
460 460 qreal sum = categorySum(category);
461 461 if ( qFuzzyIsNull(sum) ) {
462 462 return 0;
463 463 }
464 464
465 465 return value / sum;
466 466 }
467 467
468 468 qreal QBarSeriesPrivate::categorySum(int category)
469 469 {
470 470 qreal sum(0);
471 471 int count = m_barSets.count(); // Count sets
472 472 for (int set = 0; set < count; set++) {
473 473 if (category < m_barSets.at(set)->count())
474 474 sum += m_barSets.at(set)->at(category).y();
475 475 }
476 476 return sum;
477 477 }
478 478
479 479 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
480 480 {
481 481 qreal sum(0);
482 482 int count = m_barSets.count(); // Count sets
483 483 for (int set = 0; set < count; set++) {
484 484 if (category < m_barSets.at(set)->count())
485 485 sum += qAbs(m_barSets.at(set)->at(category).y());
486 486 }
487 487 return sum;
488 488 }
489 489
490 490 qreal QBarSeriesPrivate::maxCategorySum()
491 491 {
492 492 qreal max = INT_MIN;
493 493 int count = categoryCount();
494 494 for (int i = 0; i < count; i++) {
495 495 qreal sum = categorySum(i);
496 496 if (sum > max)
497 497 max = sum;
498 498 }
499 499 return max;
500 500 }
501 501
502 502 void QBarSeriesPrivate::scaleDomain(Domain& domain)
503 503 {
504 504 qreal minX(domain.minX());
505 505 qreal minY(domain.minY());
506 506 qreal maxX(domain.maxX());
507 507 qreal maxY(domain.maxY());
508 508 int tickXCount(domain.tickXCount());
509 509 int tickYCount(domain.tickYCount());
510 510
511 511 qreal x = categoryCount();
512 512 qreal y = max();
513 513 minX = qMin(minX, x) - 0.5;
514 514 minY = qMin(minY, y);
515 515 maxX = qMax(maxX, x) - 0.5;
516 516 maxY = qMax(maxY, y);
517 517 tickXCount = x+1;
518 518
519 519 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
520 520 }
521 521
522 522 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
523 523 {
524 524 Q_Q(QBarSeries);
525 525
526 526 BarChartItem* bar = new BarChartItem(q,presenter);
527 527 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
528 528 presenter->animator()->addAnimation(bar);
529 529 }
530 530 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
531 531 return bar;
532 532
533 533 }
534 534
535 535 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
536 536 {
537 537 Q_Q(QBarSeries);
538 538 QList<LegendMarker*> markers;
539 539 foreach(QBarSet* set, q->barSets()) {
540 540 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
541 541 markers << marker;
542 542 }
543 543
544 544 return markers;
545 545 }
546 546
547 547 bool QBarSeriesPrivate::append(QBarSet *set)
548 548 {
549 549 Q_Q(QBarSeries);
550 550 if ((m_barSets.contains(set)) || (set == 0)) {
551 551 // Fail if set is already in list or set is null.
552 552 return false;
553 553 }
554 554 m_barSets.append(set);
555 555 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
556 556 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
557 557 if (m_dataset) {
558 558 m_dataset->updateSeries(q); // this notifies legend
559 559 }
560 560 emit restructuredBars(); // this notifies barchartitem
561 561 return true;
562 562 }
563 563
564 564 bool QBarSeriesPrivate::remove(QBarSet *set)
565 565 {
566 566 Q_Q(QBarSeries);
567 567 if (!m_barSets.contains(set)) {
568 568 // Fail if set is not in list
569 569 return false;
570 570 }
571 571 m_barSets.removeOne(set);
572 572 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
573 573 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
574 574 if (m_dataset) {
575 575 m_dataset->updateSeries(q); // this notifies legend
576 576 }
577 577 emit restructuredBars(); // this notifies barchartitem
578 578 return true;
579 579 }
580 580
581 581 bool QBarSeriesPrivate::append(QList<QBarSet* > sets)
582 582 {
583 583 Q_Q(QBarSeries);
584 584 foreach (QBarSet* set, sets) {
585 585 if ((set == 0) || (m_barSets.contains(set))) {
586 586 // Fail if any of the sets is null or is already appended.
587 587 return false;
588 588 }
589 589 if (sets.count(set) != 1) {
590 590 // Also fail if same set is more than once in given list.
591 591 return false;
592 592 }
593 593 }
594 594
595 595 foreach (QBarSet* set, sets) {
596 596 m_barSets.append(set);
597 597 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
598 598 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
599 599 }
600 600 if (m_dataset) {
601 601 m_dataset->updateSeries(q); // this notifies legend
602 602 }
603 603 emit restructuredBars(); // this notifies barchartitem
604 604 return true;
605 605 }
606 606
607 607 bool QBarSeriesPrivate::remove(QList<QBarSet* > sets)
608 608 {
609 609 Q_Q(QBarSeries);
610 if (sets.count() == 0) {
611 return false;
612 }
610 613 foreach (QBarSet* set, sets) {
611 614 if ((set == 0) || (!m_barSets.contains(set))) {
612 615 // Fail if any of the sets is null or is not in series
613 616 return false;
614 617 }
615 618 if (sets.count(set) != 1) {
616 619 // Also fail if same set is more than once in given list.
617 620 return false;
618 621 }
619 622 }
620 623
621 624 foreach (QBarSet* set, sets) {
622 625 m_barSets.removeOne(set);
623 626 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
624 627 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
625 628 }
626 629
627 630 if (m_dataset) {
628 631 m_dataset->updateSeries(q); // this notifies legend
629 632 }
630 633 emit restructuredBars(); // this notifies barchartitem
631 634 return true;
632 635 }
633 636
634 637 bool QBarSeriesPrivate::insert(int index, QBarSet *set)
635 638 {
636 639 Q_Q(QBarSeries);
637 640 if ((m_barSets.contains(set)) || (set == 0)) {
638 641 // Fail if set is already in list or set is null.
639 642 return false;
640 643 }
641 644 m_barSets.insert(index, set);
642 645 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
643 646 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
644 647 if (m_dataset) {
645 648 m_dataset->updateSeries(q); // this notifies legend
646 649 }
647 650 emit restructuredBars(); // this notifies barchartitem
648 651 return true;
649 652 }
650 653
651 654 #include "moc_qbarseries.cpp"
652 655 #include "moc_qbarseries_p.cpp"
653 656
654 657 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now