1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Charts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QtCharts/QBoxSet>
31#include <private/qboxset_p.h>
32#include <private/charthelpers_p.h>
33
34QT_CHARTS_BEGIN_NAMESPACE
35
36/*!
37 \class QBoxSet
38 \inmodule QtCharts
39 \brief The QBoxSet class represents one item in a box-and-whiskers chart.
40
41 A box-and-whiskers item is a graphical representation of a range and three median values
42 that is constructed from five different values. There are two ways to specify the values.
43 The first one is by using a constructor or stream operator (<<). The values have to be
44 specified in the following order: lower extreme, lower quartile, median, upper quartile,
45 and upper extreme.
46
47 The second way is to create an empty QBoxSet instance and specify the values using the
48 setValue() method.
49
50 See the \l{Box and Whiskers Example}{box-and-whiskers chart example} to learn how to
51 create a box-and-whiskers chart.
52
53 \sa QBoxPlotSeries
54*/
55/*!
56 \enum QBoxSet::ValuePositions
57
58 This enum type defines the values of a box-and-whiskers item:
59
60 \value LowerExtreme The smallest value of the box-and-whiskers item.
61 \value LowerQuartile The median value of the lower half of the box-and-whiskers item.
62 \value Median The median value of the box-and-whiskers item.
63 \value UpperQuartile The median value of the upper half of the box-and-whiskers item.
64 \value UpperExtreme The largest value of the box-and-whiskers item.
65*/
66/*!
67 \property QBoxSet::pen
68 \brief The pen used to draw the lines of the box-and-whiskers item.
69*/
70/*!
71 \property QBoxSet::brush
72 \brief The brush used fill the box of the box-and-whiskers item.
73*/
74
75/*!
76 \fn void QBoxSet::clicked()
77 This signal is emitted when the user clicks a box-and-whiskers item in the chart.
78*/
79
80/*!
81 \fn void QBoxSet::pressed()
82 This signal is emitted when the user clicks a box-and-whiskers item in the chart
83 and holds down the mouse button.
84*/
85
86/*!
87 \fn void QBoxSet::released()
88 This signal is emitted when the user releases the mouse press on a box-and-whiskers item.
89*/
90
91/*!
92 \fn void QBoxSet::doubleClicked()
93 This signal is emitted when the user double-clicks a box-and-whiskers item.
94*/
95
96/*!
97 \fn void QBoxSet::hovered(bool status)
98
99 This signal is emitted when a mouse is hovered over a box-and-whiskers item in a chart.
100 When the mouse moves over the item, \a status turns \c true, and when the mouse moves
101 away again, it turns \c false.
102*/
103/*!
104 \fn void QBoxSet::penChanged()
105 This signal is emitted when the pen of the box-and-whiskers item changes.
106 \sa pen
107*/
108/*!
109 \fn void QBoxSet::brushChanged()
110 This signal is emitted when the brush of the box-and-whiskers item changes.
111 \sa brush
112*/
113/*!
114 \fn void QBoxSet::valuesChanged()
115 This signal is emitted when multiple values of the box-and-whiskers item change.
116 \sa append()
117*/
118/*!
119 \fn void QBoxSet::valueChanged(int index)
120 This signal is emitted when the value of the box-and-whiskers item specified by
121 \a index is modified.
122 \sa at()
123*/
124/*!
125 \fn void QBoxSet::cleared()
126 This signal is emitted when all the values of the box-and-whiskers item are set to 0.
127*/
128
129/*!
130 Constructs a box-and-whiskers item with the optional label \a label and parent \a parent.
131*/
132QBoxSet::QBoxSet(const QString label, QObject *parent)
133 : QObject(parent),
134 d_ptr(new QBoxSetPrivate(label, this))
135{
136}
137
138/*!
139 Constructs a box-and-whiskers item with the following ordered values: \a le specifies the
140 lower extreme, \a lq the lower quartile, \a m the median, \a uq the upper quartile, and
141 \a ue the upper quartile. Optionally, the \a label and \a parent can be specified.
142 */
143QBoxSet::QBoxSet(const qreal le, const qreal lq, const qreal m, const qreal uq, const qreal ue, const QString label, QObject *parent)
144 : QObject(parent),
145 d_ptr(new QBoxSetPrivate(label, this))
146{
147 d_ptr->append(value: le);
148 d_ptr->append(value: lq);
149 d_ptr->append(value: m);
150 d_ptr->append(value: uq);
151 d_ptr->append(value: ue);
152}
153
154/*!
155 Destroys the a box-and-whiskers item.
156*/
157QBoxSet::~QBoxSet()
158{
159}
160
161/*!
162 Appends the new value specified by \a value to the end of the box-and-whiskers item.
163*/
164void QBoxSet::append(const qreal value)
165{
166 if (d_ptr->append(value))
167 emit valueChanged(index: d_ptr->m_appendCount - 1);
168}
169
170/*!
171 Appends a list of real values specified by \a values to the end of the box-and-whiskers item.
172 \sa append()
173*/
174void QBoxSet::append(const QList<qreal> &values)
175{
176 if (d_ptr->append(values))
177 emit valuesChanged();
178}
179
180/*!
181 Sets the label specified by \a label for the category of the box-and-whiskers item.
182*/
183void QBoxSet::setLabel(const QString label)
184{
185 d_ptr->m_label = label;
186}
187
188/*!
189 Returns the label of the category of the box-and-whiskers item.
190*/
191QString QBoxSet::label() const
192{
193 return d_ptr->m_label;
194}
195
196/*!
197 A convenience operator for appending the real value specified by \a value to the end
198 of the box-and-whiskers item.
199 \sa append()
200*/
201QBoxSet &QBoxSet::operator << (const qreal &value)
202{
203 append(value);
204 return *this;
205}
206
207/*!
208 Sets the value specified by \a value in the position specified by \a index.
209 The index can be specified by using the ValuePositions enumeration values.
210*/
211void QBoxSet::setValue(const int index, const qreal value)
212{
213 d_ptr->setValue(index, value);
214 emit valueChanged(index);
215}
216
217/*!
218 Sets all the values of the box-and-whiskers item to 0.
219 */
220void QBoxSet::clear()
221{
222 d_ptr->clear();
223 emit cleared();
224}
225
226/*!
227 Returns the value of the box-and-whiskers item specified by \a index.
228 The index can be specified by using ValuePositions enumeration values.
229 If the index is out of bounds, 0.0 is returned.
230*/
231qreal QBoxSet::at(const int index) const
232{
233 if (index < 0 || index >= 5)
234 return 0;
235 return d_ptr->m_values[index];
236}
237
238/*!
239 Returns the value of the box-and-whiskers item specified by \a index.
240 The index can be specified by using ValuePositions enumeration values.
241 If the index is out of bounds, 0.0 is returned.
242*/
243qreal QBoxSet::operator [](const int index) const
244{
245 return at(index);
246}
247
248/*!
249 Returns the number of values appended to the box-and-whiskers item.
250*/
251int QBoxSet::count() const
252{
253 return d_ptr->m_appendCount;
254}
255
256/*!
257 Sets the pen used to draw the box-and-whiskers item to \a pen.
258*/
259void QBoxSet::setPen(const QPen &pen)
260{
261 if (d_ptr->m_pen != pen) {
262 d_ptr->m_pen = pen;
263 emit d_ptr->updatedBox();
264 emit penChanged();
265 }
266}
267
268/*!
269 Returns the pen used to draw the box-and-whiskers item.
270*/
271QPen QBoxSet::pen() const
272{
273 return d_ptr->m_pen;
274}
275
276/*!
277 Sets the brush used to fill the box-and-whiskers item to \a brush.
278*/
279void QBoxSet::setBrush(const QBrush &brush)
280{
281 if (d_ptr->m_brush != brush) {
282 d_ptr->m_brush = brush;
283 emit d_ptr->updatedBox();
284 emit brushChanged();
285 }
286}
287
288/*!
289 Returns the brush used to fill the box-and-whiskers item.
290*/
291QBrush QBoxSet::brush() const
292{
293 return d_ptr->m_brush;
294}
295
296////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
297
298QBoxSetPrivate::QBoxSetPrivate(const QString label, QBoxSet *parent) : QObject(parent),
299 q_ptr(parent),
300 m_label(label),
301 m_valuesCount(5),
302 m_appendCount(0),
303 m_pen(QPen(Qt::NoPen)),
304 m_brush(QBrush(Qt::NoBrush)),
305 m_series(0)
306{
307 m_values = new qreal[m_valuesCount];
308}
309
310QBoxSetPrivate::~QBoxSetPrivate()
311{
312 delete[] m_values;
313}
314
315bool QBoxSetPrivate::append(qreal value)
316{
317 if (isValidValue(value) && m_appendCount < m_valuesCount) {
318 m_values[m_appendCount++] = value;
319 emit restructuredBox();
320
321 return true;
322 }
323 return false;
324}
325
326bool QBoxSetPrivate::append(QList<qreal> values)
327{
328 bool success = false;
329
330 for (int i = 0; i < values.count(); i++) {
331 if (isValidValue(value: values.at(i)) && m_appendCount < m_valuesCount) {
332 success = true;
333 m_values[m_appendCount++] = values.at(i);
334 }
335 }
336
337 if (success)
338 emit restructuredBox();
339
340 return success;
341}
342
343void QBoxSetPrivate::clear()
344{
345 m_appendCount = 0;
346 for (int i = 0; i < m_valuesCount; i++) {
347 m_values[i] = 0.0;
348 }
349 emit restructuredBox();
350}
351
352void QBoxSetPrivate::setValue(const int index, const qreal value)
353{
354 if (index < m_valuesCount) {
355 m_values[index] = value;
356 emit updatedLayout();
357 }
358}
359
360qreal QBoxSetPrivate::value(const int index)
361{
362 if (index < 0 || index >= m_valuesCount)
363 return 0;
364 return m_values[index];
365}
366
367QT_CHARTS_END_NAMESPACE
368
369#include "moc_qboxset.cpp"
370#include "moc_qboxset_p.cpp"
371

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