##// END OF EJS Templates
Fixes to barseries and pieseries model support. Started adding barseries model tests
Marek Rosa -
r1184:3138389fa706
parent child
Show More
@@ -1,94 +1,95
1 #include "qbarmodelmapper.h"
1 #include "qbarmodelmapper.h"
2
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
4
5 QBarModelMapper::QBarModelMapper(QObject *parent) :
5 QBarModelMapper::QBarModelMapper(QObject *parent) :
6 QObject(parent),
6 QObject(parent),
7 m_first(0),
7 m_first(0),
8 m_count(-1),
8 m_count(-1),
9 m_orientation(Qt::Vertical),
9 m_orientation(Qt::Vertical),
10 m_mapBarBottom(-1),
10 m_mapBarBottom(-1),
11 m_mapBarTop(-1),
11 m_mapBarTop(-1),
12 m_mapCategories(-1)
12 m_mapCategories(-1)
13 {
13 {
14 }
14 }
15
15
16 int QBarModelMapper::first() const
16 int QBarModelMapper::first() const
17 {
17 {
18 return m_first;
18 return m_first;
19 }
19 }
20
20
21 void QBarModelMapper::setFirst(int first)
21 void QBarModelMapper::setFirst(int first)
22 {
22 {
23 m_first = qMax(first, 0);
23 m_first = qMax(first, 0);
24 emit updated();
24 emit updated();
25 }
25 }
26
26
27 int QBarModelMapper::count() const
27 int QBarModelMapper::count() const
28 {
28 {
29 return m_count;
29 return m_count;
30 }
30 }
31
31
32 void QBarModelMapper::setCount(int count)
32 void QBarModelMapper::setCount(int count)
33 {
33 {
34 m_count = qMax(count, -1);
34 m_count = qMax(count, -1);
35 emit updated();
35 emit updated();
36 }
36 }
37
37
38 Qt::Orientation QBarModelMapper::orientation() const
38 Qt::Orientation QBarModelMapper::orientation() const
39 {
39 {
40 return m_orientation;
40 return m_orientation;
41 }
41 }
42
42
43 void QBarModelMapper::setOrientation(Qt::Orientation orientation)
43 void QBarModelMapper::setOrientation(Qt::Orientation orientation)
44 {
44 {
45 m_orientation = orientation;
45 m_orientation = orientation;
46 emit updated();
46 emit updated();
47 }
47 }
48
48
49 int QBarModelMapper::mapBarBottom() const
49 int QBarModelMapper::mapBarBottom() const
50 {
50 {
51 return m_mapBarBottom;
51 return m_mapBarBottom;
52 }
52 }
53
53
54 void QBarModelMapper::setMapBarBottom(int mapValues)
54 void QBarModelMapper::setMapBarBottom(int mapValues)
55 {
55 {
56 m_mapBarBottom = mapValues;
56 m_mapBarBottom = mapValues;
57 emit updated();
57 emit updated();
58 }
58 }
59
59
60 int QBarModelMapper::mapBarTop() const
60 int QBarModelMapper::mapBarTop() const
61 {
61 {
62 return m_mapBarTop;
62 return m_mapBarTop;
63 }
63 }
64
64
65 void QBarModelMapper::setMapBarTop(int mapLabels)
65 void QBarModelMapper::setMapBarTop(int mapLabels)
66 {
66 {
67 m_mapBarTop = mapLabels;
67 m_mapBarTop = mapLabels;
68 emit updated();
68 emit updated();
69 }
69 }
70
70
71 int QBarModelMapper::mapCategories() const
71 int QBarModelMapper::mapCategories() const
72 {
72 {
73 return m_mapCategories;
73 return m_mapCategories;
74 }
74 }
75
75
76 void QBarModelMapper::setMapCategories(int mapCategories)
76 void QBarModelMapper::setMapCategories(int mapCategories)
77 {
77 {
78 m_mapCategories = mapCategories;
78 m_mapCategories = mapCategories;
79 emit updated();
79 emit updated();
80 }
80 }
81
81
82 void QBarModelMapper::reset()
82 void QBarModelMapper::reset()
83 {
83 {
84 m_first = 0;
84 m_first = 0;
85 m_count = -1;
85 m_count = -1;
86 m_orientation = Qt::Vertical;
86 m_orientation = Qt::Vertical;
87 m_mapBarBottom = -1;
87 m_mapBarBottom = -1;
88 m_mapBarTop = -1;
88 m_mapBarTop = -1;
89 m_mapCategories = -1;
89 m_mapCategories = -1;
90 emit updated();
90 }
91 }
91
92
92 #include "moc_qbarmodelmapper.cpp"
93 #include "moc_qbarmodelmapper.cpp"
93
94
94 QTCOMMERCIALCHART_END_NAMESPACE
95 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,592 +1,608
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qbarseries.h"
21 #include "qbarseries.h"
22 #include "qbarseries_p.h"
22 #include "qbarseries_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "domain_p.h"
25 #include "domain_p.h"
26 #include "legendmarker_p.h"
26 #include "legendmarker_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30
30
31 #include <QAbstractItemModel>
31 #include <QAbstractItemModel>
32 #include <QModelIndex>
32 #include <QModelIndex>
33 #include <QBarModelMapper>
33 #include <QBarModelMapper>
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 /*!
37 /*!
38 \class QBarSeries
38 \class QBarSeries
39 \brief part of QtCommercial chart API.
39 \brief part of QtCommercial chart API.
40 \mainclass
40 \mainclass
41
41
42 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
42 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
43 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
43 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
44 by QStringList.
44 by QStringList.
45
45
46 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
46 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
47 \image examples_barchart.png
47 \image examples_barchart.png
48
48
49 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
49 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
50 */
50 */
51
51
52 /*!
52 /*!
53 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
53 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
54
54
55 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
55 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
56 contained by the series.
56 contained by the series.
57 */
57 */
58
58
59 /*!
59 /*!
60 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
60 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
61
61
62 The signal is emitted if mouse is hovered on top of series.
62 The signal is emitted if mouse is hovered on top of series.
63 Parameter \a barset is the pointer of barset, where hover happened.
63 Parameter \a barset is the pointer of barset, where hover happened.
64 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
64 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
65 */
65 */
66
66
67 /*!
67 /*!
68 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
68 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
69 QBarSeries is QObject which is a child of a \a parent.
69 QBarSeries is QObject which is a child of a \a parent.
70 */
70 */
71 QBarSeries::QBarSeries(/*QBarCategories categories,*/ QObject *parent) :
71 QBarSeries::QBarSeries(/*QBarCategories categories,*/ QObject *parent) :
72 QAbstractSeries(*new QBarSeriesPrivate(/*categories,*/ this),parent)
72 QAbstractSeries(*new QBarSeriesPrivate(/*categories,*/ this),parent)
73 {
73 {
74 }
74 }
75
75
76 /*!
76 /*!
77 Destructs barseries and owned barsets.
77 Destructs barseries and owned barsets.
78 */
78 */
79 QBarSeries::~QBarSeries()
79 QBarSeries::~QBarSeries()
80 {
80 {
81 // NOTE: d_ptr destroyed by QObject
81 // NOTE: d_ptr destroyed by QObject
82 }
82 }
83
83
84 /*!
84 /*!
85 \internal
85 \internal
86 */
86 */
87 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
87 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
88 QAbstractSeries(d,parent)
88 QAbstractSeries(d,parent)
89 {
89 {
90 }
90 }
91
91
92 /*!
92 /*!
93 Returns the type of series. Derived classes override this.
93 Returns the type of series. Derived classes override this.
94 */
94 */
95 QAbstractSeries::SeriesType QBarSeries::type() const
95 QAbstractSeries::SeriesType QBarSeries::type() const
96 {
96 {
97 return QAbstractSeries::SeriesTypeBar;
97 return QAbstractSeries::SeriesTypeBar;
98 }
98 }
99
99
100 void QBarSeries::setCategories(QBarCategories categories)
100 void QBarSeries::setCategories(QBarCategories categories)
101 {
101 {
102 Q_D(QBarSeries);
102 Q_D(QBarSeries);
103 d->setCategories(categories);
103 d->setCategories(categories);
104 emit d->categoriesUpdated();
104 emit d->categoriesUpdated();
105 }
105 }
106
106
107 /*!
107 /*!
108 Adds a set of bars to series. Takes ownership of \a set.
108 Adds a set of bars to series. Takes ownership of \a set.
109 */
109 */
110 bool QBarSeries::appendBarSet(QBarSet *set)
110 bool QBarSeries::appendBarSet(QBarSet *set)
111 {
111 {
112 Q_D(QBarSeries);
112 Q_D(QBarSeries);
113 if ((d->m_barSets.contains(set)) || (set == 0)) {
113 if ((d->m_barSets.contains(set)) || (set == 0)) {
114 // Fail if set is already in list or set is null.
114 // Fail if set is already in list or set is null.
115 return false;
115 return false;
116 }
116 }
117 d->m_barSets.append(set);
117 d->m_barSets.append(set);
118 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
118 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
119 emit d->restructuredBars();
119 emit d->restructuredBars();
120 return true;
120 return true;
121 }
121 }
122
122
123 /*!
123 /*!
124 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
124 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
125 */
125 */
126 bool QBarSeries::removeBarSet(QBarSet *set)
126 bool QBarSeries::removeBarSet(QBarSet *set)
127 {
127 {
128 Q_D(QBarSeries);
128 Q_D(QBarSeries);
129 if (!d->m_barSets.contains(set)) {
129 if (!d->m_barSets.contains(set)) {
130 // Fail if set is not in list
130 // Fail if set is not in list
131 return false;
131 return false;
132 }
132 }
133 d->m_barSets.removeOne(set);
133 d->m_barSets.removeOne(set);
134 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
134 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
135 emit d->restructuredBars();
135 emit d->restructuredBars();
136 return true;
136 return true;
137 }
137 }
138
138
139 /*!
139 /*!
140 Adds a list of barsets to series. Takes ownership of \a sets.
140 Adds a list of barsets to series. Takes ownership of \a sets.
141 */
141 */
142 bool QBarSeries::appendBarSets(QList<QBarSet* > sets)
142 bool QBarSeries::appendBarSets(QList<QBarSet* > sets)
143 {
143 {
144 Q_D(QBarSeries);
144 Q_D(QBarSeries);
145 foreach (QBarSet* set, sets) {
145 foreach (QBarSet* set, sets) {
146 if ((set == 0) || (d->m_barSets.contains(set))) {
146 if ((set == 0) || (d->m_barSets.contains(set))) {
147 // Fail if any of the sets is null or is already appended.
147 // Fail if any of the sets is null or is already appended.
148 return false;
148 return false;
149 }
149 }
150 if (sets.count(set) != 1) {
150 if (sets.count(set) != 1) {
151 // Also fail if same set is more than once in given list.
151 // Also fail if same set is more than once in given list.
152 return false;
152 return false;
153 }
153 }
154 }
154 }
155
155
156 foreach (QBarSet* set, sets) {
156 foreach (QBarSet* set, sets) {
157 d->m_barSets.append(set);
157 d->m_barSets.append(set);
158 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
158 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
159 }
159 }
160 emit d->restructuredBars();
160 emit d->restructuredBars();
161 return true;
161 return true;
162 }
162 }
163
163
164 /*!
164 /*!
165 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
165 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
166 */
166 */
167 bool QBarSeries::removeBarSets(QList<QBarSet* > sets)
167 bool QBarSeries::removeBarSets(QList<QBarSet* > sets)
168 {
168 {
169 Q_D(QBarSeries);
169 Q_D(QBarSeries);
170
170
171 bool setsRemoved = false;
171 bool setsRemoved = false;
172 foreach (QBarSet* set, sets) {
172 foreach (QBarSet* set, sets) {
173 if (d->m_barSets.contains(set)) {
173 if (d->m_barSets.contains(set)) {
174 d->m_barSets.removeOne(set);
174 d->m_barSets.removeOne(set);
175 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
175 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
176 setsRemoved = true;
176 setsRemoved = true;
177 }
177 }
178 }
178 }
179
179
180 if (setsRemoved) {
180 if (setsRemoved) {
181 emit d->restructuredBars();
181 emit d->restructuredBars();
182 }
182 }
183 return setsRemoved;
183 return setsRemoved;
184 }
184 }
185
185
186 /*!
186 /*!
187 Returns number of sets in series.
187 Returns number of sets in series.
188 */
188 */
189 int QBarSeries::barsetCount() const
189 int QBarSeries::barsetCount() const
190 {
190 {
191 Q_D(const QBarSeries);
191 Q_D(const QBarSeries);
192 return d->m_barSets.count();
192 return d->m_barSets.count();
193 }
193 }
194
194
195 /*!
195 /*!
196 Returns number of categories in series
196 Returns number of categories in series
197 */
197 */
198 int QBarSeries::categoryCount() const
198 int QBarSeries::categoryCount() const
199 {
199 {
200 Q_D(const QBarSeries);
200 Q_D(const QBarSeries);
201 return d->m_categories.count();
201 return d->m_categories.count();
202 }
202 }
203
203
204 /*!
204 /*!
205 Returns a list of sets in series. Keeps ownership of sets.
205 Returns a list of sets in series. Keeps ownership of sets.
206 */
206 */
207 QList<QBarSet*> QBarSeries::barSets() const
207 QList<QBarSet*> QBarSeries::barSets() const
208 {
208 {
209 Q_D(const QBarSeries);
209 Q_D(const QBarSeries);
210 return d->m_barSets;
210 return d->m_barSets;
211 }
211 }
212
212
213 /*!
213 /*!
214 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
214 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
215 Sets the \a model to be used as a data source
215 Sets the \a model to be used as a data source
216 */
216 */
217 void QBarSeries::setModel(QAbstractItemModel *model)
217 void QBarSeries::setModel(QAbstractItemModel *model)
218 {
218 {
219 Q_D(QBarSeries);
219 Q_D(QBarSeries);
220 // disconnect signals from old model
220 // disconnect signals from old model
221 if(d->m_model)
221 if(d->m_model)
222 {
222 {
223 disconnect(d->m_model, 0, this, 0);
223 disconnect(d->m_model, 0, this, 0);
224 }
224 }
225
225
226 // set new model
226 // set new model
227 if(model)
227 if(model)
228 {
228 {
229 d->m_model = model;
229 d->m_model = model;
230
230
231 // connect the signals
231 // connect the signals
232 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
232 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
233 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
233 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
234 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
234 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
235 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
235 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
236 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
236 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
237
237
238 if (d->m_mapper)
238 if (d->m_mapper)
239 d->initializeDataFromModel();
239 d->initializeDataFromModel();
240 }
240 }
241 else
241 else
242 {
242 {
243 d->m_model = 0;
243 d->m_model = 0;
244 }
244 }
245 }
245 }
246
246
247 void QBarSeries::setModelMapper(QBarModelMapper *mapper)
247 void QBarSeries::setModelMapper(QBarModelMapper *mapper)
248 {
248 {
249 Q_D(QBarSeries);
249 Q_D(QBarSeries);
250 // disconnect signals from old mapper
250 // disconnect signals from old mapper
251 if (d->m_mapper) {
251 if (d->m_mapper) {
252 QObject::disconnect(d->m_mapper, 0, this, 0);
252 QObject::disconnect(d->m_mapper, 0, this, 0);
253 }
253 }
254
254
255 if (mapper) {
255 if (mapper) {
256 d->m_mapper = mapper;
256 d->m_mapper = mapper;
257 // connect the signal from the mapper
257 // connect the signal from the mapper
258 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
258 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializeDataFromModel()));
259
259
260 if (d->m_model)
260 if (d->m_model)
261 d->initializeDataFromModel();
261 d->initializeDataFromModel();
262 } else {
262 } else {
263 d->m_mapper = 0;
263 d->m_mapper = 0;
264 }
264 }
265 }
265 }
266
266
267 QBarModelMapper* QBarSeries::modelMapper() const
267 QBarModelMapper* QBarSeries::modelMapper() const
268 {
268 {
269 Q_D(const QBarSeries);
269 Q_D(const QBarSeries);
270 return d->m_mapper;
270 return d->m_mapper;
271 }
271 }
272
272
273 /*!
273 /*!
274 Returns the bar categories of the series.
274 Returns the bar categories of the series.
275 */
275 */
276 QBarCategories QBarSeries::categories() const
276 QBarCategories QBarSeries::categories() const
277 {
277 {
278 Q_D(const QBarSeries);
278 Q_D(const QBarSeries);
279 return d->m_categories;
279 return d->m_categories;
280 }
280 }
281
281
282 /*!
282 /*!
283 Sets the visibility of labels in series to \a visible
283 Sets the visibility of labels in series to \a visible
284 */
284 */
285 void QBarSeries::setLabelsVisible(bool visible)
285 void QBarSeries::setLabelsVisible(bool visible)
286 {
286 {
287 foreach (QBarSet* s, barSets()) {
287 foreach (QBarSet* s, barSets()) {
288 s->setLabelsVisible(visible);
288 s->setLabelsVisible(visible);
289 }
289 }
290 }
290 }
291
291
292 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
292 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293
293
294 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
294 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
295 QAbstractSeriesPrivate(q),
295 QAbstractSeriesPrivate(q),
296 m_barMargin(0.05), // Default value is 5% of category width
296 m_barMargin(0.05), // Default value is 5% of category width
297 m_mapper(0)
297 m_mapper(0)
298 // m_categories(categories),
298 // m_categories(categories),
299 {
299 {
300 }
300 }
301
301
302 void QBarSeriesPrivate::setCategories(QBarCategories categories)
302 void QBarSeriesPrivate::setCategories(QBarCategories categories)
303 {
303 {
304 m_categories = categories;
304 m_categories = categories;
305 }
305 }
306
306
307 void QBarSeriesPrivate::setBarMargin(qreal margin)
307 void QBarSeriesPrivate::setBarMargin(qreal margin)
308 {
308 {
309 if (margin > 1.0) {
309 if (margin > 1.0) {
310 margin = 1.0;
310 margin = 1.0;
311 } else if (margin < 0.0) {
311 } else if (margin < 0.0) {
312 margin = 0.0;
312 margin = 0.0;
313 }
313 }
314
314
315 m_barMargin = margin;
315 m_barMargin = margin;
316 emit updatedBars();
316 emit updatedBars();
317 }
317 }
318
318
319 qreal QBarSeriesPrivate::barMargin()
319 qreal QBarSeriesPrivate::barMargin()
320 {
320 {
321 return m_barMargin;
321 return m_barMargin;
322 }
322 }
323
323
324 QBarSet* QBarSeriesPrivate::barsetAt(int index)
324 QBarSet* QBarSeriesPrivate::barsetAt(int index)
325 {
325 {
326 return m_barSets.at(index);
326 return m_barSets.at(index);
327 }
327 }
328
328
329 QString QBarSeriesPrivate::categoryName(int category)
329 QString QBarSeriesPrivate::categoryName(int category)
330 {
330 {
331 return m_categories.at(category);
331 return m_categories.at(category);
332 }
332 }
333
333
334 qreal QBarSeriesPrivate::min()
334 qreal QBarSeriesPrivate::min()
335 {
335 {
336 if (m_barSets.count() <= 0) {
336 if (m_barSets.count() <= 0) {
337 return 0;
337 return 0;
338 }
338 }
339 qreal min = INT_MAX;
339 qreal min = INT_MAX;
340
340
341 for (int i = 0; i < m_barSets.count(); i++) {
341 for (int i = 0; i < m_barSets.count(); i++) {
342 int categoryCount = m_barSets.at(i)->count();
342 int categoryCount = m_barSets.at(i)->count();
343 for (int j = 0; j < categoryCount; j++) {
343 for (int j = 0; j < categoryCount; j++) {
344 qreal temp = m_barSets.at(i)->at(j).y();
344 qreal temp = m_barSets.at(i)->at(j).y();
345 if (temp < min)
345 if (temp < min)
346 min = temp;
346 min = temp;
347 }
347 }
348 }
348 }
349 return min;
349 return min;
350 }
350 }
351
351
352 qreal QBarSeriesPrivate::max()
352 qreal QBarSeriesPrivate::max()
353 {
353 {
354 if (m_barSets.count() <= 0) {
354 if (m_barSets.count() <= 0) {
355 return 0;
355 return 0;
356 }
356 }
357 qreal max = INT_MIN;
357 qreal max = INT_MIN;
358
358
359 for (int i = 0; i < m_barSets.count(); i++) {
359 for (int i = 0; i < m_barSets.count(); i++) {
360 int categoryCount = m_barSets.at(i)->count();
360 int categoryCount = m_barSets.at(i)->count();
361 for (int j = 0; j < categoryCount; j++) {
361 for (int j = 0; j < categoryCount; j++) {
362 qreal temp = m_barSets.at(i)->at(j).y();
362 qreal temp = m_barSets.at(i)->at(j).y();
363 if (temp > max)
363 if (temp > max)
364 max = temp;
364 max = temp;
365 }
365 }
366 }
366 }
367
367
368 return max;
368 return max;
369 }
369 }
370
370
371 qreal QBarSeriesPrivate::valueAt(int set, int category)
371 qreal QBarSeriesPrivate::valueAt(int set, int category)
372 {
372 {
373 if ((set < 0) || (set >= m_barSets.count())) {
373 if ((set < 0) || (set >= m_barSets.count())) {
374 // No set, no value.
374 // No set, no value.
375 return 0;
375 return 0;
376 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
376 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
377 // No category, no value.
377 // No category, no value.
378 return 0;
378 return 0;
379 }
379 }
380
380
381 return m_barSets.at(set)->at(category).y();
381 return m_barSets.at(set)->at(category).y();
382 }
382 }
383
383
384 qreal QBarSeriesPrivate::percentageAt(int set, int category)
384 qreal QBarSeriesPrivate::percentageAt(int set, int category)
385 {
385 {
386 if ((set < 0) || (set >= m_barSets.count())) {
386 if ((set < 0) || (set >= m_barSets.count())) {
387 // No set, no value.
387 // No set, no value.
388 return 0;
388 return 0;
389 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
389 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
390 // No category, no value.
390 // No category, no value.
391 return 0;
391 return 0;
392 }
392 }
393
393
394 qreal value = m_barSets.at(set)->at(category).y();
394 qreal value = m_barSets.at(set)->at(category).y();
395 qreal sum = categorySum(category);
395 qreal sum = categorySum(category);
396 if ( qFuzzyIsNull(sum) ) {
396 if ( qFuzzyIsNull(sum) ) {
397 return 0;
397 return 0;
398 }
398 }
399
399
400 return value / sum;
400 return value / sum;
401 }
401 }
402
402
403 qreal QBarSeriesPrivate::categorySum(int category)
403 qreal QBarSeriesPrivate::categorySum(int category)
404 {
404 {
405 qreal sum(0);
405 qreal sum(0);
406 int count = m_barSets.count(); // Count sets
406 int count = m_barSets.count(); // Count sets
407 for (int set = 0; set < count; set++) {
407 for (int set = 0; set < count; set++) {
408 if (category < m_barSets.at(set)->count())
408 if (category < m_barSets.at(set)->count())
409 sum += m_barSets.at(set)->at(category).y();
409 sum += m_barSets.at(set)->at(category).y();
410 }
410 }
411 return sum;
411 return sum;
412 }
412 }
413
413
414 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
414 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
415 {
415 {
416 qreal sum(0);
416 qreal sum(0);
417 int count = m_barSets.count(); // Count sets
417 int count = m_barSets.count(); // Count sets
418 for (int set = 0; set < count; set++) {
418 for (int set = 0; set < count; set++) {
419 if (category < m_barSets.at(set)->count())
419 if (category < m_barSets.at(set)->count())
420 sum += qAbs(m_barSets.at(set)->at(category).y());
420 sum += qAbs(m_barSets.at(set)->at(category).y());
421 }
421 }
422 return sum;
422 return sum;
423 }
423 }
424
424
425 qreal QBarSeriesPrivate::maxCategorySum()
425 qreal QBarSeriesPrivate::maxCategorySum()
426 {
426 {
427 qreal max = INT_MIN;
427 qreal max = INT_MIN;
428 int count = m_categories.count();
428 int count = m_categories.count();
429 for (int i = 0; i < count; i++) {
429 for (int i = 0; i < count; i++) {
430 qreal sum = categorySum(i);
430 qreal sum = categorySum(i);
431 if (sum > max)
431 if (sum > max)
432 max = sum;
432 max = sum;
433 }
433 }
434 return max;
434 return max;
435 }
435 }
436
436
437 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
437 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
438 {
438 {
439 if (m_model == 0 || m_mapper == 0)
440 return;
441
439 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
442 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
440 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
443 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
441 if (m_mapper->orientation() == Qt::Vertical)
444 if (m_mapper->orientation() == Qt::Vertical)
442 {
445 {
443 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
446 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
444 if ( row >= m_mapper->first() && (m_mapper->count() == - 1 || row < m_mapper->first() + m_mapper->count())) {
447 if ( row >= m_mapper->first() && (m_mapper->count() == - 1 || row < m_mapper->first() + m_mapper->count())) {
445 if (column >= m_mapper->mapBarBottom() && column <= m_mapper->mapBarTop())
448 if (column >= m_mapper->mapBarBottom() && column <= m_mapper->mapBarTop())
446 barsetAt(column - m_mapper->mapBarBottom())->replace(row - m_mapper->first(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
449 barsetAt(column - m_mapper->mapBarBottom())->replace(row - m_mapper->first(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
447 // if (column == m_mapper->mapCategories());// TODO:
450 // if (column == m_mapper->mapCategories());// TODO:
448 }
451 }
449 }
452 }
450 else
453 else
451 {
454 {
452 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
455 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
453 if (column >= m_mapper->first() && (m_mapper->count() == - 1 || column < m_mapper->first() + m_mapper->count())) {
456 if (column >= m_mapper->first() && (m_mapper->count() == - 1 || column < m_mapper->first() + m_mapper->count())) {
454 if (row >= m_mapper->mapBarBottom() && row <= m_mapper->mapBarTop())
457 if (row >= m_mapper->mapBarBottom() && row <= m_mapper->mapBarTop())
455 barsetAt(row - m_mapper->mapBarBottom())->replace(column - m_mapper->first(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
458 barsetAt(row - m_mapper->mapBarBottom())->replace(column - m_mapper->first(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
456 // if (row == m_mapper->mapCategories());// TODO:
459 // if (row == m_mapper->mapCategories());// TODO:
457 }
460 }
458 }
461 }
459 }
462 }
460 }
463 }
461 }
464 }
462
465
463 void QBarSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
466 void QBarSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
464 {
467 {
465 Q_UNUSED(parent);
468 Q_UNUSED(parent);
466 Q_UNUSED(start);
469 Q_UNUSED(start);
467 Q_UNUSED(end);
470 Q_UNUSED(end);
468 initializeDataFromModel();
471 initializeDataFromModel();
469 }
472 }
470
473
471 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
474 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
472 {
475 {
473 Q_UNUSED(parent);
476 Q_UNUSED(parent);
474 Q_UNUSED(start);
477 Q_UNUSED(start);
475 Q_UNUSED(end);
478 Q_UNUSED(end);
476 initializeDataFromModel();
479 initializeDataFromModel();
477 }
480 }
478
481
479 void QBarSeriesPrivate::initializeDataFromModel()
482 void QBarSeriesPrivate::initializeDataFromModel()
480 {
483 {
481 Q_Q(QBarSeries);
484 Q_Q(QBarSeries);
482
485
483 if (m_model == 0 || m_mapper == 0)
484 return;
485
486 // create the initial bars
486 // create the initial bars
487 m_categories.clear();
487 m_categories.clear();
488 m_barSets.clear();
488 m_barSets.clear();
489
490 if (m_model == 0 || m_mapper == 0)
491 return;
492
493 // check if mappings are set
494 if (m_mapper->mapBarBottom() == -1 || m_mapper->mapBarTop() == -1 || m_mapper->mapCategories() == -1)
495 return;
496
489 // emit restructuredBars();
497 // emit restructuredBars();
490 if (m_mapper->orientation() == Qt::Vertical) {
498 if (m_mapper->orientation() == Qt::Vertical) {
499 if (m_mapCategories >= m_model->columnCount())
500 return;
491 int rowCount = 0;
501 int rowCount = 0;
492 if(m_mapper->count() == -1)
502 if(m_mapper->count() == -1)
493 rowCount = m_model->rowCount() - m_mapper->first();
503 rowCount = m_model->rowCount() - m_mapper->first();
494 else
504 else
495 rowCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
505 rowCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
496 for (int k = m_mapper->first(); k < m_mapper->first() + rowCount; k++) {
506 for (int k = m_mapper->first(); k < m_mapper->first() + rowCount; k++) {
497 m_categories << m_model->data(m_model->index(k, m_mapper->mapCategories()), Qt::DisplayRole).toString();
507 m_categories << m_model->data(m_model->index(k, m_mapper->mapCategories()), Qt::DisplayRole).toString();
498 }
508 }
499
509
500 for (int i = m_mapper->mapBarBottom(); i <= m_mapper->mapBarTop(); i++) {
510 int lastAvailableBarSet = qMin(m_model->columnCount() - 1, m_mapper->mapBarTop());
511 for (int i = m_mapper->mapBarBottom(); i <= lastAvailableBarSet; i++) {
512 // for (int i = m_mapper->mapBarBottom(); i <= m_mapper->mapBarTop(); i++) {
501 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
513 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
502 for(int m = m_mapper->first(); m < m_mapper->first() + rowCount; m++)
514 for(int m = m_mapper->first(); m < m_mapper->first() + rowCount; m++)
503 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
515 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
504 q->appendBarSet(barSet);
516 q->appendBarSet(barSet);
505 }
517 }
506 } else {
518 } else {
519 if (m_mapCategories >= m_model->rowCount())
520 return;
507 int columnCount = 0;
521 int columnCount = 0;
508 if(m_mapper->count() == -1)
522 if(m_mapper->count() == -1)
509 columnCount = m_model->columnCount() - m_mapper->first();
523 columnCount = m_model->columnCount() - m_mapper->first();
510 else
524 else
511 columnCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
525 columnCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
512 for (int k = m_mapper->first(); k < m_mapper->first() + columnCount; k++) {
526 for (int k = m_mapper->first(); k < m_mapper->first() + columnCount; k++) {
513 m_categories << m_model->data(m_model->index(m_mapper->mapCategories(), k), Qt::DisplayRole).toString();
527 m_categories << m_model->data(m_model->index(m_mapper->mapCategories(), k), Qt::DisplayRole).toString();
514 }
528 }
515
529
516 for (int i = m_mapper->mapBarBottom(); i <= m_mapper->mapBarTop(); i++) {
530 int lastAvailableBarSet = qMin(m_model->rowCount() - 1, m_mapper->mapBarTop());
531 for (int i = m_mapper->mapBarBottom(); i <= lastAvailableBarSet; i++) {
532 // for (int i = m_mapper->mapBarBottom(); i <= m_mapper->mapBarTop(); i++) {
517 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString());
533 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString());
518 for(int m = m_mapper->first(); m < m_mapper->first() + columnCount; m++)
534 for(int m = m_mapper->first(); m < m_mapper->first() + columnCount; m++)
519 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
535 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
520 q->appendBarSet(barSet);
536 q->appendBarSet(barSet);
521 }
537 }
522 }
538 }
523 emit restructuredBars();
539 emit restructuredBars();
524 // emit updatedBars();
540 // emit updatedBars();
525 }
541 }
526
542
527 void QBarSeriesPrivate::insertCategory(int index, const QString category)
543 void QBarSeriesPrivate::insertCategory(int index, const QString category)
528 {
544 {
529 m_categories.insert(index, category);
545 m_categories.insert(index, category);
530 emit categoriesUpdated();
546 emit categoriesUpdated();
531 }
547 }
532
548
533 void QBarSeriesPrivate::removeCategory(int index)
549 void QBarSeriesPrivate::removeCategory(int index)
534 {
550 {
535 m_categories.removeAt(index);
551 m_categories.removeAt(index);
536 emit categoriesUpdated();
552 emit categoriesUpdated();
537 }
553 }
538
554
539 void QBarSeriesPrivate::barsetChanged()
555 void QBarSeriesPrivate::barsetChanged()
540 {
556 {
541 emit updatedBars();
557 emit updatedBars();
542 }
558 }
543
559
544 void QBarSeriesPrivate::scaleDomain(Domain& domain)
560 void QBarSeriesPrivate::scaleDomain(Domain& domain)
545 {
561 {
546 qreal minX(domain.minX());
562 qreal minX(domain.minX());
547 qreal minY(domain.minY());
563 qreal minY(domain.minY());
548 qreal maxX(domain.maxX());
564 qreal maxX(domain.maxX());
549 qreal maxY(domain.maxY());
565 qreal maxY(domain.maxY());
550 int tickXCount(domain.tickXCount());
566 int tickXCount(domain.tickXCount());
551 int tickYCount(domain.tickYCount());
567 int tickYCount(domain.tickYCount());
552
568
553 qreal x = m_categories.count();
569 qreal x = m_categories.count();
554 qreal y = max();
570 qreal y = max();
555 minX = qMin(minX, x);
571 minX = qMin(minX, x);
556 minY = qMin(minY, y);
572 minY = qMin(minY, y);
557 maxX = qMax(maxX, x);
573 maxX = qMax(maxX, x);
558 maxY = qMax(maxY, y);
574 maxY = qMax(maxY, y);
559 tickXCount = x+1;
575 tickXCount = x+1;
560
576
561 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
577 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
562 }
578 }
563
579
564 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
580 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
565 {
581 {
566 Q_Q(QBarSeries);
582 Q_Q(QBarSeries);
567
583
568 BarChartItem* bar = new BarChartItem(q,presenter);
584 BarChartItem* bar = new BarChartItem(q,presenter);
569 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
585 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
570 presenter->animator()->addAnimation(bar);
586 presenter->animator()->addAnimation(bar);
571 }
587 }
572 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
588 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
573 return bar;
589 return bar;
574
590
575 }
591 }
576
592
577 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
593 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
578 {
594 {
579 Q_Q(QBarSeries);
595 Q_Q(QBarSeries);
580 QList<LegendMarker*> markers;
596 QList<LegendMarker*> markers;
581 foreach(QBarSet* set, q->barSets()) {
597 foreach(QBarSet* set, q->barSets()) {
582 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
598 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
583 markers << marker;
599 markers << marker;
584 }
600 }
585
601
586 return markers;
602 return markers;
587 }
603 }
588
604
589 #include "moc_qbarseries.cpp"
605 #include "moc_qbarseries.cpp"
590 #include "moc_qbarseries_p.cpp"
606 #include "moc_qbarseries_p.cpp"
591
607
592 QTCOMMERCIALCHART_END_NAMESPACE
608 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,815 +1,815
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qpieseries.h"
21 #include "qpieseries.h"
22 #include "qpieseries_p.h"
22 #include "qpieseries_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "pieslicedata_p.h"
24 #include "pieslicedata_p.h"
25 #include "chartdataset_p.h"
25 #include "chartdataset_p.h"
26 #include "charttheme_p.h"
26 #include "charttheme_p.h"
27 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
28 #include "legendmarker_p.h"
28 #include "legendmarker_p.h"
29 #include <QAbstractItemModel>
29 #include <QAbstractItemModel>
30 #include "qpiemodelmapper.h"
30 #include "qpiemodelmapper.h"
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /*!
34 /*!
35 \class QPieSeries
35 \class QPieSeries
36 \brief Pie series API for QtCommercial Charts
36 \brief Pie series API for QtCommercial Charts
37
37
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 The actual slice size is determined by that relative value.
40 The actual slice size is determined by that relative value.
41
41
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 These relate to the actual chart rectangle.
43 These relate to the actual chart rectangle.
44
44
45 By default the pie is defined as a full pie but it can also be a partial pie.
45 By default the pie is defined as a full pie but it can also be a partial pie.
46 This can be done by setting a starting angle and angle span to the series.
46 This can be done by setting a starting angle and angle span to the series.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
48
48
49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
50 \image examples_piechart.png
50 \image examples_piechart.png
51 */
51 */
52
52
53 /*!
53 /*!
54 \property QPieSeries::horizontalPosition
54 \property QPieSeries::horizontalPosition
55 \brief Defines the horizontal position of the pie.
55 \brief Defines the horizontal position of the pie.
56
56
57 The value is a relative value to the chart rectangle where:
57 The value is a relative value to the chart rectangle where:
58
58
59 \list
59 \list
60 \o 0.0 is the absolute left.
60 \o 0.0 is the absolute left.
61 \o 1.0 is the absolute right.
61 \o 1.0 is the absolute right.
62 \endlist
62 \endlist
63
63
64 Default value is 0.5 (center).
64 Default value is 0.5 (center).
65 */
65 */
66
66
67 /*!
67 /*!
68 \property QPieSeries::verticalPosition
68 \property QPieSeries::verticalPosition
69 \brief Defines the vertical position of the pie.
69 \brief Defines the vertical position of the pie.
70
70
71 The value is a relative value to the chart rectangle where:
71 The value is a relative value to the chart rectangle where:
72
72
73 \list
73 \list
74 \o 0.0 is the absolute top.
74 \o 0.0 is the absolute top.
75 \o 1.0 is the absolute bottom.
75 \o 1.0 is the absolute bottom.
76 \endlist
76 \endlist
77
77
78 Default value is 0.5 (center).
78 Default value is 0.5 (center).
79 */
79 */
80
80
81 /*!
81 /*!
82 \property QPieSeries::size
82 \property QPieSeries::size
83 \brief Defines the pie size.
83 \brief Defines the pie size.
84
84
85 The value is a relative value to the chart rectangle where:
85 The value is a relative value to the chart rectangle where:
86
86
87 \list
87 \list
88 \o 0.0 is the minimum size (pie not drawn).
88 \o 0.0 is the minimum size (pie not drawn).
89 \o 1.0 is the maximum size that can fit the chart.
89 \o 1.0 is the maximum size that can fit the chart.
90 \endlist
90 \endlist
91
91
92 Default value is 0.7.
92 Default value is 0.7.
93 */
93 */
94
94
95 /*!
95 /*!
96 \property QPieSeries::startAngle
96 \property QPieSeries::startAngle
97 \brief Defines the starting angle of the pie.
97 \brief Defines the starting angle of the pie.
98
98
99 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
99 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
100
100
101 Default is value is 0.
101 Default is value is 0.
102 */
102 */
103
103
104 /*!
104 /*!
105 \property QPieSeries::endAngle
105 \property QPieSeries::endAngle
106 \brief Defines the ending angle of the pie.
106 \brief Defines the ending angle of the pie.
107
107
108 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
108 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
109
109
110 Default is value is 360.
110 Default is value is 360.
111 */
111 */
112
112
113
113
114 /*!
114 /*!
115 Constructs a series object which is a child of \a parent.
115 Constructs a series object which is a child of \a parent.
116 */
116 */
117 QPieSeries::QPieSeries(QObject *parent) :
117 QPieSeries::QPieSeries(QObject *parent) :
118 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
118 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
119 {
119 {
120
120
121 }
121 }
122
122
123 /*!
123 /*!
124 Destroys the series and its slices.
124 Destroys the series and its slices.
125 */
125 */
126 QPieSeries::~QPieSeries()
126 QPieSeries::~QPieSeries()
127 {
127 {
128 // NOTE: d_prt destroyed by QObject
128 // NOTE: d_prt destroyed by QObject
129 }
129 }
130
130
131 /*!
131 /*!
132 Returns QChartSeries::SeriesTypePie.
132 Returns QChartSeries::SeriesTypePie.
133 */
133 */
134 QAbstractSeries::SeriesType QPieSeries::type() const
134 QAbstractSeries::SeriesType QPieSeries::type() const
135 {
135 {
136 return QAbstractSeries::SeriesTypePie;
136 return QAbstractSeries::SeriesTypePie;
137 }
137 }
138
138
139 /*!
139 /*!
140 Appends an array of \a slices to the series.
140 Appends an array of \a slices to the series.
141 Slice ownership is passed to the series.
141 Slice ownership is passed to the series.
142 */
142 */
143 bool QPieSeries::append(QList<QPieSlice*> slices)
143 bool QPieSeries::append(QList<QPieSlice*> slices)
144 {
144 {
145 Q_D(QPieSeries);
145 Q_D(QPieSeries);
146
146
147 if (slices.count() == 0)
147 if (slices.count() == 0)
148 return false;
148 return false;
149
149
150 foreach (QPieSlice* s, slices) {
150 foreach (QPieSlice* s, slices) {
151 if (!s || d->m_slices.contains(s))
151 if (!s || d->m_slices.contains(s))
152 return false;
152 return false;
153 }
153 }
154
154
155 foreach (QPieSlice* s, slices) {
155 foreach (QPieSlice* s, slices) {
156 s->setParent(this);
156 s->setParent(this);
157 d->m_slices << s;
157 d->m_slices << s;
158 }
158 }
159
159
160 d->updateDerivativeData();
160 d->updateDerivativeData();
161
161
162 foreach (QPieSlice* s, slices) {
162 foreach (QPieSlice* s, slices) {
163 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
163 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
164 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
164 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
165 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
165 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
166 }
166 }
167
167
168 emit d->added(slices);
168 emit d->added(slices);
169
169
170 return true;
170 return true;
171 }
171 }
172
172
173 /*!
173 /*!
174 Appends a single \a slice to the series.
174 Appends a single \a slice to the series.
175 Slice ownership is passed to the series.
175 Slice ownership is passed to the series.
176 */
176 */
177 bool QPieSeries::append(QPieSlice* slice)
177 bool QPieSeries::append(QPieSlice* slice)
178 {
178 {
179 return append(QList<QPieSlice*>() << slice);
179 return append(QList<QPieSlice*>() << slice);
180 }
180 }
181
181
182 /*!
182 /*!
183 Appends a single \a slice to the series and returns a reference to the series.
183 Appends a single \a slice to the series and returns a reference to the series.
184 Slice ownership is passed to the series.
184 Slice ownership is passed to the series.
185 */
185 */
186 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
186 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
187 {
187 {
188 append(slice);
188 append(slice);
189 return *this;
189 return *this;
190 }
190 }
191
191
192
192
193 /*!
193 /*!
194 Appends a single slice to the series with give \a value and \a name.
194 Appends a single slice to the series with give \a value and \a name.
195 Slice ownership is passed to the series.
195 Slice ownership is passed to the series.
196 */
196 */
197 QPieSlice* QPieSeries::append(qreal value, QString name)
197 QPieSlice* QPieSeries::append(qreal value, QString name)
198 {
198 {
199 QPieSlice* slice = new QPieSlice(value, name);
199 QPieSlice* slice = new QPieSlice(value, name);
200 append(slice);
200 append(slice);
201 return slice;
201 return slice;
202 }
202 }
203
203
204 /*!
204 /*!
205 Inserts a single \a slice to the series before the slice at \a index position.
205 Inserts a single \a slice to the series before the slice at \a index position.
206 Slice ownership is passed to the series.
206 Slice ownership is passed to the series.
207 */
207 */
208 bool QPieSeries::insert(int index, QPieSlice* slice)
208 bool QPieSeries::insert(int index, QPieSlice* slice)
209 {
209 {
210 Q_D(QPieSeries);
210 Q_D(QPieSeries);
211
211
212 if (index < 0 || index > d->m_slices.count())
212 if (index < 0 || index > d->m_slices.count())
213 return false;
213 return false;
214
214
215 if (!slice || d->m_slices.contains(slice))
215 if (!slice || d->m_slices.contains(slice))
216 return false;
216 return false;
217
217
218 slice->setParent(this);
218 slice->setParent(this);
219 d->m_slices.insert(index, slice);
219 d->m_slices.insert(index, slice);
220
220
221 d->updateDerivativeData();
221 d->updateDerivativeData();
222
222
223 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
223 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
224 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
224 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
225 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
225 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
226
226
227 emit d->added(QList<QPieSlice*>() << slice);
227 emit d->added(QList<QPieSlice*>() << slice);
228
228
229 return true;
229 return true;
230 }
230 }
231
231
232 /*!
232 /*!
233 Removes a single \a slice from the series and deletes the slice.
233 Removes a single \a slice from the series and deletes the slice.
234
234
235 Do not reference the pointer after this call.
235 Do not reference the pointer after this call.
236 */
236 */
237 bool QPieSeries::remove(QPieSlice* slice)
237 bool QPieSeries::remove(QPieSlice* slice)
238 {
238 {
239 Q_D(QPieSeries);
239 Q_D(QPieSeries);
240
240
241 if (!d->m_slices.removeOne(slice))
241 if (!d->m_slices.removeOne(slice))
242 return false;
242 return false;
243
243
244 d->updateDerivativeData();
244 d->updateDerivativeData();
245
245
246 emit d->removed(QList<QPieSlice*>() << slice);
246 emit d->removed(QList<QPieSlice*>() << slice);
247
247
248 delete slice;
248 delete slice;
249 slice = 0;
249 slice = 0;
250
250
251 return true;
251 return true;
252 }
252 }
253
253
254 /*!
254 /*!
255 Clears all slices from the series.
255 Clears all slices from the series.
256 */
256 */
257 void QPieSeries::clear()
257 void QPieSeries::clear()
258 {
258 {
259 Q_D(QPieSeries);
259 Q_D(QPieSeries);
260 if (d->m_slices.count() == 0)
260 if (d->m_slices.count() == 0)
261 return;
261 return;
262
262
263 QList<QPieSlice*> slices = d->m_slices;
263 QList<QPieSlice*> slices = d->m_slices;
264 foreach (QPieSlice* s, d->m_slices) {
264 foreach (QPieSlice* s, d->m_slices) {
265 d->m_slices.removeOne(s);
265 d->m_slices.removeOne(s);
266 delete s;
266 delete s;
267 }
267 }
268
268
269 d->updateDerivativeData();
269 d->updateDerivativeData();
270
270
271 emit d->removed(slices);
271 emit d->removed(slices);
272 }
272 }
273
273
274 /*!
274 /*!
275 returns the number of the slices in this series.
275 returns the number of the slices in this series.
276 */
276 */
277 int QPieSeries::count() const
277 int QPieSeries::count() const
278 {
278 {
279 Q_D(const QPieSeries);
279 Q_D(const QPieSeries);
280 return d->m_slices.count();
280 return d->m_slices.count();
281 }
281 }
282
282
283 /*!
283 /*!
284 Returns true is the series is empty.
284 Returns true is the series is empty.
285 */
285 */
286 bool QPieSeries::isEmpty() const
286 bool QPieSeries::isEmpty() const
287 {
287 {
288 Q_D(const QPieSeries);
288 Q_D(const QPieSeries);
289 return d->m_slices.isEmpty();
289 return d->m_slices.isEmpty();
290 }
290 }
291
291
292 /*!
292 /*!
293 Returns a list of slices that belong to this series.
293 Returns a list of slices that belong to this series.
294 */
294 */
295 QList<QPieSlice*> QPieSeries::slices() const
295 QList<QPieSlice*> QPieSeries::slices() const
296 {
296 {
297 Q_D(const QPieSeries);
297 Q_D(const QPieSeries);
298 return d->m_slices;
298 return d->m_slices;
299 }
299 }
300
300
301 void QPieSeries::setHorizontalPosition(qreal relativePosition)
301 void QPieSeries::setHorizontalPosition(qreal relativePosition)
302 {
302 {
303 Q_D(QPieSeries);
303 Q_D(QPieSeries);
304 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
304 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
305 emit d->piePositionChanged();
305 emit d->piePositionChanged();
306 }
306 }
307
307
308 void QPieSeries::setVerticalPosition(qreal relativePosition)
308 void QPieSeries::setVerticalPosition(qreal relativePosition)
309 {
309 {
310 Q_D(QPieSeries);
310 Q_D(QPieSeries);
311 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
311 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
312 emit d->piePositionChanged();
312 emit d->piePositionChanged();
313 }
313 }
314
314
315 qreal QPieSeries::horizontalPosition() const
315 qreal QPieSeries::horizontalPosition() const
316 {
316 {
317 Q_D(const QPieSeries);
317 Q_D(const QPieSeries);
318 return d->m_pieRelativeHorPos;
318 return d->m_pieRelativeHorPos;
319 }
319 }
320
320
321 qreal QPieSeries::verticalPosition() const
321 qreal QPieSeries::verticalPosition() const
322 {
322 {
323 Q_D(const QPieSeries);
323 Q_D(const QPieSeries);
324 return d->m_pieRelativeVerPos;
324 return d->m_pieRelativeVerPos;
325 }
325 }
326
326
327 void QPieSeries::setPieSize(qreal relativeSize)
327 void QPieSeries::setPieSize(qreal relativeSize)
328 {
328 {
329 Q_D(QPieSeries);
329 Q_D(QPieSeries);
330 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
330 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
331 emit d->pieSizeChanged();
331 emit d->pieSizeChanged();
332 }
332 }
333
333
334 qreal QPieSeries::pieSize() const
334 qreal QPieSeries::pieSize() const
335 {
335 {
336 Q_D(const QPieSeries);
336 Q_D(const QPieSeries);
337 return d->m_pieRelativeSize;
337 return d->m_pieRelativeSize;
338 }
338 }
339
339
340
340
341 void QPieSeries::setPieStartAngle(qreal angle)
341 void QPieSeries::setPieStartAngle(qreal angle)
342 {
342 {
343 Q_D(QPieSeries);
343 Q_D(QPieSeries);
344 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
344 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
345 d->updateDerivativeData();
345 d->updateDerivativeData();
346 }
346 }
347
347
348 qreal QPieSeries::pieStartAngle() const
348 qreal QPieSeries::pieStartAngle() const
349 {
349 {
350 Q_D(const QPieSeries);
350 Q_D(const QPieSeries);
351 return d->m_pieStartAngle;
351 return d->m_pieStartAngle;
352 }
352 }
353
353
354 /*!
354 /*!
355 Sets the end angle of the pie.
355 Sets the end angle of the pie.
356
356
357 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
357 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
358
358
359 \a angle must be greater than start angle.
359 \a angle must be greater than start angle.
360
360
361 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
361 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
362 */
362 */
363 void QPieSeries::setPieEndAngle(qreal angle)
363 void QPieSeries::setPieEndAngle(qreal angle)
364 {
364 {
365 Q_D(QPieSeries);
365 Q_D(QPieSeries);
366
366
367 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
367 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
368 d->updateDerivativeData();
368 d->updateDerivativeData();
369 }
369 }
370
370
371 /*!
371 /*!
372 Returns the end angle of the pie.
372 Returns the end angle of the pie.
373
373
374 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
374 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
375
375
376 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
376 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
377 */
377 */
378 qreal QPieSeries::pieEndAngle() const
378 qreal QPieSeries::pieEndAngle() const
379 {
379 {
380 Q_D(const QPieSeries);
380 Q_D(const QPieSeries);
381 return d->m_pieEndAngle;
381 return d->m_pieEndAngle;
382 }
382 }
383
383
384 /*!
384 /*!
385 Sets the all the slice labels \a visible or invisible.
385 Sets the all the slice labels \a visible or invisible.
386
386
387 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
387 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
388 */
388 */
389 void QPieSeries::setLabelsVisible(bool visible)
389 void QPieSeries::setLabelsVisible(bool visible)
390 {
390 {
391 Q_D(QPieSeries);
391 Q_D(QPieSeries);
392 foreach (QPieSlice* s, d->m_slices)
392 foreach (QPieSlice* s, d->m_slices)
393 s->setLabelVisible(visible);
393 s->setLabelVisible(visible);
394 }
394 }
395
395
396 /*!
396 /*!
397 Returns the sum of all slice values in this series.
397 Returns the sum of all slice values in this series.
398
398
399 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
399 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
400 */
400 */
401 qreal QPieSeries::sum() const
401 qreal QPieSeries::sum() const
402 {
402 {
403 Q_D(const QPieSeries);
403 Q_D(const QPieSeries);
404 return d->m_sum;
404 return d->m_sum;
405 }
405 }
406
406
407 /*!
407 /*!
408 \fn void QPieSeries::clicked(QPieSlice* slice)
408 \fn void QPieSeries::clicked(QPieSlice* slice)
409
409
410 This signal is emitted when a \a slice has been clicked.
410 This signal is emitted when a \a slice has been clicked.
411
411
412 \sa QPieSlice::clicked()
412 \sa QPieSlice::clicked()
413 */
413 */
414
414
415 /*!
415 /*!
416 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
416 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
417
417
418 This signal is emitted when user has hovered over or away from the \a slice.
418 This signal is emitted when user has hovered over or away from the \a slice.
419
419
420 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
420 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
421
421
422 \sa QPieSlice::hovered()
422 \sa QPieSlice::hovered()
423 */
423 */
424
424
425 /*!
425 /*!
426 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
426 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
427 Sets the \a model to be used as a data source
427 Sets the \a model to be used as a data source
428 */
428 */
429 void QPieSeries::setModel(QAbstractItemModel* model)
429 void QPieSeries::setModel(QAbstractItemModel* model)
430 {
430 {
431 Q_D(QPieSeries);
431 Q_D(QPieSeries);
432 // disconnect signals from old model
432 // disconnect signals from old model
433 if(d->m_model)
433 if(d->m_model)
434 {
434 {
435 disconnect(d->m_model, 0, this, 0);
435 disconnect(d->m_model, 0, this, 0);
436 }
436 }
437
437
438 // set new model
438 // set new model
439 if(model)
439 if(model)
440 {
440 {
441 d->m_model = model;
441 d->m_model = model;
442 // connect signals from the model
442 // connect signals from the model
443 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
443 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
444 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
444 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
445 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
445 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
446 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
446 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
447 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
447 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
448
448
449 if (d->m_mapper)
449 if (d->m_mapper)
450 d->initializePieFromModel();
450 d->initializePieFromModel();
451 }
451 }
452 else
452 else
453 {
453 {
454 d->m_model = 0;
454 d->m_model = 0;
455 }
455 }
456 }
456 }
457
457
458 void QPieSeries::setModelMapper(QPieModelMapper *mapper)
458 void QPieSeries::setModelMapper(QPieModelMapper *mapper)
459 {
459 {
460 Q_D(QPieSeries);
460 Q_D(QPieSeries);
461 // disconnect signals from old mapper
461 // disconnect signals from old mapper
462 if (d->m_mapper) {
462 if (d->m_mapper) {
463 QObject::disconnect(d->m_mapper, 0, this, 0);
463 QObject::disconnect(d->m_mapper, 0, this, 0);
464 }
464 }
465
465
466 if (mapper) {
466 if (mapper) {
467 d->m_mapper = mapper;
467 d->m_mapper = mapper;
468 // connect the signal from the mapper
468 // connect the signal from the mapper
469 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
469 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
470
470
471 if (d->m_model)
471 if (d->m_model)
472 d->initializePieFromModel();
472 d->initializePieFromModel();
473 } else {
473 } else {
474 d->m_mapper = 0;
474 d->m_mapper = 0;
475 }
475 }
476 }
476 }
477
477
478 QPieModelMapper* QPieSeries::modelMapper() const
478 QPieModelMapper* QPieSeries::modelMapper() const
479 {
479 {
480 Q_D(const QPieSeries);
480 Q_D(const QPieSeries);
481 return d->m_mapper;
481 return d->m_mapper;
482 }
482 }
483
483
484 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
484 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
485
485
486
486
487 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
487 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
488 QAbstractSeriesPrivate(parent),
488 QAbstractSeriesPrivate(parent),
489 m_pieRelativeHorPos(0.5),
489 m_pieRelativeHorPos(0.5),
490 m_pieRelativeVerPos(0.5),
490 m_pieRelativeVerPos(0.5),
491 m_pieRelativeSize(0.7),
491 m_pieRelativeSize(0.7),
492 m_pieStartAngle(0),
492 m_pieStartAngle(0),
493 m_pieEndAngle(360),
493 m_pieEndAngle(360),
494 m_sum(0),
494 m_sum(0),
495 m_mapper(0)
495 m_mapper(0)
496 {
496 {
497
497
498 }
498 }
499
499
500 QPieSeriesPrivate::~QPieSeriesPrivate()
500 QPieSeriesPrivate::~QPieSeriesPrivate()
501 {
501 {
502
502
503 }
503 }
504
504
505 void QPieSeriesPrivate::updateDerivativeData()
505 void QPieSeriesPrivate::updateDerivativeData()
506 {
506 {
507 m_sum = 0;
507 m_sum = 0;
508
508
509 // nothing to do?
509 // nothing to do?
510 if (m_slices.count() == 0)
510 if (m_slices.count() == 0)
511 return;
511 return;
512
512
513 // calculate sum of all slices
513 // calculate sum of all slices
514 foreach (QPieSlice* s, m_slices)
514 foreach (QPieSlice* s, m_slices)
515 m_sum += s->value();
515 m_sum += s->value();
516
516
517 // nothing to show..
517 // nothing to show..
518 if (qFuzzyIsNull(m_sum))
518 if (qFuzzyIsNull(m_sum))
519 return;
519 return;
520
520
521 // update slice attributes
521 // update slice attributes
522 qreal sliceAngle = m_pieStartAngle;
522 qreal sliceAngle = m_pieStartAngle;
523 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
523 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
524 QVector<QPieSlice*> changed;
524 QVector<QPieSlice*> changed;
525 foreach (QPieSlice* s, m_slices) {
525 foreach (QPieSlice* s, m_slices) {
526
526
527 PieSliceData data = PieSliceData::data(s);
527 PieSliceData data = PieSliceData::data(s);
528 data.m_percentage = s->value() / m_sum;
528 data.m_percentage = s->value() / m_sum;
529 data.m_angleSpan = pieSpan * data.m_percentage;
529 data.m_angleSpan = pieSpan * data.m_percentage;
530 data.m_startAngle = sliceAngle;
530 data.m_startAngle = sliceAngle;
531 sliceAngle += data.m_angleSpan;
531 sliceAngle += data.m_angleSpan;
532
532
533 if (PieSliceData::data(s) != data) {
533 if (PieSliceData::data(s) != data) {
534 PieSliceData::data(s) = data;
534 PieSliceData::data(s) = data;
535 changed << s;
535 changed << s;
536 }
536 }
537 }
537 }
538
538
539 // emit signals
539 // emit signals
540 foreach (QPieSlice* s, changed)
540 foreach (QPieSlice* s, changed)
541 PieSliceData::data(s).emitChangedSignal(s);
541 PieSliceData::data(s).emitChangedSignal(s);
542 }
542 }
543
543
544 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
544 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
545 {
545 {
546 return series.d_func();
546 return series.d_func();
547 }
547 }
548
548
549 void QPieSeriesPrivate::sliceChanged()
549 void QPieSeriesPrivate::sliceChanged()
550 {
550 {
551 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
551 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
552 updateDerivativeData();
552 updateDerivativeData();
553 }
553 }
554
554
555 void QPieSeriesPrivate::sliceClicked()
555 void QPieSeriesPrivate::sliceClicked()
556 {
556 {
557 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
557 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
558 Q_ASSERT(m_slices.contains(slice));
558 Q_ASSERT(m_slices.contains(slice));
559 Q_Q(QPieSeries);
559 Q_Q(QPieSeries);
560 emit q->clicked(slice);
560 emit q->clicked(slice);
561 }
561 }
562
562
563 void QPieSeriesPrivate::sliceHovered(bool state)
563 void QPieSeriesPrivate::sliceHovered(bool state)
564 {
564 {
565 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
565 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
566 Q_ASSERT(m_slices.contains(slice));
566 Q_ASSERT(m_slices.contains(slice));
567 Q_Q(QPieSeries);
567 Q_Q(QPieSeries);
568 emit q->hovered(slice, state);
568 emit q->hovered(slice, state);
569 }
569 }
570
570
571 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
571 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
572 {
572 {
573 if (m_mapper) {
573 if (m_mapper) {
574 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
574 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
575 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
575 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
576 if (m_mapper->orientation() == Qt::Vertical)
576 if (m_mapper->orientation() == Qt::Vertical)
577 {
577 {
578 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
578 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
579 if (topLeft.column() == m_mapper->mapValues())
579 if (topLeft.column() == m_mapper->mapValues())
580 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
580 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
581 if (topLeft.column() == m_mapper->mapLabels())
581 if (topLeft.column() == m_mapper->mapLabels())
582 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
582 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
583 }
583 }
584 }
584 }
585 else
585 else
586 {
586 {
587 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
587 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
588 if (topLeft.row() == m_mapper->mapValues())
588 if (topLeft.row() == m_mapper->mapValues())
589 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
589 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
590 if (topLeft.row() == m_mapper->mapLabels())
590 if (topLeft.row() == m_mapper->mapLabels())
591 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
591 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
592 }
592 }
593 }
593 }
594 }
594 }
595 }
595 }
596 }
596 }
597 }
597 }
598
598
599
599
600 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
600 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
601 {
601 {
602 Q_UNUSED(parent);
602 Q_UNUSED(parent);
603 if (m_mapper) {
603 if (m_mapper) {
604 if (m_mapper->orientation() == Qt::Vertical)
604 if (m_mapper->orientation() == Qt::Vertical)
605 insertData(start, end);
605 insertData(start, end);
606 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
606 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
607 initializePieFromModel();
607 initializePieFromModel();
608 }
608 }
609 }
609 }
610
610
611 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
611 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
612 {
612 {
613 Q_UNUSED(parent);
613 Q_UNUSED(parent);
614 if (m_mapper) {
614 if (m_mapper) {
615 if (m_mapper->orientation() == Qt::Vertical)
615 if (m_mapper->orientation() == Qt::Vertical)
616 removeData(start, end);
616 removeData(start, end);
617 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
617 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
618 initializePieFromModel();
618 initializePieFromModel();
619 }
619 }
620 }
620 }
621
621
622 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
622 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
623 {
623 {
624 Q_UNUSED(parent);
624 Q_UNUSED(parent);
625 if (m_mapper) {
625 if (m_mapper) {
626 if (m_mapper->orientation() == Qt::Horizontal)
626 if (m_mapper->orientation() == Qt::Horizontal)
627 insertData(start, end);
627 insertData(start, end);
628 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
628 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
629 initializePieFromModel();
629 initializePieFromModel();
630 }
630 }
631 }
631 }
632
632
633 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
633 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
634 {
634 {
635 Q_UNUSED(parent);
635 Q_UNUSED(parent);
636 if (m_mapper) {
636 if (m_mapper) {
637 if (m_mapper->orientation() == Qt::Horizontal)
637 if (m_mapper->orientation() == Qt::Horizontal)
638 removeData(start, end);
638 removeData(start, end);
639 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
639 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
640 initializePieFromModel();
640 initializePieFromModel();
641 }
641 }
642 }
642 }
643
643
644 void QPieSeriesPrivate::insertData(int start, int end)
644 void QPieSeriesPrivate::insertData(int start, int end)
645 {
645 {
646 Q_Q(QPieSeries);
646 Q_Q(QPieSeries);
647 if (m_mapper) {
647 if (m_mapper) {
648 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
648 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
649 return;
649 return;
650 } else {
650 } else {
651 int addedCount = end - start + 1;
651 int addedCount = end - start + 1;
652 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
652 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
653 addedCount = m_mapper->count();
653 addedCount = m_mapper->count();
654 int first = qMax(start, m_mapper->first());
654 int first = qMax(start, m_mapper->first());
655 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
655 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
656 for (int i = first; i <= last; i++) {
656 for (int i = first; i <= last; i++) {
657 QPieSlice *slice = new QPieSlice;
657 QPieSlice *slice = new QPieSlice;
658 if (m_mapper->orientation() == Qt::Vertical) {
658 if (m_mapper->orientation() == Qt::Vertical) {
659 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
659 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
660 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
660 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
661 } else {
661 } else {
662 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
662 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
663 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
663 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
664 }
664 }
665 slice->setLabelVisible();
665 slice->setLabelVisible();
666 q->insert(i - m_mapper->first(), slice);
666 q->insert(i - m_mapper->first(), slice);
667 }
667 }
668 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
668 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
669 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
669 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
670 q->remove(q->slices().at(i));
670 q->remove(q->slices().at(i));
671 }
671 }
672 }
672 }
673 }
673 }
674
674
675 void QPieSeriesPrivate::removeData(int start, int end)
675 void QPieSeriesPrivate::removeData(int start, int end)
676 {
676 {
677 Q_Q(QPieSeries);
677 Q_Q(QPieSeries);
678 if (m_mapper) {
678 if (m_mapper) {
679 int removedCount = end - start + 1;
679 int removedCount = end - start + 1;
680 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
680 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
681 return;
681 return;
682 } else {
682 } else {
683 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
683 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
684 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
684 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
685 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
685 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
686 for (int i = last; i >= first; i--)
686 for (int i = last; i >= first; i--)
687 q->remove(q->slices().at(i - m_mapper->first()));
687 q->remove(q->slices().at(i - m_mapper->first()));
688
688
689 if (m_mapper->count() != -1) {
689 if (m_mapper->count() != -1) {
690 int itemsAvailable; // check how many are available to be added
690 int itemsAvailable; // check how many are available to be added
691 if (m_mapper->orientation() == Qt::Vertical)
691 if (m_mapper->orientation() == Qt::Vertical)
692 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
692 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
693 else
693 else
694 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
694 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
695 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
695 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
696 int currentSize = m_slices.size();
696 int currentSize = m_slices.size();
697 if (toBeAdded > 0)
697 if (toBeAdded > 0)
698 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
698 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
699 QPieSlice *slice = new QPieSlice;
699 QPieSlice *slice = new QPieSlice;
700 if (m_mapper->orientation() == Qt::Vertical) {
700 if (m_mapper->orientation() == Qt::Vertical) {
701 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
701 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
702 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
702 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
703 } else {
703 } else {
704 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
704 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
705 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
705 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
706 }
706 }
707 slice->setLabelVisible();
707 slice->setLabelVisible();
708 q->insert(i, slice);
708 q->insert(i, slice);
709 }
709 }
710 }
710 }
711 }
711 }
712 }
712 }
713 }
713 }
714
714
715 void QPieSeriesPrivate::initializePieFromModel()
715 void QPieSeriesPrivate::initializePieFromModel()
716 {
716 {
717 Q_Q(QPieSeries);
717 Q_Q(QPieSeries);
718
718
719 if (m_model == 0 || m_mapper == 0)
720 return;
721
722 // clear current content
719 // clear current content
723 q->clear();
720 q->clear();
724
721
722 if (m_model == 0 || m_mapper == 0)
723 return;
724
725 // check if mappings are set
725 // check if mappings are set
726 if (m_mapper->mapValues() == -1 || m_mapper->mapLabels() == -1)
726 if (m_mapper->mapValues() == -1 || m_mapper->mapLabels() == -1)
727 return;
727 return;
728
728
729 // create the initial slices set
729 // create the initial slices set
730 if (m_mapper->orientation() == Qt::Vertical) {
730 if (m_mapper->orientation() == Qt::Vertical) {
731 if (m_mapper->mapValues() >= m_model->columnCount() || m_mapper->mapLabels() >= m_model->columnCount())
731 if (m_mapper->mapValues() >= m_model->columnCount() || m_mapper->mapLabels() >= m_model->columnCount())
732 return; // mapped columns are not existing
732 return; // mapped columns are not existing
733
733
734 int sliceCount = 0;
734 int sliceCount = 0;
735 if(m_mapper->count() == -1)
735 if(m_mapper->count() == -1)
736 sliceCount = m_model->rowCount() - m_mapper->first();
736 sliceCount = m_model->rowCount() - m_mapper->first();
737 else
737 else
738 sliceCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
738 sliceCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
739 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
739 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
740 q->append(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
740 q->append(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
741 } else {
741 } else {
742 if (m_mapper->mapValues() >= m_model->rowCount() || m_mapper->mapLabels() >= m_model->rowCount())
742 if (m_mapper->mapValues() >= m_model->rowCount() || m_mapper->mapLabels() >= m_model->rowCount())
743 return; // mapped columns are not existing
743 return; // mapped columns are not existing
744
744
745 int sliceCount = 0;
745 int sliceCount = 0;
746 if(m_mapper->count() == -1)
746 if(m_mapper->count() == -1)
747 sliceCount = m_model->columnCount() - m_mapper->first();
747 sliceCount = m_model->columnCount() - m_mapper->first();
748 else
748 else
749 sliceCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
749 sliceCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
750 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
750 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
751 q->append(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
751 q->append(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
752 }
752 }
753 q->setLabelsVisible(true);
753 q->setLabelsVisible(true);
754 }
754 }
755
755
756 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
756 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
757 {
757 {
758 // Remove rounding errors
758 // Remove rounding errors
759 qreal roundedValue = newValue;
759 qreal roundedValue = newValue;
760 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
760 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
761 roundedValue = 0.0;
761 roundedValue = 0.0;
762 else if (qFuzzyCompare(newValue, max))
762 else if (qFuzzyCompare(newValue, max))
763 roundedValue = max;
763 roundedValue = max;
764 else if (qFuzzyCompare(newValue, min))
764 else if (qFuzzyCompare(newValue, min))
765 roundedValue = min;
765 roundedValue = min;
766
766
767 // Check if the position is valid after removing the rounding errors
767 // Check if the position is valid after removing the rounding errors
768 if (roundedValue < min || roundedValue > max) {
768 if (roundedValue < min || roundedValue > max) {
769 qWarning("QPieSeries: Illegal value");
769 qWarning("QPieSeries: Illegal value");
770 return false;
770 return false;
771 }
771 }
772
772
773 if (!qFuzzyIsNull(value - roundedValue)) {
773 if (!qFuzzyIsNull(value - roundedValue)) {
774 value = roundedValue;
774 value = roundedValue;
775 return true;
775 return true;
776 }
776 }
777
777
778 // The change was so small it is considered a rounding error
778 // The change was so small it is considered a rounding error
779 return false;
779 return false;
780 }
780 }
781
781
782 void QPieSeriesPrivate::scaleDomain(Domain& domain)
782 void QPieSeriesPrivate::scaleDomain(Domain& domain)
783 {
783 {
784 Q_UNUSED(domain);
784 Q_UNUSED(domain);
785 #ifndef QT_NO_DEBUG
785 #ifndef QT_NO_DEBUG
786 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
786 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
787 #endif
787 #endif
788 }
788 }
789
789
790 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
790 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
791 {
791 {
792 Q_Q(QPieSeries);
792 Q_Q(QPieSeries);
793 PieChartItem* pie = new PieChartItem(q,presenter);
793 PieChartItem* pie = new PieChartItem(q,presenter);
794 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
794 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
795 presenter->animator()->addAnimation(pie);
795 presenter->animator()->addAnimation(pie);
796 }
796 }
797 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
797 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
798 return pie;
798 return pie;
799 }
799 }
800
800
801 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
801 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
802 {
802 {
803 Q_Q(QPieSeries);
803 Q_Q(QPieSeries);
804 QList<LegendMarker*> markers;
804 QList<LegendMarker*> markers;
805 foreach(QPieSlice* slice, q->slices()) {
805 foreach(QPieSlice* slice, q->slices()) {
806 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
806 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
807 markers << marker;
807 markers << marker;
808 }
808 }
809 return markers;
809 return markers;
810 }
810 }
811
811
812 #include "moc_qpieseries.cpp"
812 #include "moc_qpieseries.cpp"
813 #include "moc_qpieseries_p.cpp"
813 #include "moc_qpieseries_p.cpp"
814
814
815 QTCOMMERCIALCHART_END_NAMESPACE
815 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,347 +1,403
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include <QtTest/QtTest>
21 #include <QtTest/QtTest>
22 #include <qgroupedbarseries.h>
22 #include <qgroupedbarseries.h>
23 #include <qbarset.h>
23 #include <qbarset.h>
24 #include <qchartview.h>
24 #include <qchartview.h>
25 #include <qchart.h>
25 #include <qchart.h>
26 #include <QBarModelMapper>
27 #include <QStandardItemModel>
26
28
27 QTCOMMERCIALCHART_USE_NAMESPACE
29 QTCOMMERCIALCHART_USE_NAMESPACE
28
30
29 Q_DECLARE_METATYPE(QBarSet*)
31 Q_DECLARE_METATYPE(QBarSet*)
30
32
31 class tst_QGroupedBarSeries : public QObject
33 class tst_QGroupedBarSeries : public QObject
32 {
34 {
33 Q_OBJECT
35 Q_OBJECT
34
36
35 public slots:
37 public slots:
36 void initTestCase();
38 void initTestCase();
37 void cleanupTestCase();
39 void cleanupTestCase();
38 void init();
40 void init();
39 void cleanup();
41 void cleanup();
40
42
41 private slots:
43 private slots:
42 void qgroupedbarseries_data();
44 void qgroupedbarseries_data();
43 void qgroupedbarseries();
45 void qgroupedbarseries();
44 void type_data();
46 void type_data();
45 void type();
47 void type();
46 void mouseclicked_data();
48 void mouseclicked_data();
47 void mouseclicked();
49 void mouseclicked();
48 void mousehovered_data();
50 void mousehovered_data();
49 void mousehovered();
51 void mousehovered();
52 void model();
50
53
51 private:
54 private:
52 QGroupedBarSeries* m_barseries;
55 QGroupedBarSeries* m_barseries;
53 };
56 };
54
57
55 void tst_QGroupedBarSeries::initTestCase()
58 void tst_QGroupedBarSeries::initTestCase()
56 {
59 {
57 qRegisterMetaType<QBarSet*>("QBarSet*");
60 qRegisterMetaType<QBarSet*>("QBarSet*");
58 }
61 }
59
62
60 void tst_QGroupedBarSeries::cleanupTestCase()
63 void tst_QGroupedBarSeries::cleanupTestCase()
61 {
64 {
62 }
65 }
63
66
64 void tst_QGroupedBarSeries::init()
67 void tst_QGroupedBarSeries::init()
65 {
68 {
66 m_barseries = new QGroupedBarSeries();
69 m_barseries = new QGroupedBarSeries();
67 }
70 }
68
71
69 void tst_QGroupedBarSeries::cleanup()
72 void tst_QGroupedBarSeries::cleanup()
70 {
73 {
71 delete m_barseries;
74 delete m_barseries;
72 m_barseries = 0;
75 m_barseries = 0;
73 }
76 }
74
77
75 void tst_QGroupedBarSeries::qgroupedbarseries_data()
78 void tst_QGroupedBarSeries::qgroupedbarseries_data()
76 {
79 {
77 }
80 }
78
81
79 void tst_QGroupedBarSeries::qgroupedbarseries()
82 void tst_QGroupedBarSeries::qgroupedbarseries()
80 {
83 {
81 QGroupedBarSeries *barseries = new QGroupedBarSeries();
84 QGroupedBarSeries *barseries = new QGroupedBarSeries();
82 QVERIFY(barseries != 0);
85 QVERIFY(barseries != 0);
83 }
86 }
84
87
85 void tst_QGroupedBarSeries::type_data()
88 void tst_QGroupedBarSeries::type_data()
86 {
89 {
87
90
88 }
91 }
89
92
90 void tst_QGroupedBarSeries::type()
93 void tst_QGroupedBarSeries::type()
91 {
94 {
92 QVERIFY(m_barseries->type() == QAbstractSeries::SeriesTypeGroupedBar);
95 QVERIFY(m_barseries->type() == QAbstractSeries::SeriesTypeGroupedBar);
93 }
96 }
94
97
95 void tst_QGroupedBarSeries::mouseclicked_data()
98 void tst_QGroupedBarSeries::mouseclicked_data()
96 {
99 {
97
100
98 }
101 }
99
102
100 void tst_QGroupedBarSeries::mouseclicked()
103 void tst_QGroupedBarSeries::mouseclicked()
101 {
104 {
102 QGroupedBarSeries* series = new QGroupedBarSeries();
105 QGroupedBarSeries* series = new QGroupedBarSeries();
103 QBarCategories categories;
106 QBarCategories categories;
104 categories << "test1" << "test2" << "test3";
107 categories << "test1" << "test2" << "test3";
105 series->setCategories(categories);
108 series->setCategories(categories);
106
109
107 QBarSet* set1 = new QBarSet(QString("set 1"));
110 QBarSet* set1 = new QBarSet(QString("set 1"));
108 *set1 << 10 << 10 << 10;
111 *set1 << 10 << 10 << 10;
109 series->appendBarSet(set1);
112 series->appendBarSet(set1);
110
113
111 QBarSet* set2 = new QBarSet(QString("set 2"));
114 QBarSet* set2 = new QBarSet(QString("set 2"));
112 *set2 << 10 << 10 << 10;
115 *set2 << 10 << 10 << 10;
113 series->appendBarSet(set2);
116 series->appendBarSet(set2);
114
117
115 QSignalSpy setSpy1(set1, SIGNAL(clicked(QString)));
118 QSignalSpy setSpy1(set1, SIGNAL(clicked(QString)));
116 QSignalSpy setSpy2(set2, SIGNAL(clicked(QString)));
119 QSignalSpy setSpy2(set2, SIGNAL(clicked(QString)));
117 QSignalSpy seriesSpy(series,SIGNAL(clicked(QBarSet*,QString)));
120 QSignalSpy seriesSpy(series,SIGNAL(clicked(QBarSet*,QString)));
118
121
119 QChartView view(new QChart());
122 QChartView view(new QChart());
120 view.resize(400,300);
123 view.resize(400,300);
121 view.chart()->addSeries(series);
124 view.chart()->addSeries(series);
122 view.show();
125 view.show();
123 QTest::qWaitForWindowShown(&view);
126 QTest::qWaitForWindowShown(&view);
124
127
125 //====================================================================================
128 //====================================================================================
126 // barset 1, category test1
129 // barset 1, category test1
127 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(100,180));
130 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(100,180));
128 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
131 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
129
132
130 QCOMPARE(setSpy1.count(), 1);
133 QCOMPARE(setSpy1.count(), 1);
131 QCOMPARE(setSpy2.count(), 0);
134 QCOMPARE(setSpy2.count(), 0);
132 QCOMPARE(seriesSpy.count(), 1);
135 QCOMPARE(seriesSpy.count(), 1);
133 QList<QVariant> setSpyArg = setSpy1.takeFirst();
136 QList<QVariant> setSpyArg = setSpy1.takeFirst();
134 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
137 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
135 QVERIFY(setSpyArg.at(0).toString().compare(QString("test1")) == 0);
138 QVERIFY(setSpyArg.at(0).toString().compare(QString("test1")) == 0);
136
139
137 QList<QVariant> seriesSpyArg = seriesSpy.takeFirst();
140 QList<QVariant> seriesSpyArg = seriesSpy.takeFirst();
138 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
141 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
139
142
140 //====================================================================================
143 //====================================================================================
141 // barset 1, category test2
144 // barset 1, category test2
142 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(190,180));
145 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(190,180));
143 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
146 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
144
147
145 QCOMPARE(setSpy1.count(), 1);
148 QCOMPARE(setSpy1.count(), 1);
146 QCOMPARE(setSpy2.count(), 0);
149 QCOMPARE(setSpy2.count(), 0);
147 QCOMPARE(seriesSpy.count(), 1);
150 QCOMPARE(seriesSpy.count(), 1);
148 setSpyArg = setSpy1.takeFirst();
151 setSpyArg = setSpy1.takeFirst();
149 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
152 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
150 QVERIFY(setSpyArg.at(0).toString().compare(QString("test2")) == 0);
153 QVERIFY(setSpyArg.at(0).toString().compare(QString("test2")) == 0);
151
154
152 seriesSpyArg = seriesSpy.takeFirst();
155 seriesSpyArg = seriesSpy.takeFirst();
153 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
156 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
154
157
155 //====================================================================================
158 //====================================================================================
156 // barset 1, category test3
159 // barset 1, category test3
157 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(280,180));
160 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(280,180));
158 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
161 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
159
162
160 QCOMPARE(setSpy1.count(), 1);
163 QCOMPARE(setSpy1.count(), 1);
161 QCOMPARE(setSpy2.count(), 0);
164 QCOMPARE(setSpy2.count(), 0);
162 QCOMPARE(seriesSpy.count(), 1);
165 QCOMPARE(seriesSpy.count(), 1);
163 setSpyArg = setSpy1.takeFirst();
166 setSpyArg = setSpy1.takeFirst();
164 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
167 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
165 QVERIFY(setSpyArg.at(0).toString().compare(QString("test3")) == 0);
168 QVERIFY(setSpyArg.at(0).toString().compare(QString("test3")) == 0);
166
169
167 seriesSpyArg = seriesSpy.takeFirst();
170 seriesSpyArg = seriesSpy.takeFirst();
168 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
171 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
169
172
170 //====================================================================================
173 //====================================================================================
171 // barset 2, category test1
174 // barset 2, category test1
172 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(130,180));
175 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(130,180));
173 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
176 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
174
177
175 QCOMPARE(setSpy1.count(), 0);
178 QCOMPARE(setSpy1.count(), 0);
176 QCOMPARE(setSpy2.count(), 1);
179 QCOMPARE(setSpy2.count(), 1);
177 QCOMPARE(seriesSpy.count(), 1);
180 QCOMPARE(seriesSpy.count(), 1);
178 setSpyArg = setSpy2.takeFirst();
181 setSpyArg = setSpy2.takeFirst();
179 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
182 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
180 QVERIFY(setSpyArg.at(0).toString().compare(QString("test1")) == 0);
183 QVERIFY(setSpyArg.at(0).toString().compare(QString("test1")) == 0);
181
184
182 seriesSpyArg = seriesSpy.takeFirst();
185 seriesSpyArg = seriesSpy.takeFirst();
183 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
186 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
184
187
185 //====================================================================================
188 //====================================================================================
186 // barset 2, category test2
189 // barset 2, category test2
187 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(220,180));
190 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(220,180));
188 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
191 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
189
192
190 QCOMPARE(setSpy1.count(), 0);
193 QCOMPARE(setSpy1.count(), 0);
191 QCOMPARE(setSpy2.count(), 1);
194 QCOMPARE(setSpy2.count(), 1);
192 QCOMPARE(seriesSpy.count(), 1);
195 QCOMPARE(seriesSpy.count(), 1);
193 setSpyArg = setSpy2.takeFirst();
196 setSpyArg = setSpy2.takeFirst();
194 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
197 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
195 QVERIFY(setSpyArg.at(0).toString().compare(QString("test2")) == 0);
198 QVERIFY(setSpyArg.at(0).toString().compare(QString("test2")) == 0);
196
199
197 seriesSpyArg = seriesSpy.takeFirst();
200 seriesSpyArg = seriesSpy.takeFirst();
198 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
201 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
199
202
200 //====================================================================================
203 //====================================================================================
201 // barset 2, category test3
204 // barset 2, category test3
202 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(310,180));
205 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(310,180));
203 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
206 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
204
207
205 QCOMPARE(setSpy1.count(), 0);
208 QCOMPARE(setSpy1.count(), 0);
206 QCOMPARE(setSpy2.count(), 1);
209 QCOMPARE(setSpy2.count(), 1);
207 QCOMPARE(seriesSpy.count(), 1);
210 QCOMPARE(seriesSpy.count(), 1);
208 setSpyArg = setSpy2.takeFirst();
211 setSpyArg = setSpy2.takeFirst();
209 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
212 QVERIFY(setSpyArg.at(0).type() == QVariant::String);
210 QVERIFY(setSpyArg.at(0).toString().compare(QString("test3")) == 0);
213 QVERIFY(setSpyArg.at(0).toString().compare(QString("test3")) == 0);
211
214
212 seriesSpyArg = seriesSpy.takeFirst();
215 seriesSpyArg = seriesSpy.takeFirst();
213 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
216 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
214
217
215 //====================================================================================
218 //====================================================================================
216 // no event cases
219 // no event cases
217 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(1,1)); // Outside of both sets
220 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(1,1)); // Outside of both sets
218 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(1,1)); // Right mouse button outside and inside sets
221 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(1,1)); // Right mouse button outside and inside sets
219 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(100,180)); // barset 1, category test1
222 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(100,180)); // barset 1, category test1
220 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(190,180)); // barset 1, category test2
223 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(190,180)); // barset 1, category test2
221 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(280,180)); // barset 1, category test3
224 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(280,180)); // barset 1, category test3
222 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(130,180)); // barset 2, category test1
225 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(130,180)); // barset 2, category test1
223 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(220,180)); // barset 2, category test2
226 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(220,180)); // barset 2, category test2
224 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(310,180)); // barset 2, category test3
227 QTest::mouseClick(view.viewport(), Qt::RightButton, 0, QPoint(310,180)); // barset 2, category test3
225
228
226 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
229 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
227 QCOMPARE(setSpy1.count(), 0);
230 QCOMPARE(setSpy1.count(), 0);
228 QCOMPARE(setSpy2.count(), 0);
231 QCOMPARE(setSpy2.count(), 0);
229 QCOMPARE(seriesSpy.count(), 0);
232 QCOMPARE(seriesSpy.count(), 0);
230 }
233 }
231
234
232 void tst_QGroupedBarSeries::mousehovered_data()
235 void tst_QGroupedBarSeries::mousehovered_data()
233 {
236 {
234
237
235 }
238 }
236
239
237 void tst_QGroupedBarSeries::mousehovered()
240 void tst_QGroupedBarSeries::mousehovered()
238 {
241 {
239 QGroupedBarSeries* series = new QGroupedBarSeries();
242 QGroupedBarSeries* series = new QGroupedBarSeries();
240 QBarCategories categories;
243 QBarCategories categories;
241 categories << "test1" << "test2" << "test3";
244 categories << "test1" << "test2" << "test3";
242 series->setCategories(categories);
245 series->setCategories(categories);
243
246
244 QBarSet* set1 = new QBarSet(QString("set 1"));
247 QBarSet* set1 = new QBarSet(QString("set 1"));
245 *set1 << 10 << 10 << 10;
248 *set1 << 10 << 10 << 10;
246 series->appendBarSet(set1);
249 series->appendBarSet(set1);
247
250
248 QBarSet* set2 = new QBarSet(QString("set 2"));
251 QBarSet* set2 = new QBarSet(QString("set 2"));
249 *set2 << 10 << 10 << 10;
252 *set2 << 10 << 10 << 10;
250 series->appendBarSet(set2);
253 series->appendBarSet(set2);
251
254
252 QSignalSpy setSpy1(set1, SIGNAL(hovered(bool)));
255 QSignalSpy setSpy1(set1, SIGNAL(hovered(bool)));
253 QSignalSpy setSpy2(set2, SIGNAL(hovered(bool)));
256 QSignalSpy setSpy2(set2, SIGNAL(hovered(bool)));
254 QSignalSpy seriesSpy(series,SIGNAL(hovered(QBarSet*,bool)));
257 QSignalSpy seriesSpy(series,SIGNAL(hovered(QBarSet*,bool)));
255
258
256 QChartView view(new QChart());
259 QChartView view(new QChart());
257 view.resize(400,300);
260 view.resize(400,300);
258 view.chart()->addSeries(series);
261 view.chart()->addSeries(series);
259 view.show();
262 view.show();
260 QTest::qWaitForWindowShown(&view);
263 QTest::qWaitForWindowShown(&view);
261
264
262 //this is hack since view does not get events otherwise
265 //this is hack since view does not get events otherwise
263 view.setMouseTracking(true);
266 view.setMouseTracking(true);
264
267
265 //=======================================================================
268 //=======================================================================
266 // move mouse to left border
269 // move mouse to left border
267 QTest::mouseMove(view.viewport(), QPoint(0, 180));
270 QTest::mouseMove(view.viewport(), QPoint(0, 180));
268
271
269 QVERIFY(setSpy1.count() == 0);
272 QVERIFY(setSpy1.count() == 0);
270 QVERIFY(setSpy2.count() == 0);
273 QVERIFY(setSpy2.count() == 0);
271 QVERIFY(seriesSpy.count() == 0);
274 QVERIFY(seriesSpy.count() == 0);
272
275
273 //=======================================================================
276 //=======================================================================
274 // move mouse on top of set1
277 // move mouse on top of set1
275 QTest::mouseMove(view.viewport(), QPoint(100,180));
278 QTest::mouseMove(view.viewport(), QPoint(100,180));
276
279
277 QVERIFY(setSpy1.count() == 1);
280 QVERIFY(setSpy1.count() == 1);
278 QVERIFY(setSpy2.count() == 0);
281 QVERIFY(setSpy2.count() == 0);
279 QVERIFY(seriesSpy.count() == 1);
282 QVERIFY(seriesSpy.count() == 1);
280
283
281 QList<QVariant> setSpyArg = setSpy1.takeFirst();
284 QList<QVariant> setSpyArg = setSpy1.takeFirst();
282 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
285 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
283 QVERIFY(setSpyArg.at(0).toBool() == true);
286 QVERIFY(setSpyArg.at(0).toBool() == true);
284
287
285 QList<QVariant> seriesSpyArg = seriesSpy.takeFirst();
288 QList<QVariant> seriesSpyArg = seriesSpy.takeFirst();
286 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
289 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
287
290
288 //=======================================================================
291 //=======================================================================
289 // move mouse from top of set1 to top of set2
292 // move mouse from top of set1 to top of set2
290 QTest::mouseMove(view.viewport(), QPoint(130,180));
293 QTest::mouseMove(view.viewport(), QPoint(130,180));
291
294
292 QVERIFY(setSpy1.count() == 1);
295 QVERIFY(setSpy1.count() == 1);
293 QVERIFY(setSpy2.count() == 1);
296 QVERIFY(setSpy2.count() == 1);
294 QVERIFY(seriesSpy.count() == 2);
297 QVERIFY(seriesSpy.count() == 2);
295
298
296 // should leave set1
299 // should leave set1
297 setSpyArg = setSpy1.takeFirst();
300 setSpyArg = setSpy1.takeFirst();
298 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
301 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
299 QVERIFY(setSpyArg.at(0).toBool() == false);
302 QVERIFY(setSpyArg.at(0).toBool() == false);
300
303
301 // should enter set2
304 // should enter set2
302 setSpyArg = setSpy2.takeFirst();
305 setSpyArg = setSpy2.takeFirst();
303 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
306 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
304 QVERIFY(setSpyArg.at(0).toBool() == true);
307 QVERIFY(setSpyArg.at(0).toBool() == true);
305
308
306 // should leave set1
309 // should leave set1
307 seriesSpyArg = seriesSpy.takeFirst();
310 seriesSpyArg = seriesSpy.takeFirst();
308 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
311 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set1);
309 QVERIFY(seriesSpyArg.at(1).type() == QVariant::Bool);
312 QVERIFY(seriesSpyArg.at(1).type() == QVariant::Bool);
310 QVERIFY(seriesSpyArg.at(1).toBool() == false);
313 QVERIFY(seriesSpyArg.at(1).toBool() == false);
311
314
312 // should enter set2
315 // should enter set2
313 seriesSpyArg = seriesSpy.takeFirst();
316 seriesSpyArg = seriesSpy.takeFirst();
314 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
317 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
315 QVERIFY(seriesSpyArg.at(1).type() == QVariant::Bool);
318 QVERIFY(seriesSpyArg.at(1).type() == QVariant::Bool);
316 QVERIFY(seriesSpyArg.at(1).toBool() == true);
319 QVERIFY(seriesSpyArg.at(1).toBool() == true);
317
320
318 //=======================================================================
321 //=======================================================================
319 // move mouse from top of set2 to background
322 // move mouse from top of set2 to background
320 QTest::mouseMove(view.viewport(), QPoint(160,180));
323 QTest::mouseMove(view.viewport(), QPoint(160,180));
321
324
322 QVERIFY(setSpy1.count() == 0);
325 QVERIFY(setSpy1.count() == 0);
323 QVERIFY(setSpy2.count() == 1);
326 QVERIFY(setSpy2.count() == 1);
324 QVERIFY(seriesSpy.count() == 1);
327 QVERIFY(seriesSpy.count() == 1);
325
328
326 // should leave set2 (event via set)
329 // should leave set2 (event via set)
327 setSpyArg = setSpy2.takeFirst();
330 setSpyArg = setSpy2.takeFirst();
328 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
331 QVERIFY(setSpyArg.at(0).type() == QVariant::Bool);
329 QVERIFY(setSpyArg.at(0).toBool() == false);
332 QVERIFY(setSpyArg.at(0).toBool() == false);
330
333
331 // should leave set2 (event via series)
334 // should leave set2 (event via series)
332 seriesSpyArg = seriesSpy.takeFirst();
335 seriesSpyArg = seriesSpy.takeFirst();
333 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
336 QCOMPARE(qvariant_cast<QBarSet*>(seriesSpyArg.at(0)), set2);
334 QVERIFY(seriesSpyArg.at(1).type() == QVariant::Bool);
337 QVERIFY(seriesSpyArg.at(1).type() == QVariant::Bool);
335 QVERIFY(seriesSpyArg.at(1).toBool() == false);
338 QVERIFY(seriesSpyArg.at(1).toBool() == false);
336 }
339 }
337
340
341 void tst_QGroupedBarSeries::model()
342 {
343 QGroupedBarSeries *series = new QGroupedBarSeries;
344 QChart *chart = new QChart;
345 chart->addSeries(series);
346 QChartView *chartView = new QChartView(chart);
347 chartView->show();
348
349 int rowCount = 12;
350 int columnCount = 5;
351 QStandardItemModel *stdModel = new QStandardItemModel(rowCount, columnCount);
352 series->setModel(stdModel);
353 QVERIFY2((series->model()) == stdModel, "Model should be stdModel");
354
355
356 for (int row = 0; row < rowCount; ++row) {
357 for (int column = 0; column < columnCount; column++) {
358 QStandardItem *item = new QStandardItem(row * column);
359 stdModel->setItem(row, column, item);
360 }
361 }
362
363 // data has been added to the model, but mapper is not set the number of slices should still be 0
364 QVERIFY2(series->barsetCount() == 0, "Mapper has not been set, so the number of slices should be 0");
365
366 // set the mapper
367 QBarModelMapper *mapper = new QBarModelMapper;
368 mapper->setMapCategories(0);
369 mapper->setMapBarBottom(1);
370 mapper->setMapBarTop(3);
371 series->setModelMapper(mapper); // this should cause the Pie to get initialized from the model, since there is now both the model and the mapper defined
372 QCOMPARE(series->barsetCount(), 3);
373
374 // set the mappings to be outside of the model
375 mapper->setMapBarBottom(6);
376 mapper->setMapBarTop(7);
377 QCOMPARE(series->barsetCount(), 0); // Mappings are invalid, so the number of slices should be 0
378
379 // set back to correct ones
380 mapper->setMapBarBottom(1);
381 mapper->setMapBarTop(3);
382 QCOMPARE(series->barsetCount(), 3);
383
384 // reset the mappings
385 mapper->reset();
386 QCOMPARE(series->barsetCount(), 0); // Mappings have been reset and are invalid, so the number of slices should be 0
387
388 // unset the model and the mapper
389 series->setModel(0);
390 series->setModelMapper(0);
391 QVERIFY(series->model() == 0); // Model should be unset
392 QVERIFY(series->modelMapper() == 0); // Model mapper should be unset
393 }
338
394
339 /*
395 /*
340 bool setModel(QAbstractItemModel *model);
396 bool setModel(QAbstractItemModel *model);
341 void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical);
397 void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical);
342 void setModelMappingRange(int first, int count = -1);
398 void setModelMappingRange(int first, int count = -1);
343 */
399 */
344 QTEST_MAIN(tst_QGroupedBarSeries)
400 QTEST_MAIN(tst_QGroupedBarSeries)
345
401
346 #include "tst_qgroupedbarseries.moc"
402 #include "tst_qgroupedbarseries.moc"
347
403
@@ -1,477 +1,477
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include <QtTest/QtTest>
21 #include <QtTest/QtTest>
22 #include <qchartview.h>
22 #include <qchartview.h>
23 #include <qchart.h>
23 #include <qchart.h>
24 #include <qpieseries.h>
24 #include <qpieseries.h>
25 #include <qpieslice.h>
25 #include <qpieslice.h>
26 #include <qpiemodelmapper.h>
26 #include <qpiemodelmapper.h>
27 #include <QStandardItemModel>
27 #include <QStandardItemModel>
28 #include <tst_definitions.h>
28 #include <tst_definitions.h>
29
29
30 QTCOMMERCIALCHART_USE_NAMESPACE
30 QTCOMMERCIALCHART_USE_NAMESPACE
31
31
32 Q_DECLARE_METATYPE(QPieSlice*)
32 Q_DECLARE_METATYPE(QPieSlice*)
33
33
34 class tst_qpieseries : public QObject
34 class tst_qpieseries : public QObject
35 {
35 {
36 Q_OBJECT
36 Q_OBJECT
37
37
38 public slots:
38 public slots:
39 void initTestCase();
39 void initTestCase();
40 void cleanupTestCase();
40 void cleanupTestCase();
41 void init();
41 void init();
42 void cleanup();
42 void cleanup();
43
43
44 private slots:
44 private slots:
45 void construction();
45 void construction();
46 void append();
46 void append();
47 void insert();
47 void insert();
48 void remove();
48 void remove();
49 void calculatedValues();
49 void calculatedValues();
50 void clickedSignal();
50 void clickedSignal();
51 void hoverSignal();
51 void hoverSignal();
52 void model();
52 void model();
53 void modelCustomMap();
53 void modelCustomMap();
54 void modelUpdate();
54 void modelUpdate();
55
55
56 private:
56 private:
57 void verifyCalculatedData(const QPieSeries &series, bool *ok);
57 void verifyCalculatedData(const QPieSeries &series, bool *ok);
58
58
59 private:
59 private:
60
60
61 };
61 };
62
62
63 void tst_qpieseries::initTestCase()
63 void tst_qpieseries::initTestCase()
64 {
64 {
65 qRegisterMetaType<QPieSlice*>("QPieSlice*");
65 qRegisterMetaType<QPieSlice*>("QPieSlice*");
66 }
66 }
67
67
68 void tst_qpieseries::cleanupTestCase()
68 void tst_qpieseries::cleanupTestCase()
69 {
69 {
70 }
70 }
71
71
72 void tst_qpieseries::init()
72 void tst_qpieseries::init()
73 {
73 {
74
74
75 }
75 }
76
76
77 void tst_qpieseries::cleanup()
77 void tst_qpieseries::cleanup()
78 {
78 {
79
79
80 }
80 }
81
81
82 void tst_qpieseries::construction()
82 void tst_qpieseries::construction()
83 {
83 {
84 // verify default values
84 // verify default values
85 QPieSeries s;
85 QPieSeries s;
86 QVERIFY(s.type() == QAbstractSeries::SeriesTypePie);
86 QVERIFY(s.type() == QAbstractSeries::SeriesTypePie);
87 QVERIFY(s.count() == 0);
87 QVERIFY(s.count() == 0);
88 QVERIFY(s.isEmpty());
88 QVERIFY(s.isEmpty());
89 QCOMPARE(s.sum(), 0.0);
89 QCOMPARE(s.sum(), 0.0);
90 QCOMPARE(s.horizontalPosition(), 0.5);
90 QCOMPARE(s.horizontalPosition(), 0.5);
91 QCOMPARE(s.verticalPosition(), 0.5);
91 QCOMPARE(s.verticalPosition(), 0.5);
92 QCOMPARE(s.pieSize(), 0.7);
92 QCOMPARE(s.pieSize(), 0.7);
93 QCOMPARE(s.pieStartAngle(), 0.0);
93 QCOMPARE(s.pieStartAngle(), 0.0);
94 QCOMPARE(s.pieEndAngle(), 360.0);
94 QCOMPARE(s.pieEndAngle(), 360.0);
95 }
95 }
96
96
97 void tst_qpieseries::append()
97 void tst_qpieseries::append()
98 {
98 {
99 QPieSeries s;
99 QPieSeries s;
100
100
101 // append pointer
101 // append pointer
102 QPieSlice *slice1 = 0;
102 QPieSlice *slice1 = 0;
103 QVERIFY(!s.append(slice1));
103 QVERIFY(!s.append(slice1));
104 slice1 = new QPieSlice(1, "slice 1");
104 slice1 = new QPieSlice(1, "slice 1");
105 QVERIFY(s.append(slice1));
105 QVERIFY(s.append(slice1));
106 QVERIFY(!s.append(slice1));
106 QVERIFY(!s.append(slice1));
107 QCOMPARE(s.count(), 1);
107 QCOMPARE(s.count(), 1);
108
108
109 // append pointer list
109 // append pointer list
110 QList<QPieSlice *> list;
110 QList<QPieSlice *> list;
111 QVERIFY(!s.append(list));
111 QVERIFY(!s.append(list));
112 list << (QPieSlice *) 0;
112 list << (QPieSlice *) 0;
113 QVERIFY(!s.append(list));
113 QVERIFY(!s.append(list));
114 list.clear();
114 list.clear();
115 list << new QPieSlice(2, "slice 2");
115 list << new QPieSlice(2, "slice 2");
116 list << new QPieSlice(3, "slice 3");
116 list << new QPieSlice(3, "slice 3");
117 QVERIFY(s.append(list));
117 QVERIFY(s.append(list));
118 QVERIFY(!s.append(list));
118 QVERIFY(!s.append(list));
119 QCOMPARE(s.count(), 3);
119 QCOMPARE(s.count(), 3);
120
120
121 // append operator
121 // append operator
122 s << new QPieSlice(4, "slice 4");
122 s << new QPieSlice(4, "slice 4");
123 s << slice1; // fails because already added
123 s << slice1; // fails because already added
124 QCOMPARE(s.count(), 4);
124 QCOMPARE(s.count(), 4);
125
125
126 // append with params
126 // append with params
127 QPieSlice *slice5 = s.append(5, "slice 5");
127 QPieSlice *slice5 = s.append(5, "slice 5");
128 QVERIFY(slice5 != 0);
128 QVERIFY(slice5 != 0);
129 QCOMPARE(slice5->value(), 5.0);
129 QCOMPARE(slice5->value(), 5.0);
130 QCOMPARE(slice5->label(), QString("slice 5"));
130 QCOMPARE(slice5->label(), QString("slice 5"));
131 QCOMPARE(s.count(), 5);
131 QCOMPARE(s.count(), 5);
132
132
133 // check slices
133 // check slices
134 QVERIFY(!s.isEmpty());
134 QVERIFY(!s.isEmpty());
135 for (int i=0; i<s.count(); i++) {
135 for (int i=0; i<s.count(); i++) {
136 QCOMPARE(s.slices().at(i)->value(), (qreal) i+1);
136 QCOMPARE(s.slices().at(i)->value(), (qreal) i+1);
137 QCOMPARE(s.slices().at(i)->label(), QString("slice ") + QString::number(i+1));
137 QCOMPARE(s.slices().at(i)->label(), QString("slice ") + QString::number(i+1));
138 }
138 }
139 }
139 }
140
140
141 void tst_qpieseries::insert()
141 void tst_qpieseries::insert()
142 {
142 {
143 QPieSeries s;
143 QPieSeries s;
144
144
145 // insert one slice
145 // insert one slice
146 QPieSlice *slice1 = 0;
146 QPieSlice *slice1 = 0;
147 QVERIFY(!s.insert(0, slice1));
147 QVERIFY(!s.insert(0, slice1));
148 slice1 = new QPieSlice(1, "slice 1");
148 slice1 = new QPieSlice(1, "slice 1");
149 QVERIFY(!s.insert(-1, slice1));
149 QVERIFY(!s.insert(-1, slice1));
150 QVERIFY(!s.insert(5, slice1));
150 QVERIFY(!s.insert(5, slice1));
151 QVERIFY(s.insert(0, slice1));
151 QVERIFY(s.insert(0, slice1));
152 QVERIFY(!s.insert(0, slice1));
152 QVERIFY(!s.insert(0, slice1));
153 QCOMPARE(s.count(), 1);
153 QCOMPARE(s.count(), 1);
154
154
155 // add some more slices
155 // add some more slices
156 s.append(2, "slice 2");
156 s.append(2, "slice 2");
157 s.append(4, "slice 4");
157 s.append(4, "slice 4");
158 QCOMPARE(s.count(), 3);
158 QCOMPARE(s.count(), 3);
159
159
160 // insert between slices
160 // insert between slices
161 s.insert(2, new QPieSlice(3, "slice 3"));
161 s.insert(2, new QPieSlice(3, "slice 3"));
162 QCOMPARE(s.count(), 4);
162 QCOMPARE(s.count(), 4);
163
163
164 // check slices
164 // check slices
165 for (int i=0; i<s.count(); i++) {
165 for (int i=0; i<s.count(); i++) {
166 QCOMPARE(s.slices().at(i)->value(), (qreal) i+1);
166 QCOMPARE(s.slices().at(i)->value(), (qreal) i+1);
167 QCOMPARE(s.slices().at(i)->label(), QString("slice ") + QString::number(i+1));
167 QCOMPARE(s.slices().at(i)->label(), QString("slice ") + QString::number(i+1));
168 }
168 }
169 }
169 }
170
170
171 void tst_qpieseries::remove()
171 void tst_qpieseries::remove()
172 {
172 {
173 QPieSeries s;
173 QPieSeries s;
174
174
175 // add some slices
175 // add some slices
176 QPieSlice *slice1 = s.append(1, "slice 1");
176 QPieSlice *slice1 = s.append(1, "slice 1");
177 QPieSlice *slice2 = s.append(2, "slice 2");
177 QPieSlice *slice2 = s.append(2, "slice 2");
178 QPieSlice *slice3 = s.append(3, "slice 3");
178 QPieSlice *slice3 = s.append(3, "slice 3");
179 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
179 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
180 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
180 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
181 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
181 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
182 QCOMPARE(s.count(), 3);
182 QCOMPARE(s.count(), 3);
183
183
184 // null pointer remove
184 // null pointer remove
185 QVERIFY(!s.remove(0));
185 QVERIFY(!s.remove(0));
186
186
187 // remove first
187 // remove first
188 QVERIFY(s.remove(slice1));
188 QVERIFY(s.remove(slice1));
189 QVERIFY(!s.remove(slice1));
189 QVERIFY(!s.remove(slice1));
190 QCOMPARE(s.count(), 2);
190 QCOMPARE(s.count(), 2);
191 QCOMPARE(s.slices().at(0)->label(), slice2->label());
191 QCOMPARE(s.slices().at(0)->label(), slice2->label());
192
192
193 // remove all
193 // remove all
194 s.clear();
194 s.clear();
195 QVERIFY(s.isEmpty());
195 QVERIFY(s.isEmpty());
196 QVERIFY(s.slices().isEmpty());
196 QVERIFY(s.slices().isEmpty());
197 QCOMPARE(s.count(), 0);
197 QCOMPARE(s.count(), 0);
198
198
199 // check that slices were actually destroyed
199 // check that slices were actually destroyed
200 TRY_COMPARE(spy1.count(), 1);
200 TRY_COMPARE(spy1.count(), 1);
201 TRY_COMPARE(spy2.count(), 1);
201 TRY_COMPARE(spy2.count(), 1);
202 TRY_COMPARE(spy3.count(), 1);
202 TRY_COMPARE(spy3.count(), 1);
203 }
203 }
204
204
205 void tst_qpieseries::calculatedValues()
205 void tst_qpieseries::calculatedValues()
206 {
206 {
207 bool ok;
207 bool ok;
208 QPieSeries s;
208 QPieSeries s;
209
209
210 // add a slice
210 // add a slice
211 QPieSlice *slice1 = s.append(1, "slice 1");
211 QPieSlice *slice1 = s.append(1, "slice 1");
212 verifyCalculatedData(s, &ok);
212 verifyCalculatedData(s, &ok);
213 if (!ok)
213 if (!ok)
214 return;
214 return;
215
215
216 // add some more slices
216 // add some more slices
217 QList<QPieSlice *> list;
217 QList<QPieSlice *> list;
218 list << new QPieSlice(2, "slice 2");
218 list << new QPieSlice(2, "slice 2");
219 list << new QPieSlice(3, "slice 3");
219 list << new QPieSlice(3, "slice 3");
220 s.append(list);
220 s.append(list);
221 verifyCalculatedData(s, &ok);
221 verifyCalculatedData(s, &ok);
222 if (!ok)
222 if (!ok)
223 return;
223 return;
224
224
225 // remove a slice
225 // remove a slice
226 s.remove(slice1);
226 s.remove(slice1);
227 verifyCalculatedData(s, &ok);
227 verifyCalculatedData(s, &ok);
228 if (!ok)
228 if (!ok)
229 return;
229 return;
230
230
231 // insert a slice
231 // insert a slice
232 s.insert(0, new QPieSlice(1, "Slice 4"));
232 s.insert(0, new QPieSlice(1, "Slice 4"));
233 verifyCalculatedData(s, &ok);
233 verifyCalculatedData(s, &ok);
234 if (!ok)
234 if (!ok)
235 return;
235 return;
236
236
237 // clear all
237 // clear all
238 s.clear();
238 s.clear();
239 verifyCalculatedData(s, &ok);
239 verifyCalculatedData(s, &ok);
240 }
240 }
241
241
242 void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
242 void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
243 {
243 {
244 *ok = false;
244 *ok = false;
245
245
246 qreal sum = 0;
246 qreal sum = 0;
247 foreach (const QPieSlice *slice, series.slices())
247 foreach (const QPieSlice *slice, series.slices())
248 sum += slice->value();
248 sum += slice->value();
249 QCOMPARE(series.sum(), sum);
249 QCOMPARE(series.sum(), sum);
250
250
251 qreal startAngle = series.pieStartAngle();
251 qreal startAngle = series.pieStartAngle();
252 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
252 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
253 foreach (const QPieSlice *slice, series.slices()) {
253 foreach (const QPieSlice *slice, series.slices()) {
254 qreal ratio = slice->value() / sum;
254 qreal ratio = slice->value() / sum;
255 qreal sliceSpan = pieAngleSpan * ratio;
255 qreal sliceSpan = pieAngleSpan * ratio;
256 QCOMPARE(slice->startAngle(), startAngle);
256 QCOMPARE(slice->startAngle(), startAngle);
257 QCOMPARE(slice->endAngle(), startAngle + sliceSpan);
257 QCOMPARE(slice->endAngle(), startAngle + sliceSpan);
258 QCOMPARE(slice->percentage(), ratio);
258 QCOMPARE(slice->percentage(), ratio);
259 startAngle += sliceSpan;
259 startAngle += sliceSpan;
260 }
260 }
261
261
262 if (!series.isEmpty())
262 if (!series.isEmpty())
263 QCOMPARE(series.slices().last()->endAngle(), series.pieEndAngle());
263 QCOMPARE(series.slices().last()->endAngle(), series.pieEndAngle());
264
264
265 *ok = true;
265 *ok = true;
266 }
266 }
267
267
268
268
269 void tst_qpieseries::clickedSignal()
269 void tst_qpieseries::clickedSignal()
270 {
270 {
271 // create a pie series
271 // create a pie series
272 QPieSeries *series = new QPieSeries();
272 QPieSeries *series = new QPieSeries();
273 series->setPieSize(1.0);
273 series->setPieSize(1.0);
274 QPieSlice *s1 = series->append(1, "slice 1");
274 QPieSlice *s1 = series->append(1, "slice 1");
275 series->append(2, "slice 2");
275 series->append(2, "slice 2");
276 series->append(3, "slice 3");
276 series->append(3, "slice 3");
277 QSignalSpy clickSpy1(series, SIGNAL(clicked(QPieSlice*)));
277 QSignalSpy clickSpy1(series, SIGNAL(clicked(QPieSlice*)));
278
278
279 // add series to the chart
279 // add series to the chart
280 QChartView view(new QChart());
280 QChartView view(new QChart());
281 view.resize(200, 200);
281 view.resize(200, 200);
282 view.chart()->addSeries(series);
282 view.chart()->addSeries(series);
283 view.show();
283 view.show();
284 QTest::qWaitForWindowShown(&view);
284 QTest::qWaitForWindowShown(&view);
285
285
286 // simulate clicks
286 // simulate clicks
287 // pie rectangle: QRectF(60,60 121x121)
287 // pie rectangle: QRectF(60,60 121x121)
288 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(139, 85)); // inside slice 1
288 QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, QPoint(139, 85)); // inside slice 1
289 TRY_COMPARE(clickSpy1.count(), 1);
289 TRY_COMPARE(clickSpy1.count(), 1);
290 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy1.at(0).at(0)), s1);
290 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy1.at(0).at(0)), s1);
291 }
291 }
292
292
293 void tst_qpieseries::hoverSignal()
293 void tst_qpieseries::hoverSignal()
294 {
294 {
295 // create a pie series
295 // create a pie series
296 QPieSeries *series = new QPieSeries();
296 QPieSeries *series = new QPieSeries();
297 series->setPieSize(1.0);
297 series->setPieSize(1.0);
298 QPieSlice *s1 = series->append(1, "slice 1");
298 QPieSlice *s1 = series->append(1, "slice 1");
299 series->append(2, "slice 2");
299 series->append(2, "slice 2");
300 series->append(3, "slice 3");
300 series->append(3, "slice 3");
301
301
302 // add series to the chart
302 // add series to the chart
303 QChartView view(new QChart());
303 QChartView view(new QChart());
304 view.resize(200, 200);
304 view.resize(200, 200);
305 view.chart()->addSeries(series);
305 view.chart()->addSeries(series);
306 view.show();
306 view.show();
307 QTest::qWaitForWindowShown(&view);
307 QTest::qWaitForWindowShown(&view);
308
308
309 // first move to right top corner
309 // first move to right top corner
310 QTest::mouseMove(view.viewport(), QPoint(200, 0));
310 QTest::mouseMove(view.viewport(), QPoint(200, 0));
311 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
311 QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
312
312
313 // move inside the slice
313 // move inside the slice
314 // pie rectangle: QRectF(60,60 121x121)
314 // pie rectangle: QRectF(60,60 121x121)
315 QSignalSpy hoverSpy(series, SIGNAL(hovered(QPieSlice*,bool)));
315 QSignalSpy hoverSpy(series, SIGNAL(hovered(QPieSlice*,bool)));
316 QTest::mouseMove(view.viewport(), QPoint(139, 85));
316 QTest::mouseMove(view.viewport(), QPoint(139, 85));
317 TRY_COMPARE(hoverSpy.count(), 1);
317 TRY_COMPARE(hoverSpy.count(), 1);
318 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(0).at(0)), s1);
318 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(0).at(0)), s1);
319 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(0).at(1)), true);
319 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(0).at(1)), true);
320
320
321 // move outside the slice
321 // move outside the slice
322 QTest::mouseMove(view.viewport(), QPoint(200, 0));
322 QTest::mouseMove(view.viewport(), QPoint(200, 0));
323 TRY_COMPARE(hoverSpy.count(), 2);
323 TRY_COMPARE(hoverSpy.count(), 2);
324 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(1).at(0)), s1);
324 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(1).at(0)), s1);
325 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(1).at(1)), false);
325 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(1).at(1)), false);
326 }
326 }
327
327
328 void tst_qpieseries::model()
328 void tst_qpieseries::model()
329 {
329 {
330 QPieSeries *series = new QPieSeries;
330 QPieSeries *series = new QPieSeries;
331 QChart *chart = new QChart;
331 QChart *chart = new QChart;
332 chart->addSeries(series);
332 chart->addSeries(series);
333 QChartView *chartView = new QChartView(chart);
333 QChartView *chartView = new QChartView(chart);
334 chartView->show();
334 chartView->show();
335
335
336 QStandardItemModel *stdModel = new QStandardItemModel(0, 2);
336 QStandardItemModel *stdModel = new QStandardItemModel(0, 2);
337 series->setModel(stdModel);
337 series->setModel(stdModel);
338 QVERIFY2((series->model()) == stdModel, "Model should be stdModel");
338 QVERIFY2((series->model()) == stdModel, "Model should be stdModel");
339
339
340 int rowCount = 3;
340 int rowCount = 3;
341 for (int row = 0; row < rowCount; ++row) {
341 for (int row = 0; row < rowCount; ++row) {
342 for (int column = 0; column < 2; column++) {
342 for (int column = 0; column < 2; column++) {
343 QStandardItem *item = new QStandardItem(row * column);
343 QStandardItem *item = new QStandardItem(row * column);
344 stdModel->setItem(row, column, item);
344 stdModel->setItem(row, column, item);
345 }
345 }
346 }
346 }
347
347
348 // data has been added to the model, but mapper is not set the number of slices should still be 0
348 // data has been added to the model, but mapper is not set the number of slices should still be 0
349 QVERIFY2(series->slices().count() == 0, "Mapper has not been set, so the number of slices should be 0");
349 QVERIFY2(series->slices().count() == 0, "Mapper has not been set, so the number of slices should be 0");
350
350
351 // set the mapper
351 // set the mapper
352 QPieModelMapper *mapper = new QPieModelMapper;
352 QPieModelMapper *mapper = new QPieModelMapper;
353 mapper->setMapValues(0);
353 mapper->setMapValues(0);
354 mapper->setMapLabels(0);
354 mapper->setMapLabels(0);
355 series->setModelMapper(mapper); // this should cause the Pie to get initialized from the model, since there is now both the model and the mapper defined
355 series->setModelMapper(mapper); // this should cause the Pie to get initialized from the model, since there is now both the model and the mapper defined
356 QCOMPARE(series->slices().count(), rowCount);
356 QCOMPARE(series->slices().count(), rowCount);
357
357
358 // set the mappings to be outside of the model
358 // set the mappings to be outside of the model
359 mapper->setMapLabels(5);
359 mapper->setMapLabels(5);
360 mapper->setMapValues(4);
360 mapper->setMapValues(4);
361 QCOMPARE(series->slices().count(), 0); // Mappings are invalid, so the number of slices should be 0
361 QCOMPARE(series->slices().count(), 0); // Mappings are invalid, so the number of slices should be 0
362
362
363 // set back to correct ones
363 // set back to correct ones
364 mapper->setMapValues(0);
364 mapper->setMapValues(0);
365 mapper->setMapLabels(0);
365 mapper->setMapLabels(0);
366 QCOMPARE(series->slices().count(), rowCount);
366 QCOMPARE(series->slices().count(), rowCount);
367
367
368 // reset the mappings
368 // reset the mappings
369 mapper->reset();
369 mapper->reset();
370 QCOMPARE(series->slices().count(), 0); // Mappings have been reset and are invalid, so the number of slices should be 0
370 QCOMPARE(series->slices().count(), 0); // Mappings have been reset and are invalid, so the number of slices should be 0
371
371
372 // unset the model and the mapper
372 // unset the model and the mapper
373 series->setModel(0);
373 series->setModel(0);
374 series->setModelMapper(0);
374 series->setModelMapper(0);
375 QVERIFY(series->model() == 0); // Model should be unset
375 QVERIFY(series->model() == 0); // Model should be unset
376 QVERIFY(series->modelMapper() == 0); // Model mapper should be unset
376 QVERIFY(series->modelMapper() == 0); // Model mapper should be unset
377 }
377 }
378
378
379 void tst_qpieseries::modelCustomMap()
379 void tst_qpieseries::modelCustomMap()
380 {
380 {
381 int rowCount = 12;
381 int rowCount = 12;
382 int columnCount = 3;
382 int columnCount = 3;
383 QStandardItemModel *stdModel = new QStandardItemModel(0, 3);
383 QStandardItemModel *stdModel = new QStandardItemModel(0, 3);
384 for (int row = 0; row < rowCount; ++row) {
384 for (int row = 0; row < rowCount; ++row) {
385 for (int column = 0; column < 2; column++) {
385 for (int column = 0; column < 2; column++) {
386 QStandardItem *item = new QStandardItem(row * column);
386 QStandardItem *item = new QStandardItem(row * column);
387 stdModel->setItem(row, column, item);
387 stdModel->setItem(row, column, item);
388 }
388 }
389 }
389 }
390
390
391 QPieSeries *series = new QPieSeries;
391 QPieSeries *series = new QPieSeries;
392 QChart *chart = new QChart;
392 QChart *chart = new QChart;
393 chart->addSeries(series);
393 chart->addSeries(series);
394 QChartView *chartView = new QChartView(chart);
394 QChartView *chartView = new QChartView(chart);
395 chartView->show();
395 chartView->show();
396 series->setModel(stdModel);
396 series->setModel(stdModel);
397
397
398 QPieModelMapper *mapper = new QPieModelMapper;
398 QPieModelMapper *mapper = new QPieModelMapper;
399 mapper->setMapValues(0);
399 mapper->setMapValues(0);
400 mapper->setMapLabels(0);
400 mapper->setMapLabels(0);
401 series->setModelMapper(mapper);
401 series->setModelMapper(mapper);
402 QCOMPARE(series->slices().count(), rowCount);
402 QCOMPARE(series->slices().count(), rowCount);
403
403
404 // lets change the orientation to horizontal
404 // lets change the orientation to horizontal
405 mapper->setOrientation(Qt::Horizontal);
405 mapper->setOrientation(Qt::Horizontal);
406 QCOMPARE(series->slices().count(), columnCount);
406 QCOMPARE(series->slices().count(), columnCount);
407
407
408 // change it back to vertical
408 // change it back to vertical
409 mapper->setOrientation(Qt::Vertical);
409 mapper->setOrientation(Qt::Vertical);
410 QCOMPARE(series->slices().count(), rowCount);
410 QCOMPARE(series->slices().count(), rowCount);
411
411
412 // lets customize the mapping
412 // lets customize the mapping
413 int first = 3;
413 int first = 3;
414 mapper->setFirst(first);
414 mapper->setFirst(first);
415 QCOMPARE(series->slices().count(), rowCount - first);
415 QCOMPARE(series->slices().count(), rowCount - first);
416 int count = 7;
416 int count = 7;
417 mapper->setCount(count);
417 mapper->setCount(count);
418 QCOMPARE(series->slices().count(), count);
418 QCOMPARE(series->slices().count(), count);
419 first = 9;
419 first = 9;
420 mapper->setFirst(first);
420 mapper->setFirst(first);
421 QCOMPARE(series->slices().count(), qMin(count, rowCount - first));
421 QCOMPARE(series->slices().count(), qMin(count, rowCount - first));
422 }
422 }
423
423
424 void tst_qpieseries::modelUpdate()
424 void tst_qpieseries::modelUpdate()
425 {
425 {
426 int rowCount = 12;
426 int rowCount = 12;
427 int columnCount = 7;
427 int columnCount = 7;
428 QStandardItemModel *stdModel = new QStandardItemModel(0, 3);
428 QStandardItemModel *stdModel = new QStandardItemModel(rowCount, columnCount);
429 for (int row = 0; row < rowCount; ++row) {
429 for (int row = 0; row < rowCount; ++row) {
430 for (int column = 0; column < 2; column++) {
430 for (int column = 0; column < columnCount; column++) {
431 QStandardItem *item = new QStandardItem(row * column);
431 QStandardItem *item = new QStandardItem(row * column);
432 stdModel->setItem(row, column, item);
432 stdModel->setItem(row, column, item);
433 }
433 }
434 }
434 }
435
435
436 QPieSeries *series = new QPieSeries;
436 QPieSeries *series = new QPieSeries;
437 QChart *chart = new QChart;
437 QChart *chart = new QChart;
438 chart->addSeries(series);
438 chart->addSeries(series);
439 QChartView *chartView = new QChartView(chart);
439 QChartView *chartView = new QChartView(chart);
440 chartView->show();
440 chartView->show();
441 series->setModel(stdModel);
441 series->setModel(stdModel);
442
442
443 QPieModelMapper *mapper = new QPieModelMapper;
443 QPieModelMapper *mapper = new QPieModelMapper;
444 mapper->setMapValues(0);
444 mapper->setMapValues(0);
445 mapper->setMapLabels(0);
445 mapper->setMapLabels(0);
446 series->setModelMapper(mapper);
446 series->setModelMapper(mapper);
447
447
448 stdModel->insertRows(3, 5);
448 stdModel->insertRows(3, 5);
449 QCOMPARE(series->slices().count(), rowCount + 5);
449 QCOMPARE(series->slices().count(), rowCount + 5);
450
450
451 stdModel->removeRows(10, 5);
451 stdModel->removeRows(10, 5);
452 QCOMPARE(series->slices().count(), rowCount);
452 QCOMPARE(series->slices().count(), rowCount);
453
453
454 // limit the number of slices taken from the model to 12
454 // limit the number of slices taken from the model to 12
455 mapper->setCount(rowCount);
455 mapper->setCount(rowCount);
456 stdModel->insertRows(3, 5);
456 stdModel->insertRows(3, 5);
457 QCOMPARE(series->slices().count(), rowCount);
457 QCOMPARE(series->slices().count(), rowCount);
458
458
459 stdModel->removeRows(0, 10);
459 stdModel->removeRows(0, 10);
460 QCOMPARE(series->slices().count(), rowCount - 5);
460 QCOMPARE(series->slices().count(), rowCount - 5);
461
461
462 // change the orientation to horizontal
462 // change the orientation to horizontal
463 mapper->setOrientation(Qt::Horizontal);
463 mapper->setOrientation(Qt::Horizontal);
464 QCOMPARE(series->slices().count(), columnCount);
464 QCOMPARE(series->slices().count(), columnCount);
465
465
466 stdModel->insertColumns(3, 10);
466 stdModel->insertColumns(3, 10);
467 QCOMPARE(series->slices().count(), rowCount); // count is limited to rowCount (12)
467 QCOMPARE(series->slices().count(), rowCount); // count is limited to rowCount (12)
468
468
469 stdModel->removeColumns(5, 10);
469 stdModel->removeColumns(5, 10);
470 QCOMPARE(series->slices().count(), columnCount);
470 QCOMPARE(series->slices().count(), columnCount);
471
471
472 }
472 }
473
473
474 QTEST_MAIN(tst_qpieseries)
474 QTEST_MAIN(tst_qpieseries)
475
475
476 #include "tst_qpieseries.moc"
476 #include "tst_qpieseries.moc"
477
477
General Comments 0
You need to be logged in to leave comments. Login now