##// END OF EJS Templates
Revert barseries thought to be only model related
Marek Rosa -
r1333:415d595f93c9
parent child
Show More
@@ -1,545 +1,562
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 \fn void QBarSeries::clicked(QBarSet *barset, int index)
51 51
52 52 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
53 53 Clicked bar inside set is indexed by \a index
54 54 */
55 55
56 56 /*!
57 57 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
58 58
59 59 The signal is emitted if mouse is hovered on top of series.
60 60 Parameter \a barset is the pointer of barset, where hover happened.
61 61 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
62 62 */
63 63
64 64 /*!
65 65 Constructs empty QBarSeries.
66 66 QBarSeries is QObject which is a child of a \a parent.
67 67 */
68 68 QBarSeries::QBarSeries(QObject *parent) :
69 69 QAbstractSeries(*new QBarSeriesPrivate(this),parent)
70 70 {
71 71 }
72 72
73 73 /*!
74 74 Destructs barseries and owned barsets.
75 75 */
76 76 QBarSeries::~QBarSeries()
77 77 {
78 78 Q_D(QBarSeries);
79 79 if(d->m_dataset){
80 80 d->m_dataset->removeSeries(this);
81 81 }
82 82 }
83 83
84 84 /*!
85 85 \internal
86 86 */
87 87 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
88 88 QAbstractSeries(d,parent)
89 89 {
90 90 }
91 91
92 92 /*!
93 93 Returns the type of series. Derived classes override this.
94 94 */
95 95 QAbstractSeries::SeriesType QBarSeries::type() const
96 96 {
97 97 return QAbstractSeries::SeriesTypeBar;
98 98 }
99 99
100 100 /*!
101 101 Sets the margin around bars. Parameter \a margin is from 0 to 1 and represents
102 102 percentage of margin compared to bars
103 103 */
104 104 void QBarSeries::setBarMargin(qreal margin)
105 105 {
106 106 Q_D(QBarSeries);
107 107 d->setBarMargin(margin);
108 108 }
109 109
110 110 /*!
111 111 Returns the margin around bars
112 112 */
113 113 qreal QBarSeries::barMargin() const
114 114 {
115 115 Q_D(const QBarSeries);
116 116 return d->barMargin();
117 117 }
118 118
119 119 /*!
120 120 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.
121 121 Returns true, if appending succeeded.
122 122
123 123 */
124 124 bool QBarSeries::append(QBarSet *set)
125 125 {
126 126 Q_D(QBarSeries);
127 127 return d->append(set);
128 128 }
129 129
130 130 /*!
131 131 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
132 132 Returns true, if set was removed.
133 133 */
134 134 bool QBarSeries::remove(QBarSet *set)
135 135 {
136 136 Q_D(QBarSeries);
137 137 return d->remove(set);
138 138 }
139 139
140 140 /*!
141 141 Adds a list of barsets to series. Takes ownership of \a sets.
142 142 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
143 143 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
144 144 and function returns false.
145 145 */
146 146 bool QBarSeries::append(QList<QBarSet* > sets)
147 147 {
148 148 Q_D(QBarSeries);
149 149 return d->append(sets);
150 150 }
151 151
152 152 /*!
153 153 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
154 154 */
155 155 bool QBarSeries::remove(QList<QBarSet* > sets)
156 156 {
157 157 Q_D(QBarSeries);
158 158 return d->remove(sets);
159 159 }
160 160
161 161 void QBarSeries::clear()
162 162 {
163 163 Q_D(QBarSeries);
164 164 d->m_barSets.clear();
165 165 }
166 166
167 167 /*!
168 168 Returns number of sets in series.
169 169 */
170 170 int QBarSeries::barsetCount() const
171 171 {
172 172 Q_D(const QBarSeries);
173 173 return d->m_barSets.count();
174 174 }
175 175
176 176 /*!
177 177 Returns a list of sets in series. Keeps ownership of sets.
178 178 */
179 179 QList<QBarSet*> QBarSeries::barSets() const
180 180 {
181 181 Q_D(const QBarSeries);
182 182 return d->m_barSets;
183 183 }
184 184
185 185 /*!
186 186 Sets the visibility of series to \a visible
187 187 */
188 188 void QBarSeries::setVisible(bool visible)
189 189 {
190 190 Q_D(QBarSeries);
191 191 d->setVisible(visible);
192 192 }
193 193
194 194 /*!
195 195 Returns the visibility of series
196 196 */
197 197 bool QBarSeries::isVisible() const
198 198 {
199 199 Q_D(const QBarSeries);
200 200 return d->isVisible();
201 201 }
202 202
203 203 /*!
204 204 Sets the visibility of labels in series to \a visible
205 205 */
206 206 void QBarSeries::setLabelsVisible(bool visible)
207 207 {
208 208 Q_D(QBarSeries);
209 209 if (d->m_labelsVisible != visible) {
210 210 d->m_labelsVisible = visible;
211 211 emit d->labelsVisibleChanged(visible);
212 212 }
213 213 }
214 214
215 215 /*!
216 216 Returns the visibility of labels
217 217 */
218 218 bool QBarSeries::isLabelsVisible() const
219 219 {
220 220 Q_D(const QBarSeries);
221 221 return d->m_labelsVisible;
222 222 }
223 223
224 224 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225 225
226 226 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
227 227 QAbstractSeriesPrivate(q),
228 228 m_barMargin(0.5), // Default value is 50% of category width
229 229 m_labelsVisible(false),
230 230 m_visible(true)
231 231 {
232 232 }
233 233
234 void QBarSeriesPrivate::setCategories(QStringList categories)
235 {
236 m_categories = categories;
237 }
238
239 void QBarSeriesPrivate::insertCategory(int index, const QString category)
240 {
241 m_categories.insert(index, category);
242 emit categoriesUpdated();
243 }
244
245 void QBarSeriesPrivate::removeCategory(int index)
246 {
247 m_categories.removeAt(index);
248 emit categoriesUpdated();
249 }
250
234 251 int QBarSeriesPrivate::categoryCount() const
235 252 {
236 253 if (m_categories.count() > 0) {
237 254 return m_categories.count();
238 255 }
239 256
240 257 // No categories defined. return count of longest set.
241 258 int count = 0;
242 259 for (int i=0; i<m_barSets.count(); i++) {
243 260 if (m_barSets.at(i)->count() > count) {
244 261 count = m_barSets.at(i)->count();
245 262 }
246 263 }
247 264
248 265 return count;
249 266 }
250 267
251 268 QStringList QBarSeriesPrivate::categories() const
252 269 {
253 270 if (m_categories.count() > 0) {
254 271 return m_categories;
255 272 }
256 273
257 274 // No categories defined. retun list of indices.
258 275 QStringList categories;
259 276
260 277 int count = categoryCount();
261 278 for (int i = 0; i < count; i++) {
262 279 categories.append(QString::number(i));
263 280 }
264 281 return categories;
265 282 }
266 283
267 284 void QBarSeriesPrivate::setBarMargin(qreal margin)
268 285 {
269 286 if (margin > 1.0) {
270 287 margin = 1.0;
271 288 } else if (margin < 0.0) {
272 289 margin = 0.0;
273 290 }
274 291
275 292 m_barMargin = margin;
276 293 emit updatedBars();
277 294 }
278 295
279 296 qreal QBarSeriesPrivate::barMargin() const
280 297 {
281 298 return m_barMargin;
282 299 }
283 300
284 301 QBarSet* QBarSeriesPrivate::barsetAt(int index)
285 302 {
286 303 return m_barSets.at(index);
287 304 }
288 305
289 306 void QBarSeriesPrivate::setVisible(bool visible)
290 307 {
291 308 if (m_visible != visible) {
292 309 m_visible = visible;
293 310 emit updatedBars();
294 311 }
295 312 }
296 313
297 314 bool QBarSeriesPrivate::isVisible() const
298 315 {
299 316 return m_visible;
300 317 }
301 318
302 319 QString QBarSeriesPrivate::categoryName(int category)
303 320 {
304 321 if ((category >= 0) && (category < m_categories.count())) {
305 322 return m_categories.at(category);
306 323 }
307 324
308 325 return QString::number(category);
309 326 }
310 327
311 328 qreal QBarSeriesPrivate::min()
312 329 {
313 330 if (m_barSets.count() <= 0) {
314 331 return 0;
315 332 }
316 333 qreal min = INT_MAX;
317 334
318 335 for (int i = 0; i < m_barSets.count(); i++) {
319 336 int categoryCount = m_barSets.at(i)->count();
320 337 for (int j = 0; j < categoryCount; j++) {
321 338 qreal temp = m_barSets.at(i)->at(j).y();
322 339 if (temp < min)
323 340 min = temp;
324 341 }
325 342 }
326 343 return min;
327 344 }
328 345
329 346 qreal QBarSeriesPrivate::max()
330 347 {
331 348 if (m_barSets.count() <= 0) {
332 349 return 0;
333 350 }
334 351 qreal max = INT_MIN;
335 352
336 353 for (int i = 0; i < m_barSets.count(); i++) {
337 354 int categoryCount = m_barSets.at(i)->count();
338 355 for (int j = 0; j < categoryCount; j++) {
339 356 qreal temp = m_barSets.at(i)->at(j).y();
340 357 if (temp > max)
341 358 max = temp;
342 359 }
343 360 }
344 361
345 362 return max;
346 363 }
347 364
348 365 qreal QBarSeriesPrivate::valueAt(int set, int category)
349 366 {
350 367 if ((set < 0) || (set >= m_barSets.count())) {
351 368 // No set, no value.
352 369 return 0;
353 370 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
354 371 // No category, no value.
355 372 return 0;
356 373 }
357 374
358 375 return m_barSets.at(set)->at(category).y();
359 376 }
360 377
361 378 qreal QBarSeriesPrivate::percentageAt(int set, int category)
362 379 {
363 380 if ((set < 0) || (set >= m_barSets.count())) {
364 381 // No set, no value.
365 382 return 0;
366 383 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
367 384 // No category, no value.
368 385 return 0;
369 386 }
370 387
371 388 qreal value = m_barSets.at(set)->at(category).y();
372 389 qreal sum = categorySum(category);
373 390 if ( qFuzzyIsNull(sum) ) {
374 391 return 0;
375 392 }
376 393
377 394 return value / sum;
378 395 }
379 396
380 397 qreal QBarSeriesPrivate::categorySum(int category)
381 398 {
382 399 qreal sum(0);
383 400 int count = m_barSets.count(); // Count sets
384 401 for (int set = 0; set < count; set++) {
385 402 if (category < m_barSets.at(set)->count())
386 403 sum += m_barSets.at(set)->at(category).y();
387 404 }
388 405 return sum;
389 406 }
390 407
391 408 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
392 409 {
393 410 qreal sum(0);
394 411 int count = m_barSets.count(); // Count sets
395 412 for (int set = 0; set < count; set++) {
396 413 if (category < m_barSets.at(set)->count())
397 414 sum += qAbs(m_barSets.at(set)->at(category).y());
398 415 }
399 416 return sum;
400 417 }
401 418
402 419 qreal QBarSeriesPrivate::maxCategorySum()
403 420 {
404 421 qreal max = INT_MIN;
405 422 int count = categoryCount();
406 423 for (int i = 0; i < count; i++) {
407 424 qreal sum = categorySum(i);
408 425 if (sum > max)
409 426 max = sum;
410 427 }
411 428 return max;
412 429 }
413 430
414 431 void QBarSeriesPrivate::barsetChanged()
415 432 {
416 433 emit updatedBars();
417 434 }
418 435
419 436 void QBarSeriesPrivate::scaleDomain(Domain& domain)
420 437 {
421 438 qreal minX(domain.minX());
422 439 qreal minY(domain.minY());
423 440 qreal maxX(domain.maxX());
424 441 qreal maxY(domain.maxY());
425 442 int tickXCount(domain.tickXCount());
426 443 int tickYCount(domain.tickYCount());
427 444
428 445 qreal x = categoryCount();
429 446 qreal y = max();
430 447 minX = qMin(minX, x) - 0.5;
431 448 minY = qMin(minY, y);
432 449 maxX = qMax(maxX, x) - 0.5;
433 450 maxY = qMax(maxY, y);
434 451 tickXCount = x+1;
435 452
436 453 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
437 454 }
438 455
439 456 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
440 457 {
441 458 Q_Q(QBarSeries);
442 459
443 460 BarChartItem* bar = new BarChartItem(q,presenter);
444 461 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
445 462 presenter->animator()->addAnimation(bar);
446 463 }
447 464 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
448 465 return bar;
449 466
450 467 }
451 468
452 469 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
453 470 {
454 471 Q_Q(QBarSeries);
455 472 QList<LegendMarker*> markers;
456 473 foreach(QBarSet* set, q->barSets()) {
457 474 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
458 475 markers << marker;
459 476 }
460 477
461 478 return markers;
462 479 }
463 480
464 481 bool QBarSeriesPrivate::append(QBarSet *set)
465 482 {
466 483 Q_Q(QBarSeries);
467 484 if ((m_barSets.contains(set)) || (set == 0)) {
468 485 // Fail if set is already in list or set is null.
469 486 return false;
470 487 }
471 488 m_barSets.append(set);
472 489 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
473 490 if (m_dataset) {
474 491 m_dataset->updateSeries(q); // this notifies legend
475 492 }
476 // emit restructuredBars(); // this notifies barchartitem
493 emit restructuredBars(); // this notifies barchartitem
477 494 return true;
478 495 }
479 496
480 497 bool QBarSeriesPrivate::remove(QBarSet *set)
481 498 {
482 499 Q_Q(QBarSeries);
483 500 if (!m_barSets.contains(set)) {
484 501 // Fail if set is not in list
485 502 return false;
486 503 }
487 504 m_barSets.removeOne(set);
488 505 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
489 506 if (m_dataset) {
490 507 m_dataset->updateSeries(q); // this notifies legend
491 508 }
492 // emit restructuredBars(); // this notifies barchartitem
509 emit restructuredBars(); // this notifies barchartitem
493 510 return true;
494 511 }
495 512
496 513 bool QBarSeriesPrivate::append(QList<QBarSet* > sets)
497 514 {
498 515 Q_Q(QBarSeries);
499 516 foreach (QBarSet* set, sets) {
500 517 if ((set == 0) || (m_barSets.contains(set))) {
501 518 // Fail if any of the sets is null or is already appended.
502 519 return false;
503 520 }
504 521 if (sets.count(set) != 1) {
505 522 // Also fail if same set is more than once in given list.
506 523 return false;
507 524 }
508 525 }
509 526
510 527 foreach (QBarSet* set, sets) {
511 528 m_barSets.append(set);
512 529 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
513 530 }
514 531 if (m_dataset) {
515 532 m_dataset->updateSeries(q); // this notifies legend
516 533 }
517 // emit restructuredBars(); // this notifies barchartitem
534 emit restructuredBars(); // this notifies barchartitem
518 535 return true;
519 536 }
520 537
521 538 bool QBarSeriesPrivate::remove(QList<QBarSet* > sets)
522 539 {
523 540 Q_Q(QBarSeries);
524 541 bool setsRemoved = false;
525 542 foreach (QBarSet* set, sets) {
526 543 if (m_barSets.contains(set)) {
527 544 m_barSets.removeOne(set);
528 545 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
529 546 setsRemoved = true;
530 547 }
531 548 }
532 549
533 550 if (setsRemoved) {
534 551 if (m_dataset) {
535 552 m_dataset->updateSeries(q); // this notifies legend
536 553 }
537 // emit restructuredBars(); // this notifies barchartitem
554 emit restructuredBars(); // this notifies barchartitem
538 555 }
539 556 return setsRemoved;
540 557 }
541 558
542 559 #include "moc_qbarseries.cpp"
543 560 #include "moc_qbarseries_p.cpp"
544 561
545 562 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,99 +1,102
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QBARSERIES_P_H
31 31 #define QBARSERIES_P_H
32 32
33 33 #include "qbarseries.h"
34 34 #include "qabstractseries_p.h"
35 35 #include <QStringList>
36 36 #include <QAbstractSeries>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class QBarModelMapper;
41 41
42 42 class QBarSeriesPrivate : public QAbstractSeriesPrivate
43 43 {
44 44 Q_OBJECT
45 45 public:
46 46 QBarSeriesPrivate(QBarSeries *parent);
47 47 // TODO: refactor/remove private category stuff
48 void setCategories(QStringList categories);
49 void insertCategory(int index, const QString category);
50 void removeCategory(int index);
48 51 int categoryCount() const;
49 52 QStringList categories() const;
50 53
51 54 void setBarMargin(qreal margin);
52 55 qreal barMargin() const;
53 56
54 57 void setVisible(bool visible);
55 58 bool isVisible() const;
56 59
57 60 void scaleDomain(Domain& domain);
58 61 Chart* createGraphics(ChartPresenter* presenter);
59 62 QList<LegendMarker*> createLegendMarker(QLegend* legend);
60 63
61 64 bool append(QBarSet *set);
62 65 bool remove(QBarSet *set);
63 66 bool append(QList<QBarSet* > sets);
64 67 bool remove(QList<QBarSet* > sets);
65 68
66 69 QBarSet* barsetAt(int index);
67 70 QString categoryName(int category);
68 71 qreal min();
69 72 qreal max();
70 73 qreal valueAt(int set, int category);
71 74 qreal percentageAt(int set, int category);
72 75 qreal categorySum(int category);
73 76 qreal absoluteCategorySum(int category);
74 77 qreal maxCategorySum();
75 78
76 79 Q_SIGNALS:
77 80 void clicked(QBarSet *barset, int index);
78 81 void updatedBars();
79 // void restructuredBars();
80 // void categoriesUpdated();
82 void restructuredBars();
83 void categoriesUpdated();
81 84 void labelsVisibleChanged(bool visible);
82 85
83 86 private Q_SLOTS:
84 87 void barsetChanged();
85 88
86 89 protected:
87 90 QList<QBarSet *> m_barSets;
88 91 QStringList m_categories;
89 92 qreal m_barMargin;
90 93 bool m_labelsVisible;
91 94 bool m_visible;
92 95
93 96 private:
94 97 Q_DECLARE_PUBLIC(QBarSeries)
95 98 };
96 99
97 100 QTCOMMERCIALCHART_END_NAMESPACE
98 101
99 102 #endif // QBARSERIESPRIVATE_P_H
General Comments 0
You need to be logged in to leave comments. Login now