1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
5
6#include <QtCharts/QBoxPlotSeries>
7#include <private/qboxplotseries_p.h>
8#include <QtCharts/QBoxPlotLegendMarker>
9#include <QtCharts/QBarCategoryAxis>
10#include <private/boxplotchartitem_p.h>
11#include <private/chartdataset_p.h>
12#include <private/charttheme_p.h>
13#include <QtCharts/QValueAxis>
14#include <private/charttheme_p.h>
15#include <private/boxplotanimation_p.h>
16#include <private/qchart_p.h>
17#include <QtCharts/QBoxSet>
18#include <private/qboxset_p.h>
19
20QT_BEGIN_NAMESPACE
21
22/*!
23 \class QBoxPlotSeries
24 \inmodule QtCharts
25 \brief The QBoxPlotSeries class presents data in box-and-whiskers charts.
26
27 A box plot series acts as a container for box-and-whiskers items. Items from multiple series
28 are grouped into categories according to their index value.
29
30 The QBarCategoryAxis class is used to add the categories to the chart's axis. Category labels
31 have to be unique. If the same category label is defined for several box-and-whiskers items,
32 only the first one is drawn.
33
34 See the \l {Charts with Widgets Gallery} to learn how to create a
35 box-and-whiskers chart.
36 \image examples_boxplotchart.png
37
38 \sa QBoxSet, QBarCategoryAxis
39*/
40/*!
41 \fn QBoxPlotSeries::boxsetsAdded(const QList<QBoxSet *> &sets)
42 This signal is emitted when the list of box-and-whiskers items specified by \a sets
43 is added to the series.
44*/
45/*!
46 \fn QBoxPlotSeries::boxsetsRemoved(const QList<QBoxSet *> &sets)
47 This signal is emitted when the list of box-and-whiskers items specified by \a sets
48 is removed from the series.
49*/
50/*!
51 \fn QBoxPlotSeries::clicked(QBoxSet *boxset)
52 This signal is emitted when the user clicks the box-and-whiskers item specified by
53 \a boxset in the chart.
54*/
55/*!
56 \fn QBoxPlotSeries::pressed(QBoxSet *boxset)
57 This signal is emitted when the user clicks the box-and-whiskers item specified by
58 \a boxset in the chart and holds down the mouse button.
59*/
60/*!
61 \fn QBoxPlotSeries::released(QBoxSet *boxset)
62 This signal is emitted when the user releases the mouse press on the box-and-whiskers
63 item specified by \a boxset in the chart.
64*/
65/*!
66 \fn QBoxPlotSeries::doubleClicked(QBoxSet *boxset)
67 This signal is emitted when the user double-clicks the box-and-whiskers item specified by
68 \a boxset in the chart.
69*/
70/*!
71 \fn QBoxPlotSeries::hovered(bool status, QBoxSet *boxset)
72 This signal is emitted when a mouse is hovered over the box-and-whiskers item specified by
73 \a boxset in the chart. When the mouse moves over the item, \a status turns \c true, and
74 when the mouse moves away again, it turns \c false.
75*/
76/*!
77 \fn QBoxPlotSeries::countChanged()
78 This signal is emitted when the number of box-and-whiskers items in the series changes.
79*/
80/*!
81 \property QBoxPlotSeries::boxOutlineVisible
82 \brief The visibility of the box outline.
83*/
84/*!
85 \property QBoxPlotSeries::boxWidth
86 \brief The width of the box-and-whiskers item. The value indicates the relative
87 width of the item within its category. The value can be between 0.0 and 1.0. Negative values
88 are replaced with 0.0 and values greater than 1.0 are replaced with 1.0.
89*/
90/*!
91 \property QBoxPlotSeries::pen
92 \brief The pen used to draw the lines of the box-and-whiskers items.
93*/
94/*!
95 \property QBoxPlotSeries::brush
96 \brief The brush used to fill the boxes of the box-and-whiskers items.
97*/
98/*!
99 \property QBoxPlotSeries::count
100 \brief The number of box-and-whiskers items in a box plot series.
101*/
102
103/*!
104 \fn void QBoxPlotSeries::boxOutlineVisibilityChanged()
105 This signal is emitted when the box outline visibility changes.
106*/
107
108/*!
109 \fn void QBoxPlotSeries::boxWidthChanged()
110 This signal is emitted when the width of the box-and-whiskers item changes.
111*/
112/*!
113 \fn void QBoxPlotSeries::penChanged()
114 This signal is emitted when the pen used to draw the lines of the box-and-whiskers
115 items changes.
116*/
117/*!
118 \fn void QBoxPlotSeries::brushChanged()
119 This signal is emitted when the brush used to fill the boxes of the box-and-whiskers
120 items changes.
121*/
122/*!
123 \fn virtual SeriesType QBoxPlotSeries::type() const
124 Returns the type of the series.
125 \sa QAbstractSeries, SeriesType
126*/
127
128/*!
129 Constructs an empty box plot series that is a QObject and a child of \a parent.
130*/
131QBoxPlotSeries::QBoxPlotSeries(QObject *parent)
132 : QAbstractSeries(*new QBoxPlotSeriesPrivate(this), parent)
133{
134}
135
136/*!
137 Removes the series from the chart.
138*/
139QBoxPlotSeries::~QBoxPlotSeries()
140{
141 Q_D(QBoxPlotSeries);
142 if (d->m_chart)
143 d->m_chart->removeSeries(series: this);
144}
145
146/*!
147 Adds a single box-and-whiskers item specified by \a set to the series and takes ownership of
148 it. If the item is null or it already belongs to the series, it will not be appended.
149 Returns \c true if appending succeeded.
150*/
151bool QBoxPlotSeries::append(QBoxSet *set)
152{
153 Q_D(QBoxPlotSeries);
154
155 bool success = d->append(set);
156 if (success) {
157 QList<QBoxSet *> sets;
158 sets.append(t: set);
159 set->setParent(this);
160 emit boxsetsAdded(sets);
161 emit countChanged();
162 }
163 return success;
164}
165
166/*!
167 Removes the box-and-whiskers item specified by \a set from the series and permanently
168 deletes it if the removal succeeds. Returns \c true if the item was removed.
169*/
170bool QBoxPlotSeries::remove(QBoxSet *set)
171{
172 Q_D(QBoxPlotSeries);
173 bool success = d->remove(set);
174 if (success) {
175 QList<QBoxSet *> sets;
176 sets.append(t: set);
177 set->setParent(0);
178 emit boxsetsRemoved(sets);
179 emit countChanged();
180 delete set;
181 set = 0;
182 }
183 return success;
184}
185
186/*!
187 Takes the box-and-whiskers item specified by \a set from the series. Does not delete the
188 item.
189
190 \note The series remains the item's parent object. You must set the parent object to take
191 full ownership.
192
193 Returns \c true if the take operation succeeds.
194
195*/
196bool QBoxPlotSeries::take(QBoxSet *set)
197{
198 Q_D(QBoxPlotSeries);
199
200 bool success = d->remove(set);
201 if (success) {
202 QList<QBoxSet *> sets;
203 sets.append(t: set);
204 emit boxsetsRemoved(sets);
205 emit countChanged();
206 }
207 return success;
208}
209
210/*!
211 Adds a list of box-and-whiskers items specified by \a sets to the series and takes ownership of
212 them. If the list is null or the items already belong to the series, it will not be appended.
213 Returns \c true if appending succeeded.
214*/
215bool QBoxPlotSeries::append(const QList<QBoxSet *> &sets)
216{
217 Q_D(QBoxPlotSeries);
218 bool success = d->append(sets);
219 if (success) {
220 emit boxsetsAdded(sets);
221 emit countChanged();
222 }
223 return success;
224}
225
226/*!
227 Inserts a box-and-whiskers item specified by \a set to a series at the position specified by
228 \a index and takes ownership of the item. If the item is null or already belongs to the series,
229 it will not be appended. Returns \c true if inserting succeeds.
230*/
231bool QBoxPlotSeries::insert(int index, QBoxSet *set)
232{
233 Q_D(QBoxPlotSeries);
234 bool success = d->insert(index, set);
235 if (success) {
236 QList<QBoxSet *> sets;
237 sets.append(t: set);
238 emit boxsetsAdded(sets);
239 emit countChanged();
240 }
241 return success;
242}
243
244/*!
245 Removes all box-and-whiskers items from the series and permanently deletes them.
246*/
247void QBoxPlotSeries::clear()
248{
249 Q_D(QBoxPlotSeries);
250 QList<QBoxSet *> sets = boxSets();
251 bool success = d->remove(sets);
252 if (success) {
253 emit boxsetsRemoved(sets);
254 emit countChanged();
255 foreach (QBoxSet *set, sets)
256 delete set;
257 }
258}
259
260/*!
261 Returns the number of box-and-whiskers items in a box plot series.
262*/
263int QBoxPlotSeries::count() const
264{
265 Q_D(const QBoxPlotSeries);
266 return d->m_boxSets.size();
267}
268
269/*!
270 Returns a list of box-and-whiskers items in a box plot series. Keeps the ownership of the items.
271 */
272QList<QBoxSet *> QBoxPlotSeries::boxSets() const
273{
274 Q_D(const QBoxPlotSeries);
275 return d->m_boxSets;
276}
277
278/*
279 Returns QAbstractSeries::SeriesTypeBoxPlot.
280*/
281QAbstractSeries::SeriesType QBoxPlotSeries::type() const
282{
283 return QAbstractSeries::SeriesTypeBoxPlot;
284}
285
286void QBoxPlotSeries::setBoxOutlineVisible(bool visible)
287{
288 Q_D(QBoxPlotSeries);
289
290 if (d->m_boxOutlineVisible != visible) {
291 d->m_boxOutlineVisible = visible;
292 emit d->updated();
293 emit boxOutlineVisibilityChanged();
294 }
295}
296
297bool QBoxPlotSeries::boxOutlineVisible()
298{
299 Q_D(QBoxPlotSeries);
300
301 return d->m_boxOutlineVisible;
302}
303
304void QBoxPlotSeries::setBoxWidth(qreal width)
305{
306 Q_D(QBoxPlotSeries);
307
308 if (width != d->m_boxWidth) {
309 if (width < 0.0)
310 width = 0.0;
311 if (width > 1.0)
312 width = 1.0;
313 d->m_boxWidth = width;
314 emit d->updatedLayout();
315 emit boxWidthChanged();
316 }
317}
318
319qreal QBoxPlotSeries::boxWidth()
320{
321 Q_D(QBoxPlotSeries);
322
323 return d->m_boxWidth;
324}
325
326void QBoxPlotSeries::setBrush(const QBrush &brush)
327{
328 Q_D(QBoxPlotSeries);
329
330 if (d->m_brush != brush) {
331 d->m_brush = brush;
332 emit d->updated();
333 emit brushChanged();
334 }
335}
336
337QBrush QBoxPlotSeries::brush() const
338{
339 Q_D(const QBoxPlotSeries);
340
341 return d->m_brush;
342}
343
344void QBoxPlotSeries::setPen(const QPen &pen)
345{
346 Q_D(QBoxPlotSeries);
347
348 if (d->m_pen != pen) {
349 d->m_pen = pen;
350 emit d->updated();
351 emit penChanged();
352 }
353}
354
355QPen QBoxPlotSeries::pen() const
356{
357 Q_D(const QBoxPlotSeries);
358
359 return d->m_pen;
360}
361
362///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
363
364QBoxPlotSeriesPrivate::QBoxPlotSeriesPrivate(QBoxPlotSeries *q)
365 : QAbstractSeriesPrivate(q),
366 m_pen(QChartPrivate::defaultPen()),
367 m_brush(QChartPrivate::defaultBrush()),
368 m_boxOutlineVisible(true),
369 m_boxWidth(0.5)
370{
371}
372
373QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()
374{
375 disconnect(sender: this, signal: 0, receiver: 0, member: 0);
376}
377
378void QBoxPlotSeriesPrivate::initializeDomain()
379{
380 qreal minX(domain()->minX());
381 qreal minY(domain()->minY());
382 qreal maxX(domain()->maxX());
383 qreal maxY(domain()->maxY());
384
385 qreal x = m_boxSets.size();
386 minX = qMin(a: minX, b: qreal(-0.5));
387 minY = qMin(a: minY, b: min());
388 maxX = qMax(a: maxX, b: x - qreal(0.5));
389 maxY = qMax(a: maxY, b: max());
390
391 domain()->setRange(minX, maxX, minY, maxY);
392}
393
394void QBoxPlotSeriesPrivate::initializeAxes()
395{
396 foreach (QAbstractAxis* axis, m_axes) {
397 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
398 if (axis->orientation() == Qt::Horizontal)
399 populateCategories(axis: qobject_cast<QBarCategoryAxis *>(object: axis));
400 }
401 }
402}
403
404QAbstractAxis::AxisType QBoxPlotSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
405{
406 if (orientation == Qt::Horizontal)
407 return QAbstractAxis::AxisTypeBarCategory;
408
409 return QAbstractAxis::AxisTypeValue;
410}
411
412QAbstractAxis* QBoxPlotSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
413{
414 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
415 return new QBarCategoryAxis;
416 else
417 return new QValueAxis;
418}
419
420void QBoxPlotSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
421{
422 QStringList categories;
423 if (axis->categories().isEmpty()) {
424 for (int i(1); i < m_boxSets.size() + 1; i++) {
425 QBoxSet *set = m_boxSets.at(i: i - 1);
426 if (set->label().isEmpty())
427 categories << presenter()->numberToString(value: i);
428 else
429 categories << set->label();
430 }
431 axis->append(categories);
432 }
433}
434
435void QBoxPlotSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
436{
437 Q_Q(QBoxPlotSeries);
438
439 BoxPlotChartItem *boxPlot = new BoxPlotChartItem(q, parent);
440 m_item.reset(p: boxPlot);
441 QAbstractSeriesPrivate::initializeGraphics(parent);
442
443 if (m_chart) {
444 connect(sender: m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: this, SLOT(handleSeriesChange(QAbstractSeries*)));
445 connect(sender: m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: this, SLOT(handleSeriesRemove(QAbstractSeries*)));
446
447 QList<QAbstractSeries *> serieses = m_chart->series();
448
449 // Tries to find this series from the Chart's list of series and deduce the index
450 int index = 0;
451 foreach (QAbstractSeries *s, serieses) {
452 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
453 if (q == static_cast<QBoxPlotSeries *>(s)) {
454 boxPlot->m_seriesIndex = index;
455 m_index = index;
456 }
457 index++;
458 }
459 }
460 boxPlot->m_seriesCount = index;
461 }
462
463 // Make BoxPlotChartItem to instantiate box & whisker items
464 boxPlot->handleDataStructureChanged();
465}
466
467void QBoxPlotSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
468{
469 Q_Q(QBoxPlotSeries);
470
471 const QList<QGradient> gradients = theme->seriesGradients();
472
473 if (forced || QChartPrivate::defaultBrush() == m_brush) {
474 QColor brushColor = ChartThemeManager::colorAt(gradient: gradients.at(i: index % gradients.size()), pos: 0.5);
475 q->setBrush(brushColor);
476 }
477
478 if (forced || QChartPrivate::defaultPen() == m_pen) {
479 QPen pen = theme->outlinePen();
480 pen.setCosmetic(true);
481 q->setPen(pen);
482 }
483}
484
485void QBoxPlotSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
486 QEasingCurve &curve)
487{
488 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.get());
489 Q_ASSERT(item);
490 if (item->animation())
491 item->animation()->stopAndDestroyLater();
492
493 if (options.testFlag(flag: QChart::SeriesAnimations))
494 m_animation = new BoxPlotAnimation(item, duration, curve);
495 else
496 m_animation = 0;
497 item->setAnimation(m_animation);
498
499 QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
500
501 // Make BoxPlotChartItem to instantiate box & whisker items
502 item->handleDataStructureChanged();
503}
504
505QList<QLegendMarker*> QBoxPlotSeriesPrivate::createLegendMarkers(QLegend *legend)
506{
507 Q_Q(QBoxPlotSeries);
508 QList<QLegendMarker *> list;
509 return list << new QBoxPlotLegendMarker(q, legend);
510}
511
512void QBoxPlotSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
513{
514 Q_Q(QBoxPlotSeries);
515
516 QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
517
518 if (q == removedSeries) {
519 if (m_animation)
520 m_animation->stopAll();
521 QObject::disconnect(sender: m_chart->d_ptr->m_dataset, signal: 0, receiver: this, member: 0);
522 }
523
524 // Test if series removed is me, then don't do anything
525 if (q != removedSeries) {
526 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.get());
527 if (item) {
528 item->m_seriesCount = item->m_seriesCount - 1;
529 if (removedSeries->d_func()->m_index < m_index) {
530 m_index--;
531 item->m_seriesIndex = m_index;
532 }
533
534 item->handleDataStructureChanged();
535 }
536 }
537}
538
539void QBoxPlotSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
540{
541 Q_UNUSED(series);
542
543 Q_Q(QBoxPlotSeries);
544
545 BoxPlotChartItem *boxPlot = static_cast<BoxPlotChartItem *>(m_item.get());
546
547 if (m_chart) {
548 QList<QAbstractSeries *> serieses = m_chart->series();
549
550 // Tries to find this series from the Chart's list of series and deduce the index
551 int index = 0;
552 foreach (QAbstractSeries *s, serieses) {
553 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
554 if (q == static_cast<QBoxPlotSeries *>(s)) {
555 boxPlot->m_seriesIndex = index;
556 m_index = index;
557 }
558 index++;
559 }
560 }
561 boxPlot->m_seriesCount = index;
562 }
563
564 boxPlot->handleDataStructureChanged();
565}
566
567bool QBoxPlotSeriesPrivate::append(QBoxSet *set)
568{
569 if (m_boxSets.contains(t: set) || (set == 0) || set->d_ptr->m_series)
570 return false; // Fail if set is already in list or set is null.
571
572 m_boxSets.append(t: set);
573 QObject::connect(sender: set->d_ptr.data(), SIGNAL(updatedLayout()), receiver: this, SIGNAL(updatedLayout()));
574 QObject::connect(sender: set->d_ptr.data(), SIGNAL(updatedBox()), receiver: this, SIGNAL(updatedBoxes()));
575 QObject::connect(sender: set->d_ptr.data(), SIGNAL(restructuredBox()), receiver: this, SIGNAL(restructuredBoxes()));
576 set->d_ptr->m_series = this;
577
578 emit restructuredBoxes(); // this notifies boxplotchartitem
579 return true;
580}
581
582bool QBoxPlotSeriesPrivate::remove(QBoxSet *set)
583{
584 if (!m_boxSets.contains(t: set))
585 return false; // Fail if set is not in list
586
587 set->d_ptr->m_series = 0;
588 m_boxSets.removeOne(t: set);
589 QObject::disconnect(sender: set->d_ptr.data(), SIGNAL(updatedLayout()), receiver: this, SIGNAL(updatedLayout()));
590 QObject::disconnect(sender: set->d_ptr.data(), SIGNAL(updatedBox()), receiver: this, SIGNAL(updatedBoxes()));
591 QObject::disconnect(sender: set->d_ptr.data(), SIGNAL(restructuredBox()), receiver: this, SIGNAL(restructuredBoxes()));
592
593 emit restructuredBoxes(); // this notifies boxplotchartitem
594 return true;
595}
596
597bool QBoxPlotSeriesPrivate::append(const QList<QBoxSet *> &sets)
598{
599 for (auto *set : sets) {
600 if ((set == 0) || m_boxSets.contains(t: set) || set->d_ptr->m_series)
601 return false; // Fail if any of the sets is null or is already appended.
602 if (sets.count(t: set) != 1)
603 return false; // Also fail if same set is more than once in given list.
604 }
605
606 for (auto *set : sets) {
607 m_boxSets.append(t: set);
608 QObject::connect(sender: set->d_ptr.data(), SIGNAL(updatedLayout()), receiver: this, SIGNAL(updatedLayout()));
609 QObject::connect(sender: set->d_ptr.data(), SIGNAL(updatedBox()), receiver: this, SIGNAL(updatedBoxes()));
610 QObject::connect(sender: set->d_ptr.data(), SIGNAL(restructuredBox()), receiver: this, SIGNAL(restructuredBoxes()));
611 set->d_ptr->m_series = this;
612 }
613
614 emit restructuredBoxes(); // this notifies boxplotchartitem
615 return true;
616}
617
618bool QBoxPlotSeriesPrivate::remove(const QList<QBoxSet *> &sets)
619{
620 if (sets.size() == 0)
621 return false;
622
623 for (auto *set : sets) {
624 if ((set == 0) || (!m_boxSets.contains(t: set)))
625 return false; // Fail if any of the sets is null or is not in series
626 if (sets.count(t: set) != 1)
627 return false; // Also fail if same set is more than once in given list.
628 }
629
630 for (auto *set : sets) {
631 set->d_ptr->m_series = 0;
632 m_boxSets.removeOne(t: set);
633 QObject::disconnect(sender: set->d_ptr.data(), SIGNAL(updatedLayout()), receiver: this, SIGNAL(updatedLayout()));
634 QObject::disconnect(sender: set->d_ptr.data(), SIGNAL(updatedBox()), receiver: this, SIGNAL(updatedBoxes()));
635 QObject::disconnect(sender: set->d_ptr.data(), SIGNAL(restructuredBox()), receiver: this, SIGNAL(restructuredBoxes()));
636 }
637
638 emit restructuredBoxes(); // this notifies boxplotchartitem
639
640 return true;
641}
642
643bool QBoxPlotSeriesPrivate::insert(int index, QBoxSet *set)
644{
645 if ((m_boxSets.contains(t: set)) || (set == 0) || set->d_ptr->m_series)
646 return false; // Fail if set is already in list or set is null.
647
648 m_boxSets.insert(i: index, t: set);
649 set->d_ptr->m_series = this;
650 QObject::connect(sender: set->d_ptr.data(), SIGNAL(updatedLayout()), receiver: this, SIGNAL(updatedLayout()));
651 QObject::connect(sender: set->d_ptr.data(), SIGNAL(updatedBox()), receiver: this, SIGNAL(updatedBoxes()));
652 QObject::connect(sender: set->d_ptr.data(), SIGNAL(restructuredBox()), receiver: this, SIGNAL(restructuredBoxes()));
653
654 emit restructuredBoxes(); // this notifies boxplotchartitem
655 return true;
656}
657
658QBoxSet *QBoxPlotSeriesPrivate::boxSetAt(int index)
659{
660 return m_boxSets.at(i: index);
661}
662
663qreal QBoxPlotSeriesPrivate::min()
664{
665 if (m_boxSets.size() <= 0)
666 return 0;
667
668 qreal min = m_boxSets.at(i: 0)->at(index: 0);
669
670 foreach (QBoxSet *set, m_boxSets) {
671 for (int i = 0; i < 5; i++) {
672 if (set->at(index: i) < min)
673 min = set->at(index: i);
674 }
675 }
676
677 return min;
678}
679
680qreal QBoxPlotSeriesPrivate::max()
681{
682 if (m_boxSets.size() <= 0)
683 return 0;
684
685 qreal max = m_boxSets.at(i: 0)->at(index: 0);
686
687 foreach (QBoxSet *set, m_boxSets) {
688 for (int i = 0; i < 5; i++) {
689 if (set->at(index: i) > max)
690 max = set->at(index: i);
691 }
692 }
693
694 return max;
695}
696
697QT_END_NAMESPACE
698
699#include "moc_qboxplotseries.cpp"
700#include "moc_qboxplotseries_p.cpp"
701

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtcharts/src/charts/boxplotchart/qboxplotseries.cpp