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