##// END OF EJS Templates
Clarified box-and-whiskers chart documentation...
Titta Heikkala -
r2812:2c2bde37df65
parent child
Show More
@@ -1,703 +1,709
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <QtCharts/QBoxPlotSeries>
20 20 #include <private/qboxplotseries_p.h>
21 21 #include <QtCharts/QBoxPlotLegendMarker>
22 22 #include <QtCharts/QBarCategoryAxis>
23 23 #include <private/boxplotchartitem_p.h>
24 24 #include <private/chartdataset_p.h>
25 25 #include <private/charttheme_p.h>
26 26 #include <QtCharts/QValueAxis>
27 27 #include <private/charttheme_p.h>
28 28 #include <private/boxplotanimation_p.h>
29 29 #include <private/qchart_p.h>
30 30 #include <QtCharts/QBoxSet>
31 31 #include <private/qboxset_p.h>
32 32
33 33 QT_CHARTS_BEGIN_NAMESPACE
34 34
35 35 /*!
36 36 \class QBoxPlotSeries
37 37 \inmodule Qt Charts
38 38 \brief Series for creating box-and-whiskers chart.
39 39
40 QBoxPlotSeries represents a series of data shown as box-and-whisker bars. The purpose of this class is to act as
41 a container for single box-and-whisker items. Each item is drawn to own slot. If chart includes multiple instances of
42 QBoxPlotSeries then box-and-whiskers items with the same index are drawn to same slot.
40 QBoxPlotSeries represents a series of data shown as box-and-whisker bars. The purpose of this
41 class is to act as a container for single box-and-whisker items. Each item is drawn to own slot.
42 If chart includes multiple instances of QBoxPlotSeries then box-and-whiskers items with the same
43 index are drawn to same slot.
43 44
44 See the \l {Box and Whiskers Example} {box-and-whiskers chart example} to learn how to create a box-and-whiskers chart.
45 \note The slot, each item in QBoxPlotSeries is drawn, represents a category in QBarCategoryAxis.
46 The category labels have to be unique. If same category label is defined for several
47 box-and-whisker items only the first one is drawn.
48
49 See the \l {Box and Whiskers Example} {box-and-whiskers chart example} to learn how to create a
50 box-and-whiskers chart.
45 51 \image examples_boxplotchart.png
46 52
47 \sa QBoxSet
53 \sa QBoxSet, QBarCategoryAxis
48 54 */
49 55 /*!
50 56 \fn QBoxPlotSeries::boxsetsAdded(QList<QBoxSet *> sets)
51 57 \brief Signal is emitted when a new \a sets of box-and-whiskers data is added to the series.
52 58 */
53 59 /*!
54 60 \fn QBoxPlotSeries::boxsetsRemoved(QList<QBoxSet *> sets)
55 61 \brief Signal is emitted when \a sets of box-and-whiskers data is removed from the series.
56 62 */
57 63 /*!
58 64 \fn QBoxPlotSeries::clicked(QBoxSet *boxset)
59 65 \brief Signal is emitted when the user clicks the \a boxset on the chart.
60 66 */
61 67 /*!
62 68 \fn QBoxPlotSeries::pressed(QBoxSet *boxset)
63 69 \brief Signal is emitted when the user presses the \a boxset on the chart.
64 70 */
65 71 /*!
66 72 \fn QBoxPlotSeries::released(QBoxSet *boxset)
67 73 \brief Signal is emitted when the user releases the \a boxset on the chart.
68 74 */
69 75 /*!
70 76 \fn QBoxPlotSeries::doubleClicked(QBoxSet *boxset)
71 77 \brief Signal is emitted when the user doubleclicks the \a boxset on the chart.
72 78 */
73 79 /*!
74 80 \fn QBoxPlotSeries::hovered(bool status, QBoxSet *boxset)
75 81 \brief Signal is emitted when there is change in hover \a status over \a boxset.
76 82 */
77 83 /*!
78 84 \fn QBoxPlotSeries::countChanged()
79 85 \brief Signal is emitted when there is change in count of box-and-whiskers items in the series.
80 86 */
81 87 /*!
82 88 \property QBoxPlotSeries::boxOutlineVisible
83 89 \brief This property configures the visibility of the middle box outline.
84 90 */
85 91 /*!
86 92 \property QBoxPlotSeries::boxWidth
87 93 \brief This property configures the width of the box-and-whiskers item. The value signifies the relative
88 94 width of the box-and-whiskers item inside its own slot. The value can between 0.0 and 1.0. Negative values
89 95 are clamped to 0.0 and values over 1.0 are clamped to 1.0.
90 96 */
91 97 /*!
92 98 \property QBoxPlotSeries::pen
93 99 \brief This property configures the pen of the box-and-whiskers items.
94 100 */
95 101 /*!
96 102 \property QBoxPlotSeries::brush
97 103 \brief This property configures the brush of the box-and-whiskers items.
98 104 */
99 105 /*!
100 106 \property QBoxPlotSeries::count
101 107 \brief The count of sets in series.
102 108 */
103 109
104 110 /*!
105 111 \qmlproperty QString BoxPlotSeries::brushFilename
106 112 The name of the file used as a brush for the series.
107 113 */
108 114
109 115 /*!
110 116 \fn void QBoxPlotSeries::boxOutlineVisibilityChanged()
111 117 Signal is emitted when the middle box outline visibility is changed.
112 118 */
113 119 /*!
114 120 \fn void QBoxPlotSeries::boxWidthChanged()
115 121 Signal is emitted when the width of the box-and-whiskers item is changed.
116 122 */
117 123 /*!
118 124 \fn void QBoxPlotSeries::penChanged()
119 125 This signal is emitted when the pen of the box-and-whiskers has changed.
120 126 \sa brush
121 127 */
122 128 /*!
123 129 \fn void QBoxPlotSeries::brushChanged()
124 130 This signal is emitted when the brush of the box-and-whiskers has changed.
125 131 \sa brush
126 132 */
127 133 /*!
128 134 \fn virtual SeriesType QBoxPlotSeries::type() const
129 135 \brief Returns type of series.
130 136 \sa QAbstractSeries, SeriesType
131 137 */
132 138
133 139 /*!
134 140 Constructs empty QBoxPlotSeries.
135 141 QBoxPlotSeries is QObject which is a child of a \a parent.
136 142 */
137 143 QBoxPlotSeries::QBoxPlotSeries(QObject *parent)
138 144 : QAbstractSeries(*new QBoxPlotSeriesPrivate(this), parent)
139 145 {
140 146 }
141 147
142 148 /*!
143 149 Destructor. Removes series from chart.
144 150 */
145 151 QBoxPlotSeries::~QBoxPlotSeries()
146 152 {
147 153 Q_D(QBoxPlotSeries);
148 154 if (d->m_chart)
149 155 d->m_chart->removeSeries(this);
150 156 }
151 157
152 158 /*!
153 159 Adds a single box and whiskers set to series. Takes ownership of the \a set. If the set is null or is already in series, it won't be appended.
154 160 Returns true, if appending succeeded.
155 161 */
156 162 bool QBoxPlotSeries::append(QBoxSet *set)
157 163 {
158 164 Q_D(QBoxPlotSeries);
159 165
160 166 bool success = d->append(set);
161 167 if (success) {
162 168 QList<QBoxSet *> sets;
163 169 sets.append(set);
164 170 set->setParent(this);
165 171 emit boxsetsAdded(sets);
166 172 emit countChanged();
167 173 }
168 174 return success;
169 175 }
170 176
171 177 /*!
172 178 Removes boxset from the series. Deletes the \a set and returns true if successful.
173 179 */
174 180 bool QBoxPlotSeries::remove(QBoxSet *set)
175 181 {
176 182 Q_D(QBoxPlotSeries);
177 183 bool success = d->remove(set);
178 184 if (success) {
179 185 QList<QBoxSet *> sets;
180 186 sets.append(set);
181 187 set->setParent(0);
182 188 emit boxsetsRemoved(sets);
183 189 emit countChanged();
184 190 delete set;
185 191 set = 0;
186 192 }
187 193 return success;
188 194 }
189 195
190 196 /*!
191 197 Takes a single \a set from the series. Does not delete the boxset object.
192 198
193 199 NOTE: The series remains as the boxset's parent object. You must set the
194 200 parent object to take full ownership.
195 201
196 202 Returns true if take was successful.
197 203 */
198 204 bool QBoxPlotSeries::take(QBoxSet *set)
199 205 {
200 206 Q_D(QBoxPlotSeries);
201 207
202 208 bool success = d->remove(set);
203 209 if (success) {
204 210 QList<QBoxSet *> sets;
205 211 sets.append(set);
206 212 emit boxsetsRemoved(sets);
207 213 emit countChanged();
208 214 }
209 215 return success;
210 216 }
211 217
212 218 /*!
213 219 Adds a list of boxsets to series. Takes ownership of the \a sets.
214 220 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
215 221 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
216 222 and function returns false.
217 223 */
218 224 bool QBoxPlotSeries::append(QList<QBoxSet *> sets)
219 225 {
220 226 Q_D(QBoxPlotSeries);
221 227 bool success = d->append(sets);
222 228 if (success) {
223 229 emit boxsetsAdded(sets);
224 230 emit countChanged();
225 231 }
226 232 return success;
227 233 }
228 234
229 235 /*!
230 236 Insert a box-and-whiskers set to the series at \a index postion. Takes ownership of the \a set. If the set is null or
231 237 is already in series, it won't be appended. Returns true, if inserting succeeded.
232 238
233 239 */
234 240 bool QBoxPlotSeries::insert(int index, QBoxSet *set)
235 241 {
236 242 Q_D(QBoxPlotSeries);
237 243 bool success = d->insert(index, set);
238 244 if (success) {
239 245 QList<QBoxSet *> sets;
240 246 sets.append(set);
241 247 emit boxsetsAdded(sets);
242 248 emit countChanged();
243 249 }
244 250 return success;
245 251 }
246 252
247 253 /*!
248 254 Removes all boxsets from the series. Deletes removed sets.
249 255 */
250 256 void QBoxPlotSeries::clear()
251 257 {
252 258 Q_D(QBoxPlotSeries);
253 259 QList<QBoxSet *> sets = boxSets();
254 260 bool success = d->remove(sets);
255 261 if (success) {
256 262 emit boxsetsRemoved(sets);
257 263 emit countChanged();
258 264 foreach (QBoxSet *set, sets)
259 265 delete set;
260 266 }
261 267 }
262 268
263 269 /*!
264 270 Returns number of sets in series.
265 271 */
266 272 int QBoxPlotSeries::count() const
267 273 {
268 274 Q_D(const QBoxPlotSeries);
269 275 return d->m_boxSets.count();
270 276 }
271 277
272 278 /*!
273 279 Returns a list of sets in series. Keeps ownership of sets.
274 280 */
275 281 QList<QBoxSet *> QBoxPlotSeries::boxSets() const
276 282 {
277 283 Q_D(const QBoxPlotSeries);
278 284 return d->m_boxSets;
279 285 }
280 286
281 287 /*
282 288 Returns QAbstractSeries::SeriesTypeBoxPlot.
283 289 */
284 290 QAbstractSeries::SeriesType QBoxPlotSeries::type() const
285 291 {
286 292 return QAbstractSeries::SeriesTypeBoxPlot;
287 293 }
288 294
289 295 void QBoxPlotSeries::setBoxOutlineVisible(bool visible)
290 296 {
291 297 Q_D(QBoxPlotSeries);
292 298
293 299 if (d->m_boxOutlineVisible != visible) {
294 300 d->m_boxOutlineVisible = visible;
295 301 emit d->updated();
296 302 emit boxOutlineVisibilityChanged();
297 303 }
298 304 }
299 305
300 306 bool QBoxPlotSeries::boxOutlineVisible()
301 307 {
302 308 Q_D(QBoxPlotSeries);
303 309
304 310 return d->m_boxOutlineVisible;
305 311 }
306 312
307 313 void QBoxPlotSeries::setBoxWidth(qreal width)
308 314 {
309 315 Q_D(QBoxPlotSeries);
310 316
311 317 if (width != d->m_boxWidth) {
312 318 if (width < 0.0)
313 319 width = 0.0;
314 320 if (width > 1.0)
315 321 width = 1.0;
316 322 d->m_boxWidth = width;
317 323 emit d->updatedLayout();
318 324 emit boxWidthChanged();
319 325 }
320 326 }
321 327
322 328 qreal QBoxPlotSeries::boxWidth()
323 329 {
324 330 Q_D(QBoxPlotSeries);
325 331
326 332 return d->m_boxWidth;
327 333 }
328 334
329 335 void QBoxPlotSeries::setBrush(const QBrush &brush)
330 336 {
331 337 Q_D(QBoxPlotSeries);
332 338
333 339 if (d->m_brush != brush) {
334 340 d->m_brush = brush;
335 341 emit d->updated();
336 342 emit brushChanged();
337 343 }
338 344 }
339 345
340 346 QBrush QBoxPlotSeries::brush() const
341 347 {
342 348 Q_D(const QBoxPlotSeries);
343 349
344 350 return d->m_brush;
345 351 }
346 352
347 353 void QBoxPlotSeries::setPen(const QPen &pen)
348 354 {
349 355 Q_D(QBoxPlotSeries);
350 356
351 357 if (d->m_pen != pen) {
352 358 d->m_pen = pen;
353 359 emit d->updated();
354 360 emit penChanged();
355 361 }
356 362 }
357 363
358 364 QPen QBoxPlotSeries::pen() const
359 365 {
360 366 Q_D(const QBoxPlotSeries);
361 367
362 368 return d->m_pen;
363 369 }
364 370
365 371 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
366 372
367 373 QBoxPlotSeriesPrivate::QBoxPlotSeriesPrivate(QBoxPlotSeries *q)
368 374 : QAbstractSeriesPrivate(q),
369 375 m_pen(QChartPrivate::defaultPen()),
370 376 m_brush(QChartPrivate::defaultBrush()),
371 377 m_boxOutlineVisible(true),
372 378 m_boxWidth(0.5)
373 379 {
374 380 }
375 381
376 382 QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()
377 383 {
378 384 disconnect(this, 0, 0, 0);
379 385 }
380 386
381 387 void QBoxPlotSeriesPrivate::initializeDomain()
382 388 {
383 389 qreal minX(domain()->minX());
384 390 qreal minY(domain()->minY());
385 391 qreal maxX(domain()->maxX());
386 392 qreal maxY(domain()->maxY());
387 393
388 394 qreal x = m_boxSets.count();
389 395 minX = qMin(minX, qreal(-0.5));
390 396 minY = qMin(minY, min());
391 397 maxX = qMax(maxX, x - qreal(0.5));
392 398 maxY = qMax(maxY, max());
393 399
394 400 domain()->setRange(minX, maxX, minY, maxY);
395 401 }
396 402
397 403 void QBoxPlotSeriesPrivate::initializeAxes()
398 404 {
399 405 foreach (QAbstractAxis* axis, m_axes) {
400 406 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
401 407 if (axis->orientation() == Qt::Horizontal)
402 408 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
403 409 }
404 410 }
405 411 }
406 412
407 413 QAbstractAxis::AxisType QBoxPlotSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
408 414 {
409 415 if (orientation == Qt::Horizontal)
410 416 return QAbstractAxis::AxisTypeBarCategory;
411 417
412 418 return QAbstractAxis::AxisTypeValue;
413 419 }
414 420
415 421 QAbstractAxis* QBoxPlotSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
416 422 {
417 423 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
418 424 return new QBarCategoryAxis;
419 425 else
420 426 return new QValueAxis;
421 427 }
422 428
423 429 void QBoxPlotSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
424 430 {
425 431 QStringList categories;
426 432 if (axis->categories().isEmpty()) {
427 433 for (int i(1); i < m_boxSets.count() + 1; i++) {
428 434 QBoxSet *set = m_boxSets.at(i - 1);
429 435 if (set->label().isEmpty())
430 436 categories << presenter()->numberToString(i);
431 437 else
432 438 categories << set->label();
433 439 }
434 440 axis->append(categories);
435 441 }
436 442 }
437 443
438 444 void QBoxPlotSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
439 445 {
440 446 Q_Q(QBoxPlotSeries);
441 447
442 448 BoxPlotChartItem *boxPlot = new BoxPlotChartItem(q, parent);
443 449 m_item.reset(boxPlot);
444 450 QAbstractSeriesPrivate::initializeGraphics(parent);
445 451
446 452 if (m_chart) {
447 453 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesChange(QAbstractSeries*)) );
448 454 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SLOT(handleSeriesRemove(QAbstractSeries*)) );
449 455
450 456 QList<QAbstractSeries *> serieses = m_chart->series();
451 457
452 458 // Tries to find this series from the Chart's list of series and deduce the index
453 459 int index = 0;
454 460 foreach (QAbstractSeries *s, serieses) {
455 461 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
456 462 if (q == static_cast<QBoxPlotSeries *>(s)) {
457 463 boxPlot->m_seriesIndex = index;
458 464 m_index = index;
459 465 }
460 466 index++;
461 467 }
462 468 }
463 469 boxPlot->m_seriesCount = index;
464 470 }
465 471
466 472 // Make BoxPlotChartItem to instantiate box & whisker items
467 473 boxPlot->handleDataStructureChanged();
468 474 }
469 475
470 476 void QBoxPlotSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
471 477 {
472 478 Q_Q(QBoxPlotSeries);
473 479
474 480 const QList<QGradient> gradients = theme->seriesGradients();
475 481
476 482 if (forced || QChartPrivate::defaultBrush() == m_brush) {
477 483 QColor brushColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.5);
478 484 q->setBrush(brushColor);
479 485 }
480 486
481 487 if (forced || QChartPrivate::defaultPen() == m_pen) {
482 488 QPen pen = theme->outlinePen();
483 489 pen.setCosmetic(true);
484 490 q->setPen(pen);
485 491 }
486 492 }
487 493
488 494 void QBoxPlotSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
489 495 QEasingCurve &curve)
490 496 {
491 497 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
492 498 Q_ASSERT(item);
493 499 if (item->animation())
494 500 item->animation()->stopAndDestroyLater();
495 501
496 502 if (options.testFlag(QChart::SeriesAnimations))
497 503 m_animation = new BoxPlotAnimation(item, duration, curve);
498 504 else
499 505 m_animation = 0;
500 506 item->setAnimation(m_animation);
501 507
502 508 QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
503 509
504 510 // Make BoxPlotChartItem to instantiate box & whisker items
505 511 item->handleDataStructureChanged();
506 512 }
507 513
508 514 QList<QLegendMarker*> QBoxPlotSeriesPrivate::createLegendMarkers(QLegend *legend)
509 515 {
510 516 Q_Q(QBoxPlotSeries);
511 517 QList<QLegendMarker *> list;
512 518 return list << new QBoxPlotLegendMarker(q, legend);
513 519 }
514 520
515 521 void QBoxPlotSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
516 522 {
517 523 Q_Q(QBoxPlotSeries);
518 524
519 525 QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
520 526
521 527 if (q == removedSeries && m_animation) {
522 528 m_animation->stopAll();
523 529 QObject::disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
524 530 }
525 531
526 532 // Test if series removed is me, then don't do anything
527 533 if (q != removedSeries) {
528 534 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
529 535 if (item) {
530 536 item->m_seriesCount = item->m_seriesCount - 1;
531 537 if (removedSeries->d_func()->m_index < m_index) {
532 538 m_index--;
533 539 item->m_seriesIndex = m_index;
534 540 }
535 541
536 542 item->handleDataStructureChanged();
537 543 }
538 544 }
539 545 }
540 546
541 547 void QBoxPlotSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
542 548 {
543 549 Q_UNUSED(series);
544 550
545 551 Q_Q(QBoxPlotSeries);
546 552
547 553 BoxPlotChartItem *boxPlot = static_cast<BoxPlotChartItem *>(m_item.data());
548 554
549 555 if (m_chart) {
550 556 QList<QAbstractSeries *> serieses = m_chart->series();
551 557
552 558 // Tries to find this series from the Chart's list of series and deduce the index
553 559 int index = 0;
554 560 foreach (QAbstractSeries *s, serieses) {
555 561 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
556 562 if (q == static_cast<QBoxPlotSeries *>(s)) {
557 563 boxPlot->m_seriesIndex = index;
558 564 m_index = index;
559 565 }
560 566 index++;
561 567 }
562 568 }
563 569 boxPlot->m_seriesCount = index;
564 570 }
565 571
566 572 boxPlot->handleDataStructureChanged();
567 573 }
568 574
569 575 bool QBoxPlotSeriesPrivate::append(QBoxSet *set)
570 576 {
571 577 if (m_boxSets.contains(set) || (set == 0) || set->d_ptr->m_series)
572 578 return false; // Fail if set is already in list or set is null.
573 579
574 580 m_boxSets.append(set);
575 581 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
576 582 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
577 583 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
578 584 set->d_ptr->m_series = this;
579 585
580 586 emit restructuredBoxes(); // this notifies boxplotchartitem
581 587 return true;
582 588 }
583 589
584 590 bool QBoxPlotSeriesPrivate::remove(QBoxSet *set)
585 591 {
586 592 if (!m_boxSets.contains(set))
587 593 return false; // Fail if set is not in list
588 594
589 595 set->d_ptr->m_series = 0;
590 596 m_boxSets.removeOne(set);
591 597 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
592 598 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
593 599 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
594 600
595 601 emit restructuredBoxes(); // this notifies boxplotchartitem
596 602 return true;
597 603 }
598 604
599 605 bool QBoxPlotSeriesPrivate::append(QList<QBoxSet *> sets)
600 606 {
601 607 foreach (QBoxSet *set, sets) {
602 608 if ((set == 0) || m_boxSets.contains(set) || set->d_ptr->m_series)
603 609 return false; // Fail if any of the sets is null or is already appended.
604 610 if (sets.count(set) != 1)
605 611 return false; // Also fail if same set is more than once in given list.
606 612 }
607 613
608 614 foreach (QBoxSet *set, sets) {
609 615 m_boxSets.append(set);
610 616 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
611 617 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
612 618 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
613 619 set->d_ptr->m_series = this;
614 620 }
615 621
616 622 emit restructuredBoxes(); // this notifies boxplotchartitem
617 623 return true;
618 624 }
619 625
620 626 bool QBoxPlotSeriesPrivate::remove(QList<QBoxSet *> sets)
621 627 {
622 628 if (sets.count() == 0)
623 629 return false;
624 630
625 631 foreach (QBoxSet *set, sets) {
626 632 if ((set == 0) || (!m_boxSets.contains(set)))
627 633 return false; // Fail if any of the sets is null or is not in series
628 634 if (sets.count(set) != 1)
629 635 return false; // Also fail if same set is more than once in given list.
630 636 }
631 637
632 638 foreach (QBoxSet *set, sets) {
633 639 set->d_ptr->m_series = 0;
634 640 m_boxSets.removeOne(set);
635 641 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
636 642 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
637 643 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
638 644 }
639 645
640 646 emit restructuredBoxes(); // this notifies boxplotchartitem
641 647
642 648 return true;
643 649 }
644 650
645 651 bool QBoxPlotSeriesPrivate::insert(int index, QBoxSet *set)
646 652 {
647 653 if ((m_boxSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
648 654 return false; // Fail if set is already in list or set is null.
649 655
650 656 m_boxSets.insert(index, set);
651 657 set->d_ptr->m_series = this;
652 658 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
653 659 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
654 660 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
655 661
656 662 emit restructuredBoxes(); // this notifies boxplotchartitem
657 663 return true;
658 664 }
659 665
660 666 QBoxSet *QBoxPlotSeriesPrivate::boxSetAt(int index)
661 667 {
662 668 return m_boxSets.at(index);
663 669 }
664 670
665 671 qreal QBoxPlotSeriesPrivate::min()
666 672 {
667 673 if (m_boxSets.count() <= 0)
668 674 return 0;
669 675
670 676 qreal min = m_boxSets.at(0)->at(0);
671 677
672 678 foreach (QBoxSet *set, m_boxSets) {
673 679 for (int i = 0; i < 5; i++) {
674 680 if (set->at(i) < min)
675 681 min = set->at(i);
676 682 }
677 683 }
678 684
679 685 return min;
680 686 }
681 687
682 688 qreal QBoxPlotSeriesPrivate::max()
683 689 {
684 690 if (m_boxSets.count() <= 0)
685 691 return 0;
686 692
687 693 qreal max = m_boxSets.at(0)->at(0);
688 694
689 695 foreach (QBoxSet *set, m_boxSets) {
690 696 for (int i = 0; i < 5; i++) {
691 697 if (set->at(i) > max)
692 698 max = set->at(i);
693 699 }
694 700 }
695 701
696 702 return max;
697 703 }
698 704
699 705 #include "moc_qboxplotseries.cpp"
700 706 #include "moc_qboxplotseries_p.cpp"
701 707
702 708 QT_CHARTS_END_NAMESPACE
703 709
@@ -1,349 +1,349
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <QtCharts/QBoxSet>
20 20 #include <private/qboxset_p.h>
21 21 #include <private/charthelpers_p.h>
22 22
23 23 QT_CHARTS_BEGIN_NAMESPACE
24 24
25 25 /*!
26 26 \class QBoxSet
27 27 \inmodule Qt Charts
28 28 \brief Building block for box-and-whiskers chart.
29 29
30 30 QBoxSet represents one box-and-whiskers item. It takes five values to create a graphical representation
31 31 of range and three medians. There are two ways to give the values. The first one is with constructor
32 32 or stream operator (<<). The values have to be given in the following order: lower extreme,
33 33 lower quartile, median, upper quartile and upper extreme. The Second method is to create an empty QBoxSet instance and
34 34 give the values using setValue method.
35 35
36 36 \sa QBoxPlotSeries
37 37 */
38 38 /*!
39 39 \enum QBoxSet::ValuePositions
40 40
41 41 \value LowerExtreme
42 42 \value LowerQuartile
43 43 \value Median
44 44 \value UpperQuartile
45 45 \value UpperExtreme
46 46 */
47 47 /*!
48 48 \property QBoxSet::pen
49 49 \brief Defines the pen used by the box-and-whiskers set.
50 50 */
51 51 /*!
52 52 \property QBoxSet::brush
53 53 \brief Defines the brush used by the box-and-whiskers set.
54 54 */
55 55
56 56 /*!
57 57 \qmlproperty QString BoxSet::brushFilename
58 58 The name of the file used as a brush for the box-and-whiskers set.
59 59 */
60 60
61 61 /*!
62 62 \fn void QBoxSet::clicked()
63 63 The signal is emitted if the user clicks with a mouse on top of box-and-whisker item.
64 64 */
65 65
66 66 /*!
67 67 \fn void QBoxSet::pressed()
68 68 The signal is emitted if the user presses with a mouse on top of box-and-whisker item.
69 69 */
70 70
71 71 /*!
72 72 \fn void QBoxSet::released()
73 73 The signal is emitted if the user releases with a mouse on top of box-and-whisker item.
74 74 */
75 75
76 76 /*!
77 77 \fn void QBoxSet::doubleClicked()
78 78 The signal is emitted if the user doubleclicks with a mouse on top of box-and-whisker item.
79 79 */
80 80
81 81 /*!
82 82 \fn void QBoxSet::hovered(bool status)
83 83
84 84 The signal is emitted if mouse is hovered on top of box-and-whisker item.
85 85 Parameter \a status is true, if mouse entered on top of item, false if mouse left from top of item.
86 86 */
87 87 /*!
88 88 \fn void QBoxSet::penChanged()
89 89 This signal is emitted when the pen of the box-and-whisker item has changed.
90 90 \sa pen
91 91 */
92 92 /*!
93 93 \fn void QBoxSet::brushChanged()
94 94 This signal is emitted when the brush of the box-and-whisker item has changed.
95 95 \sa brush
96 96 */
97 97 /*!
98 98 \fn void QBoxSet::valuesChanged()
99 99 This signal is emitted when multiple values have been changed on the box-and-whisker item.
100 100 \sa append()
101 101 */
102 102 /*!
103 103 \fn void QBoxSet::valueChanged(int index)
104 104 This signal is emitted values the value in the box-and-whisker item has been modified.
105 105 Parameter \a index indicates the position of the modified value.
106 106 \sa at()
107 107 */
108 108 /*!
109 109 \fn void QBoxSet::cleared()
110 110 This signal is emitted when all the values on the set are cleared to 0.
111 111 */
112 112
113 113 /*!
114 114 Constructs QBoxSet with optional \a label and parent of \a parent
115 115 */
116 116 QBoxSet::QBoxSet(const QString label, QObject *parent)
117 117 : QObject(parent),
118 118 d_ptr(new QBoxSetPrivate(label, this))
119 119 {
120 120 }
121 121
122 122 /*!
123 123 Constructs QBoxSet with given ordered values. \a le for lower extreme, \a lq for lower quartile, \a m for median,
124 124 \a uq for upper quartile and \a ue for upper quartile. \a label and \a parent are optional.
125 125 */
126 126 QBoxSet::QBoxSet(const qreal le, const qreal lq, const qreal m, const qreal uq, const qreal ue, const QString label, QObject *parent)
127 127 : QObject(parent),
128 128 d_ptr(new QBoxSetPrivate(label, this))
129 129 {
130 130 d_ptr->append(le);
131 131 d_ptr->append(lq);
132 132 d_ptr->append(m);
133 133 d_ptr->append(uq);
134 134 d_ptr->append(ue);
135 135 }
136 136
137 137 /*!
138 138 Destroys the boxset
139 139 */
140 140 QBoxSet::~QBoxSet()
141 141 {
142 142 }
143 143
144 144 /*!
145 145 Appends new value \a value to the end of set.
146 146 */
147 147 void QBoxSet::append(const qreal value)
148 148 {
149 149 if (d_ptr->append(value))
150 150 emit valueChanged(d_ptr->m_appendCount - 1);
151 151 }
152 152
153 153 /*!
154 154 Appends a list of reals to set. Works like append with single real value. The \a values in list
155 155 are appended to end of boxset.
156 156 \sa append()
157 157 */
158 158 void QBoxSet::append(const QList<qreal> &values)
159 159 {
160 160 if (d_ptr->append(values))
161 161 emit valuesChanged();
162 162 }
163 163
164 164 /*!
165 Sets new \a label for set.
165 Sets new \a label for the category of the set.
166 166 */
167 167 void QBoxSet::setLabel(const QString label)
168 168 {
169 169 d_ptr->m_label = label;
170 170 }
171 171
172 172 /*!
173 Returns label of the set.
173 Returns the label of the the category of the set.
174 174 */
175 175 QString QBoxSet::label() const
176 176 {
177 177 return d_ptr->m_label;
178 178 }
179 179
180 180 /*!
181 181 Convenience operator. Same as append, with real \a value.
182 182 \sa append()
183 183 */
184 184 QBoxSet &QBoxSet::operator << (const qreal &value)
185 185 {
186 186 append(value);
187 187 return *this;
188 188 }
189 189
190 190 /*!
191 191 Sets a new \a value on the \a index position. For \a index ValuePositions can be used.
192 192 */
193 193 void QBoxSet::setValue(const int index, const qreal value)
194 194 {
195 195 d_ptr->setValue(index, value);
196 196 emit valueChanged(index);
197 197 }
198 198
199 199 /*!
200 200 Sets all values on the set to 0.
201 201 */
202 202 void QBoxSet::clear()
203 203 {
204 204 d_ptr->clear();
205 205 emit cleared();
206 206 }
207 207
208 208 /*!
209 209 Returns value of set indexed by \a index. For \a index ValuePositions can be used.
210 210 If the index is out of bounds 0.0 is returned.
211 211 */
212 212 qreal QBoxSet::at(const int index) const
213 213 {
214 214 if (index < 0 || index >= 5)
215 215 return 0;
216 216 return d_ptr->m_values[index];
217 217 }
218 218
219 219 /*!
220 220 Returns value of set indexed by \a index. For \a index ValuePositions can be used.
221 221 If the index is out of bounds 0.0 is returned.
222 222 */
223 223 qreal QBoxSet::operator [](const int index) const
224 224 {
225 225 return at(index);
226 226 }
227 227
228 228 /*!
229 229 Returns count of values appended to the set.
230 230 */
231 231 int QBoxSet::count() const
232 232 {
233 233 return d_ptr->m_appendCount;
234 234 }
235 235
236 236 /*!
237 237 Sets pen for set. Boxes of this set are drawn using \a pen
238 238 */
239 239 void QBoxSet::setPen(const QPen &pen)
240 240 {
241 241 if (d_ptr->m_pen != pen) {
242 242 d_ptr->m_pen = pen;
243 243 emit d_ptr->updatedBox();
244 244 emit penChanged();
245 245 }
246 246 }
247 247
248 248 /*!
249 249 Returns pen of the set.
250 250 */
251 251 QPen QBoxSet::pen() const
252 252 {
253 253 return d_ptr->m_pen;
254 254 }
255 255
256 256 /*!
257 257 Sets brush for the set. Boxes of this set are drawn using \a brush
258 258 */
259 259 void QBoxSet::setBrush(const QBrush &brush)
260 260 {
261 261 if (d_ptr->m_brush != brush) {
262 262 d_ptr->m_brush = brush;
263 263 emit d_ptr->updatedBox();
264 264 emit brushChanged();
265 265 }
266 266 }
267 267
268 268 /*!
269 269 Returns brush of the set.
270 270 */
271 271 QBrush QBoxSet::brush() const
272 272 {
273 273 return d_ptr->m_brush;
274 274 }
275 275
276 276 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
277 277
278 278 QBoxSetPrivate::QBoxSetPrivate(const QString label, QBoxSet *parent) : QObject(parent),
279 279 q_ptr(parent),
280 280 m_label(label),
281 281 m_valuesCount(5),
282 282 m_appendCount(0),
283 283 m_pen(QPen(Qt::NoPen)),
284 284 m_brush(QBrush(Qt::NoBrush)),
285 285 m_series(0)
286 286 {
287 287 m_values = new qreal[m_valuesCount];
288 288 }
289 289
290 290 QBoxSetPrivate::~QBoxSetPrivate()
291 291 {
292 292 delete[] m_values;
293 293 }
294 294
295 295 bool QBoxSetPrivate::append(qreal value)
296 296 {
297 297 if (isValidValue(value) && m_appendCount < m_valuesCount) {
298 298 m_values[m_appendCount++] = value;
299 299 emit restructuredBox();
300 300
301 301 return true;
302 302 }
303 303 return false;
304 304 }
305 305
306 306 bool QBoxSetPrivate::append(QList<qreal> values)
307 307 {
308 308 bool success = false;
309 309
310 310 for (int i = 0; i < values.count(); i++) {
311 311 if (isValidValue(values.at(i)) && m_appendCount < m_valuesCount) {
312 312 success = true;
313 313 m_values[m_appendCount++] = values.at(i);
314 314 }
315 315 }
316 316
317 317 if (success)
318 318 emit restructuredBox();
319 319
320 320 return success;
321 321 }
322 322
323 323 void QBoxSetPrivate::clear()
324 324 {
325 325 m_appendCount = 0;
326 326 for (int i = 0; i < m_valuesCount; i++)
327 327 m_values[i] = 0.0;
328 328 emit restructuredBox();
329 329 }
330 330
331 331 void QBoxSetPrivate::setValue(const int index, const qreal value)
332 332 {
333 333 if (index < m_valuesCount) {
334 334 m_values[index] = value;
335 335 emit updatedLayout();
336 336 }
337 337 }
338 338
339 339 qreal QBoxSetPrivate::value(const int index)
340 340 {
341 341 if (index < 0 || index >= m_valuesCount)
342 342 return 0;
343 343 return m_values[index];
344 344 }
345 345
346 346 #include "moc_qboxset.cpp"
347 347 #include "moc_qboxset_p.cpp"
348 348
349 349 QT_CHARTS_END_NAMESPACE
@@ -1,459 +1,465
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include "declarativebarseries.h"
20 20 #include "declarativeboxplotseries.h"
21 21 #include <QtCharts/QBoxSet>
22 22 #include <QtCharts/QVBoxPlotModelMapper>
23 23
24 24 QT_CHARTS_BEGIN_NAMESPACE
25 25
26 26 /*!
27 27 \qmltype BoxSet
28 28 \instantiates QBoxSet
29 29 \inqmlmodule QtCharts
30 30
31 31 \brief Building block for box-and-whiskers chart.
32 32
33 33 BoxSet represents one box-and-whiskers item. It takes five values to create a graphical
34 34 representation of range and three medians. There are two ways to give the values. The first one
35 35 is with constructor or with append method. In these the values have to be given in the following
36 36 order: lower extreme, lower quartile, median, upper quartile and upper extreme. The second
37 37 method is to create an empty QBoxSet instance and give the values using value specific methods.
38 38 \sa BoxPlotSeries
39 39 */
40 40 /*!
41 41 \qmlproperty string BoxSet::values
42 42 The values on the box-and-whiskers set.
43 43 */
44 44 /*!
45 45 \qmlproperty string BoxSet::label
46 Defines the label of the box-and-whiskers set.
46 Defines the label of the category of the box-and-whiskers set.
47 47 */
48 48 /*!
49 49 \qmlproperty int BoxSet::count
50 50 The count of values on the box-and-whiskers set
51 51 */
52 52 /*!
53 53 \qmlmethod void BoxSet::at(int index)
54 54 Returns the value at \a index position.
55 55 */
56 56 /*!
57 57 \qmlmethod void BoxSet::append(qreal value)
58 58 Appends new value \a value to the end of set.
59 59 */
60 60 /*!
61 61 \qmlmethod void BoxSet::clear()
62 62 Sets all values on the set to 0.
63 63 */
64 64 /*!
65 65 \qmlmethod void BoxSet::setValue(int index, qreal value)
66 66 Sets a new \a value on the \a index position.
67 67 */
68 68 /*!
69 69 \qmlsignal BoxSet::onClicked()
70 70 This signal is emitted when the user clicks with a mouse on top of box-and-whiskers item.
71 71 */
72 72 /*!
73 73 \qmlsignal BoxSet::onPressed()
74 74 This signal is emitted when the user presses with a mouse on top of box-and-whiskers item.
75 75 */
76 76 /*!
77 77 \qmlsignal BoxSet::onReleased()
78 78 This signal is emitted when the user releases with a mouse on top of box-and-whiskers item.
79 79 */
80 80 /*!
81 81 \qmlsignal BoxSet::onDoubleClicked()
82 82 This signal is emitted when the user doubleclicks with a mouse on top of box-and-whiskers item.
83 83 */
84 84 /*!
85 85 \qmlsignal BoxSet::onHovered(bool status)
86 86 The signal is emitted if mouse is hovered on top of box-and-whiskers item.
87 87 Parameter \a status is true, if mouse entered on top of the item, and false if mouse left from top of the item.
88 88 */
89 89 /*!
90 90 \qmlsignal BoxSet::onPenChanged()
91 91 This signal is emitted when the pen of the box-and-whiskers item has changed.
92 92 */
93 93 /*!
94 94 \qmlsignal BoxSet::onBrushChanged()
95 95 This signal is emitted when the brush of the box-and-whiskers item has changed.
96 96 */
97 97 /*!
98 98 \qmlsignal BoxSet::onChangedValues()
99 99 This signal is emitted when multiple values have been changed on the box-and-whiskers item.
100 100 */
101 101 /*!
102 102 \qmlsignal BoxSet::onChangedValue(int index)
103 103 This signal is emitted values the value in the box-and-whiskers item has been modified.
104 104 Parameter \a index indicates the position of the modified value.
105 105 */
106 106 /*!
107 107 \qmlsignal BoxSet::onCleared()
108 108 This signal is emitted when all the values on the set are cleared to 0.
109 109 */
110 110
111 111 /*!
112 112 \qmltype BoxPlotSeries
113 113 \instantiates QBoxPlotSeries
114 114 \inqmlmodule QtCharts
115 115
116 116 \inherits AbstractSeries
117 117
118 118 \brief Series for creating box-and-whiskers chart.
119 119
120 120 BoxPlotSeries represents a series of data shown as box-and-whiskers bars. The purpose of this
121 121 class is to act as a container for single box-and-whiskers items. Each item is drawn to own
122 122 slot. If chart includes multiple instances of BoxPlotSeries then box-and-whiskers items with the
123 123 same index are drawn to same slot.
124 124
125 \note The slot, each item in BoxPlotSeries is drawn, represents a category in BarCategoryAxis.
126 The category labels have to be unique. If same category label is defined for several
127 box-and-whisker items only the first one is drawn.
128
125 129 The following QML shows how to create a simple box-and-whiskers chart:
126 130 \code
127 131 import QtQuick 2.0
128 132 import QtCharts 2.0
129 133
130 134 ChartView {
131 135 title: "Box Plot series"
132 136 width: 400
133 137 height: 300
134 138 theme: ChartView.ChartThemeBrownSand
135 139 legend.alignment: Qt.AlignBottom
136 140
137 141 BoxPlotSeries {
138 142 id: plotSeries
139 143 name: "Income"
140 144 BoxSet { label: "Jan"; values: [3, 4, 5.1, 6.2, 8.5] }
141 145 BoxSet { label: "Feb"; values: [5, 6, 7.5, 8.6, 11.8] }
142 146 BoxSet { label: "Mar"; values: [3.2, 5, 5.7, 8, 9.2] }
143 147 BoxSet { label: "Apr"; values: [3.8, 5, 6.4, 7, 8] }
144 148 BoxSet { label: "May"; values: [4, 5, 5.2, 6, 7] }
145 149 }
146 150 }
147 151 \endcode
148 152
149 153 \beginfloatleft
150 154 \image examples_qmlboxplot.png
151 155 \endfloat
152 156 \clearfloat
157
158 \sa BoxSet, BarCategoryAxis
153 159 */
154 160
155 161 /*!
156 162 \qmlmethod BoxPlotSeries::append(string label, VariantList values)
157 163 Appends a new box-and-whiskers set with \a label and \a values to the series.
158 164 */
159 165 /*!
160 166 \qmlmethod BoxPlotSeries::append(BoxSet box)
161 167 Appends the \a box to the series.
162 168 */
163 169 /*!
164 170 \qmlmethod BoxPlotSeries::insert(int index, string label, VariantList values)
165 171 Inserts a new box-and-whiskers set with \a label and \a values at the \a index position.
166 172 */
167 173 /*!
168 174 \qmlmethod BoxPlotSeries::remove(QBoxSet boxset)
169 175 Removes the \a boxset from the series.
170 176 */
171 177 /*!
172 178 \qmlmethod BoxPlotSeries::clear()
173 179 Removes all boxsets from the series. Deletes removed sets.
174 180 */
175 181 /*!
176 182 \qmlsignal BoxPlotSeries::onClicked(BoxSet boxset);
177 183 Signal is emitted when the user clicks the \a boxset on the chart.
178 184 */
179 185 /*!
180 186 \qmlsignal BoxPlotSeries::onHovered(bool status, BoxSet boxset);
181 187 Signal is emitted when there is change in hover \a status over \a boxset.
182 188 */
183 189 /*!
184 190 \qmlsignal BoxPlotSeries::onPressed(BoxSet boxset)
185 191 This signal is emitted when the user presses the \a boxset on the chart.
186 192 */
187 193 /*!
188 194 \qmlsignal BoxPlotSeries::onReleased(BoxSet boxset)
189 195 This signal is emitted when the user releases the \a boxset on the chart.
190 196 */
191 197 /*!
192 198 \qmlsignal BoxPlotSeries::onDoubleClicked(BoxSet boxset)
193 199 This signal is emitted when the user doubleclicks the \a boxset on the chart.
194 200 */
195 201 /*!
196 202 \qmlsignal BoxPlotSeries::onCountChanged();
197 203 Signal is emitted when there is change in count of box-and-whiskers items in the series.
198 204 */
199 205 /*!
200 206 \qmlsignal BoxPlotSeries::onBoxsetsAdded()
201 207 Signal is emitted when new box-and-whiskers sets are added to the series.
202 208 */
203 209 /*!
204 210 \qmlsignal BoxPlotSeries::onBoxsetsRemoved()
205 211 Signal is emitted when new box-and-whiskers sets are removed from the series.
206 212 */
207 213 /*!
208 214 \qmlproperty AbstractAxis BoxPlotSeries::axisX
209 215 The x axis used for the series. If you leave both axisX and axisXTop undefined, a BarCategoriesAxis is created for
210 216 the series.
211 217 \sa axisXTop
212 218 */
213 219 /*!
214 220 \qmlproperty AbstractAxis BoxPlotSeries::axisY
215 221 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
216 222 the series.
217 223 \sa axisYRight
218 224 */
219 225 /*!
220 226 \qmlproperty AbstractAxis BoxPlotSeries::axisXTop
221 227 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
222 228 axisXTop, but not both.
223 229 \sa axisX
224 230 */
225 231 /*!
226 232 \qmlproperty AbstractAxis BoxPlotSeries::axisYRight
227 233 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
228 234 or axisYRight, but not both.
229 235 \sa axisY
230 236 */
231 237 /*!
232 238 \qmlproperty bool BoxPlotSeries::boxOutlineVisible
233 239 This property configures the visibility of the middle box outline.
234 240 */
235 241 /*!
236 242 \qmlproperty qreal BoxPlotSeries::boxWidth
237 243 This property configures the width of the box-and-whiskers item. The value signifies the relative
238 244 width of the box-and-whiskers item inside its own slot. The value can between 0.0 and 1.0. Negative values
239 245 are clamped to 0.0 and values over 1.0 are clamped to 1.0.
240 246 */
241 247 /*!
242 248 \qmlproperty Pen BoxPlotSeries::pen
243 249 This property configures the pen of the box-and-whiskers items.
244 250 */
245 251 /*!
246 252 \qmlproperty Brush BoxPlotSeries::brush
247 253 This property configures the brush of the box-and-whiskers items.
248 254 */
249 255 /*!
250 256 \qmlproperty int BoxPlotSeries::count
251 257 The count of sets in series.
252 258 */
253 259 /*!
254 260 \qmlsignal BoxPlotSeries::onBoxOutlineVisibilityChanged()
255 261 Signal is emitted when the middle box outline visibility is changed.
256 262 */
257 263 /*!
258 264 \qmlsignal BoxPlotSeries::onBoxWidthChanged()
259 265 Signal is emitted when the width of the box-and-whiskers item is changed.
260 266 */
261 267 /*!
262 268 \qmlsignal BoxPlotSeries::onPenChanged()
263 269 Signal is emitted when the pen for box-and-whiskers items has changed.
264 270 */
265 271 /*!
266 272 \qmlsignal BoxPlotSeries::onBrushChanged()
267 273 Signal is emitted when the brush for box-and-whiskers items has changed.
268 274 */
269 275 /*!
270 276 \qmlsignal BoxPlotSeries::onAxisXChanged(AbstractAxis axis)
271 277 Signal is emitted when there is change in X axis.
272 278 */
273 279 /*!
274 280 \qmlsignal BoxPlotSeries::onAxisYChanged(AbstractAxis axis)
275 281 Signal is emitted when there is change in Y axis.
276 282 */
277 283 /*!
278 284 \qmlsignal BoxPlotSeries::onAxisXTopChanged(AbstractAxis axis)
279 285 Signal is emitted when there is change in top X axis.
280 286 */
281 287 /*!
282 288 \qmlsignal BoxPlotSeries::onAxisYRightChanged(AbstractAxis axis)
283 289 Signal is emitted when there is change in Y right axis.
284 290 */
285 291
286 292
287 293 DeclarativeBoxSet::DeclarativeBoxSet(const QString label, QObject *parent)
288 294 : QBoxSet(label, parent)
289 295 {
290 296 connect(this, SIGNAL(valuesChanged()), this, SIGNAL(changedValues()));
291 297 connect(this, SIGNAL(valueChanged(int)), this, SIGNAL(changedValue(int)));
292 298 connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged()));
293 299 }
294 300
295 301 QVariantList DeclarativeBoxSet::values()
296 302 {
297 303 QVariantList values;
298 304 for (int i(0); i < 5; i++)
299 305 values.append(QVariant(QBoxSet::at(i)));
300 306 return values;
301 307 }
302 308
303 309 void DeclarativeBoxSet::setValues(QVariantList values)
304 310 {
305 311 for (int i(0); i < values.count(); i++) {
306 312 if (values.at(i).canConvert(QVariant::Double))
307 313 QBoxSet::append(values[i].toDouble());
308 314 }
309 315 }
310 316
311 317 QString DeclarativeBoxSet::brushFilename() const
312 318 {
313 319 return m_brushFilename;
314 320 }
315 321
316 322 void DeclarativeBoxSet::setBrushFilename(const QString &brushFilename)
317 323 {
318 324 QImage brushImage(brushFilename);
319 325 if (QBoxSet::brush().textureImage() != brushImage) {
320 326 QBrush brush = QBoxSet::brush();
321 327 brush.setTextureImage(brushImage);
322 328 QBoxSet::setBrush(brush);
323 329 m_brushFilename = brushFilename;
324 330 m_brushImage = brushImage;
325 331 emit brushFilenameChanged(brushFilename);
326 332 }
327 333 }
328 334
329 335 void DeclarativeBoxSet::handleBrushChanged()
330 336 {
331 337 // If the texture image of the brush has changed along the brush
332 338 // the brush file name needs to be cleared.
333 339 if (!m_brushFilename.isEmpty() && QBoxSet::brush().textureImage() != m_brushImage) {
334 340 m_brushFilename.clear();
335 341 emit brushFilenameChanged(QString(""));
336 342 }
337 343 }
338 344
339 345 // =====================================================
340 346
341 347 DeclarativeBoxPlotSeries::DeclarativeBoxPlotSeries(QQuickItem *parent) :
342 348 QBoxPlotSeries(parent),
343 349 m_axes(new DeclarativeAxes(this))
344 350 {
345 351 connect(m_axes, SIGNAL(axisXChanged(QAbstractAxis*)), this, SIGNAL(axisXChanged(QAbstractAxis*)));
346 352 connect(m_axes, SIGNAL(axisYChanged(QAbstractAxis*)), this, SIGNAL(axisYChanged(QAbstractAxis*)));
347 353 connect(m_axes, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SIGNAL(axisXTopChanged(QAbstractAxis*)));
348 354 connect(m_axes, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SIGNAL(axisYRightChanged(QAbstractAxis*)));
349 355 connect(this, SIGNAL(hovered(bool, QBoxSet*)), this, SLOT(onHovered(bool, QBoxSet*)));
350 356 connect(this, SIGNAL(clicked(QBoxSet*)), this, SLOT(onClicked(QBoxSet*)));
351 357 connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged()));
352 358 connect(this, SIGNAL(pressed(QBoxSet*)), this, SLOT(onPressed(QBoxSet*)));
353 359 connect(this, SIGNAL(released(QBoxSet*)), this, SLOT(onReleased(QBoxSet*)));
354 360 connect(this, SIGNAL(doubleClicked(QBoxSet*)), this, SLOT(onDoubleClicked(QBoxSet*)));
355 361 }
356 362
357 363 void DeclarativeBoxPlotSeries::classBegin()
358 364 {
359 365 }
360 366
361 367 void DeclarativeBoxPlotSeries::componentComplete()
362 368 {
363 369 foreach (QObject *child, children()) {
364 370 if (qobject_cast<DeclarativeBoxSet *>(child)) {
365 371 QBoxPlotSeries::append(qobject_cast<DeclarativeBoxSet *>(child));
366 372 } else if (qobject_cast<QVBoxPlotModelMapper *>(child)) {
367 373 QVBoxPlotModelMapper *mapper = qobject_cast<QVBoxPlotModelMapper *>(child);
368 374 mapper->setSeries(this);
369 375 }
370 376 }
371 377 }
372 378
373 379 QQmlListProperty<QObject> DeclarativeBoxPlotSeries::seriesChildren()
374 380 {
375 381 return QQmlListProperty<QObject>(this, 0, &DeclarativeBoxPlotSeries::appendSeriesChildren ,0,0,0);
376 382 }
377 383
378 384 void DeclarativeBoxPlotSeries::appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element)
379 385 {
380 386 // Empty implementation; the children are parsed in componentComplete instead
381 387 Q_UNUSED(list);
382 388 Q_UNUSED(element);
383 389 }
384 390
385 391 DeclarativeBoxSet *DeclarativeBoxPlotSeries::at(int index)
386 392 {
387 393 QList<QBoxSet *> setList = boxSets();
388 394 if (index >= 0 && index < setList.count())
389 395 return qobject_cast<DeclarativeBoxSet *>(setList[index]);
390 396
391 397 return 0;
392 398 }
393 399
394 400 DeclarativeBoxSet *DeclarativeBoxPlotSeries::insert(int index, const QString label, QVariantList values)
395 401 {
396 402 DeclarativeBoxSet *barset = new DeclarativeBoxSet(label, this);
397 403 barset->setValues(values);
398 404 if (QBoxPlotSeries::insert(index, barset))
399 405 return barset;
400 406 delete barset;
401 407 return 0;
402 408 }
403 409
404 410 void DeclarativeBoxPlotSeries::onHovered(bool status, QBoxSet *boxset)
405 411 {
406 412 emit hovered(status, qobject_cast<DeclarativeBoxSet *>(boxset));
407 413 }
408 414
409 415 void DeclarativeBoxPlotSeries::onClicked(QBoxSet *boxset)
410 416 {
411 417 emit clicked(qobject_cast<DeclarativeBoxSet *>(boxset));
412 418 }
413 419
414 420 void DeclarativeBoxPlotSeries::onPressed(QBoxSet *boxset)
415 421 {
416 422 emit pressed(qobject_cast<DeclarativeBoxSet *>(boxset));
417 423 }
418 424
419 425 void DeclarativeBoxPlotSeries::onReleased(QBoxSet *boxset)
420 426 {
421 427 emit released(qobject_cast<DeclarativeBoxSet *>(boxset));
422 428 }
423 429
424 430 void DeclarativeBoxPlotSeries::onDoubleClicked(QBoxSet *boxset)
425 431 {
426 432 emit doubleClicked(qobject_cast<DeclarativeBoxSet *>(boxset));
427 433 }
428 434
429 435 QString DeclarativeBoxPlotSeries::brushFilename() const
430 436 {
431 437 return m_brushFilename;
432 438 }
433 439
434 440 void DeclarativeBoxPlotSeries::setBrushFilename(const QString &brushFilename)
435 441 {
436 442 QImage brushImage(brushFilename);
437 443 if (QBoxPlotSeries::brush().textureImage() != brushImage) {
438 444 QBrush brush = QBoxPlotSeries::brush();
439 445 brush.setTextureImage(brushImage);
440 446 QBoxPlotSeries::setBrush(brush);
441 447 m_brushFilename = brushFilename;
442 448 m_brushImage = brushImage;
443 449 emit brushFilenameChanged(brushFilename);
444 450 }
445 451 }
446 452
447 453 void DeclarativeBoxPlotSeries::handleBrushChanged()
448 454 {
449 455 // If the texture image of the brush has changed along the brush
450 456 // the brush file name needs to be cleared.
451 457 if (!m_brushFilename.isEmpty() && QBoxPlotSeries::brush().textureImage() != m_brushImage) {
452 458 m_brushFilename.clear();
453 459 emit brushFilenameChanged(QString(""));
454 460 }
455 461 }
456 462
457 463 #include "moc_declarativeboxplotseries.cpp"
458 464
459 465 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now