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

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