##// END OF EJS Templates
Prevent double adding slice pointer to series with Q_ASSERT
Jani Honkonen -
r1092:f123347f2951
parent child
Show More
@@ -1,789 +1,791
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
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 /*!
33 /*!
34 \class QPieSeries
34 \class QPieSeries
35 \brief Pie series API for QtCommercial Charts
35 \brief Pie series API for QtCommercial Charts
36
36
37 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
37 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
38 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 The actual slice size is determined by that relative value.
39 The actual slice size is determined by that relative value.
40
40
41 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
41 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 These relate to the actual chart rectangle.
42 These relate to the actual chart rectangle.
43
43
44 By default the pie is defined as a full pie but it can also be a partial pie.
44 By default the pie is defined as a full pie but it can also be a partial pie.
45 This can be done by setting a starting angle and angle span to the series.
45 This can be done by setting a starting angle and angle span to the series.
46 Full pie is 360 degrees where 0 is at 12 a'clock.
46 Full pie is 360 degrees where 0 is at 12 a'clock.
47
47
48 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
48 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
49 \image examples_piechart.png
49 \image examples_piechart.png
50 */
50 */
51
51
52 /*!
52 /*!
53 \property QPieSeries::horizontalPosition
53 \property QPieSeries::horizontalPosition
54 \brief Defines the horizontal position of the pie.
54 \brief Defines the horizontal position of the pie.
55
55
56 The value is a relative value to the chart rectangle where:
56 The value is a relative value to the chart rectangle where:
57
57
58 \list
58 \list
59 \o 0.0 is the absolute left.
59 \o 0.0 is the absolute left.
60 \o 1.0 is the absolute right.
60 \o 1.0 is the absolute right.
61 \endlist
61 \endlist
62
62
63 Default value is 0.5 (center).
63 Default value is 0.5 (center).
64 */
64 */
65
65
66 /*!
66 /*!
67 \property QPieSeries::verticalPosition
67 \property QPieSeries::verticalPosition
68 \brief Defines the vertical position of the pie.
68 \brief Defines the vertical position of the pie.
69
69
70 The value is a relative value to the chart rectangle where:
70 The value is a relative value to the chart rectangle where:
71
71
72 \list
72 \list
73 \o 0.0 is the absolute top.
73 \o 0.0 is the absolute top.
74 \o 1.0 is the absolute bottom.
74 \o 1.0 is the absolute bottom.
75 \endlist
75 \endlist
76
76
77 Default value is 0.5 (center).
77 Default value is 0.5 (center).
78 */
78 */
79
79
80 /*!
80 /*!
81 \property QPieSeries::size
81 \property QPieSeries::size
82 \brief Defines the pie size.
82 \brief Defines the pie size.
83
83
84 The value is a relative value to the chart rectangle where:
84 The value is a relative value to the chart rectangle where:
85
85
86 \list
86 \list
87 \o 0.0 is the minimum size (pie not drawn).
87 \o 0.0 is the minimum size (pie not drawn).
88 \o 1.0 is the maximum size that can fit the chart.
88 \o 1.0 is the maximum size that can fit the chart.
89 \endlist
89 \endlist
90
90
91 Default value is 0.7.
91 Default value is 0.7.
92 */
92 */
93
93
94 /*!
94 /*!
95 \property QPieSeries::startAngle
95 \property QPieSeries::startAngle
96 \brief Defines the starting angle of the pie.
96 \brief Defines the starting angle of the pie.
97
97
98 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
98 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
99
99
100 Default is value is 0.
100 Default is value is 0.
101 */
101 */
102
102
103 /*!
103 /*!
104 \property QPieSeries::endAngle
104 \property QPieSeries::endAngle
105 \brief Defines the ending angle of the pie.
105 \brief Defines the ending angle of the pie.
106
106
107 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
107 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
108
108
109 Default is value is 360.
109 Default is value is 360.
110 */
110 */
111
111
112
112
113 /*!
113 /*!
114 Constructs a series object which is a child of \a parent.
114 Constructs a series object which is a child of \a parent.
115 */
115 */
116 QPieSeries::QPieSeries(QObject *parent) :
116 QPieSeries::QPieSeries(QObject *parent) :
117 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
117 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
118 {
118 {
119
119
120 }
120 }
121
121
122 /*!
122 /*!
123 Destroys the series and its slices.
123 Destroys the series and its slices.
124 */
124 */
125 QPieSeries::~QPieSeries()
125 QPieSeries::~QPieSeries()
126 {
126 {
127 // NOTE: d_prt destroyed by QObject
127 // NOTE: d_prt destroyed by QObject
128 }
128 }
129
129
130 /*!
130 /*!
131 Returns QChartSeries::SeriesTypePie.
131 Returns QChartSeries::SeriesTypePie.
132 */
132 */
133 QAbstractSeries::QSeriesType QPieSeries::type() const
133 QAbstractSeries::QSeriesType QPieSeries::type() const
134 {
134 {
135 return QAbstractSeries::SeriesTypePie;
135 return QAbstractSeries::SeriesTypePie;
136 }
136 }
137
137
138 /*!
138 /*!
139 Appends an array of \a slices to the series.
139 Appends an array of \a slices to the series.
140 Slice ownership is passed to the series.
140 Slice ownership is passed to the series.
141 */
141 */
142 void QPieSeries::append(QList<QPieSlice*> slices)
142 void QPieSeries::append(QList<QPieSlice*> slices)
143 {
143 {
144 Q_D(QPieSeries);
144 Q_D(QPieSeries);
145
145
146 foreach (QPieSlice* s, slices) {
146 foreach (QPieSlice* s, slices) {
147 Q_ASSERT(!d->m_slices.contains(s)); // cannot add same slice twice
147 s->setParent(this);
148 s->setParent(this);
148 d->m_slices << s;
149 d->m_slices << s;
149 }
150 }
150
151
151 d->updateDerivativeData();
152 d->updateDerivativeData();
152
153
153 foreach (QPieSlice* s, slices) {
154 foreach (QPieSlice* s, slices) {
154 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
155 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
155 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
156 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
156 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
157 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
157 }
158 }
158
159
159 emit d->added(slices);
160 emit d->added(slices);
160 }
161 }
161
162
162 /*!
163 /*!
163 Appends a single \a slice to the series.
164 Appends a single \a slice to the series.
164 Slice ownership is passed to the series.
165 Slice ownership is passed to the series.
165 */
166 */
166 void QPieSeries::append(QPieSlice* slice)
167 void QPieSeries::append(QPieSlice* slice)
167 {
168 {
168 append(QList<QPieSlice*>() << slice);
169 append(QList<QPieSlice*>() << slice);
169 }
170 }
170
171
171 /*!
172 /*!
172 Appends a single \a slice to the series and returns a reference to the series.
173 Appends a single \a slice to the series and returns a reference to the series.
173 Slice ownership is passed to the series.
174 Slice ownership is passed to the series.
174 */
175 */
175 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
176 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
176 {
177 {
177 append(slice);
178 append(slice);
178 return *this;
179 return *this;
179 }
180 }
180
181
181
182
182 /*!
183 /*!
183 Appends a single slice to the series with give \a value and \a name.
184 Appends a single slice to the series with give \a value and \a name.
184 Slice ownership is passed to the series.
185 Slice ownership is passed to the series.
185 */
186 */
186 QPieSlice* QPieSeries::append(qreal value, QString name)
187 QPieSlice* QPieSeries::append(qreal value, QString name)
187 {
188 {
188 QPieSlice* slice = new QPieSlice(value, name);
189 QPieSlice* slice = new QPieSlice(value, name);
189 append(slice);
190 append(slice);
190 return slice;
191 return slice;
191 }
192 }
192
193
193 /*!
194 /*!
194 Inserts a single \a slice to the series before the slice at \a index position.
195 Inserts a single \a slice to the series before the slice at \a index position.
195 Slice ownership is passed to the series.
196 Slice ownership is passed to the series.
196 */
197 */
197 void QPieSeries::insert(int index, QPieSlice* slice)
198 void QPieSeries::insert(int index, QPieSlice* slice)
198 {
199 {
199 Q_D(QPieSeries);
200 Q_D(QPieSeries);
200 Q_ASSERT(index <= d->m_slices.count());
201 Q_ASSERT(index <= d->m_slices.count());
202 Q_ASSERT(!d->m_slices.contains(slice)); // cannot add same slice twice
201 slice->setParent(this);
203 slice->setParent(this);
202 d->m_slices.insert(index, slice);
204 d->m_slices.insert(index, slice);
203
205
204 d->updateDerivativeData();
206 d->updateDerivativeData();
205
207
206 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
208 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
207 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
209 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
208 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
210 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
209
211
210 emit d->added(QList<QPieSlice*>() << slice);
212 emit d->added(QList<QPieSlice*>() << slice);
211 }
213 }
212
214
213 /*!
215 /*!
214 Removes a single \a slice from the series and deletes the slice.
216 Removes a single \a slice from the series and deletes the slice.
215
217
216 Do not reference the pointer after this call.
218 Do not reference the pointer after this call.
217 */
219 */
218 void QPieSeries::remove(QPieSlice* slice)
220 void QPieSeries::remove(QPieSlice* slice)
219 {
221 {
220 Q_D(QPieSeries);
222 Q_D(QPieSeries);
221 if (!d->m_slices.removeOne(slice)) {
223 if (!d->m_slices.removeOne(slice)) {
222 Q_ASSERT(0); // TODO: how should this be reported?
224 Q_ASSERT(0); // TODO: how should this be reported?
223 return;
225 return;
224 }
226 }
225
227
226 d->updateDerivativeData();
228 d->updateDerivativeData();
227
229
228 emit d->removed(QList<QPieSlice*>() << slice);
230 emit d->removed(QList<QPieSlice*>() << slice);
229
231
230 delete slice;
232 delete slice;
231 slice = 0;
233 slice = 0;
232 }
234 }
233
235
234 /*!
236 /*!
235 Clears all slices from the series.
237 Clears all slices from the series.
236 */
238 */
237 void QPieSeries::clear()
239 void QPieSeries::clear()
238 {
240 {
239 Q_D(QPieSeries);
241 Q_D(QPieSeries);
240 if (d->m_slices.count() == 0)
242 if (d->m_slices.count() == 0)
241 return;
243 return;
242
244
243 QList<QPieSlice*> slices = d->m_slices;
245 QList<QPieSlice*> slices = d->m_slices;
244 foreach (QPieSlice* s, d->m_slices) {
246 foreach (QPieSlice* s, d->m_slices) {
245 d->m_slices.removeOne(s);
247 d->m_slices.removeOne(s);
246 delete s;
248 delete s;
247 }
249 }
248
250
249 d->updateDerivativeData();
251 d->updateDerivativeData();
250
252
251 emit d->removed(slices);
253 emit d->removed(slices);
252 }
254 }
253
255
254 /*!
256 /*!
255 returns the number of the slices in this series.
257 returns the number of the slices in this series.
256 */
258 */
257 int QPieSeries::count() const
259 int QPieSeries::count() const
258 {
260 {
259 Q_D(const QPieSeries);
261 Q_D(const QPieSeries);
260 return d->m_slices.count();
262 return d->m_slices.count();
261 }
263 }
262
264
263 /*!
265 /*!
264 Returns true is the series is empty.
266 Returns true is the series is empty.
265 */
267 */
266 bool QPieSeries::isEmpty() const
268 bool QPieSeries::isEmpty() const
267 {
269 {
268 Q_D(const QPieSeries);
270 Q_D(const QPieSeries);
269 return d->m_slices.isEmpty();
271 return d->m_slices.isEmpty();
270 }
272 }
271
273
272 /*!
274 /*!
273 Returns a list of slices that belong to this series.
275 Returns a list of slices that belong to this series.
274 */
276 */
275 QList<QPieSlice*> QPieSeries::slices() const
277 QList<QPieSlice*> QPieSeries::slices() const
276 {
278 {
277 Q_D(const QPieSeries);
279 Q_D(const QPieSeries);
278 return d->m_slices;
280 return d->m_slices;
279 }
281 }
280
282
281 void QPieSeries::setHorizontalPosition(qreal relativePosition)
283 void QPieSeries::setHorizontalPosition(qreal relativePosition)
282 {
284 {
283 Q_D(QPieSeries);
285 Q_D(QPieSeries);
284 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
286 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
285 emit d->piePositionChanged();
287 emit d->piePositionChanged();
286 }
288 }
287
289
288 void QPieSeries::setVerticalPosition(qreal relativePosition)
290 void QPieSeries::setVerticalPosition(qreal relativePosition)
289 {
291 {
290 Q_D(QPieSeries);
292 Q_D(QPieSeries);
291 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
293 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
292 emit d->piePositionChanged();
294 emit d->piePositionChanged();
293 }
295 }
294
296
295 qreal QPieSeries::horizontalPosition() const
297 qreal QPieSeries::horizontalPosition() const
296 {
298 {
297 Q_D(const QPieSeries);
299 Q_D(const QPieSeries);
298 return d->m_pieRelativeHorPos;
300 return d->m_pieRelativeHorPos;
299 }
301 }
300
302
301 qreal QPieSeries::verticalPosition() const
303 qreal QPieSeries::verticalPosition() const
302 {
304 {
303 Q_D(const QPieSeries);
305 Q_D(const QPieSeries);
304 return d->m_pieRelativeVerPos;
306 return d->m_pieRelativeVerPos;
305 }
307 }
306
308
307 void QPieSeries::setPieSize(qreal relativeSize)
309 void QPieSeries::setPieSize(qreal relativeSize)
308 {
310 {
309 Q_D(QPieSeries);
311 Q_D(QPieSeries);
310 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
312 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
311 emit d->pieSizeChanged();
313 emit d->pieSizeChanged();
312 }
314 }
313
315
314 qreal QPieSeries::pieSize() const
316 qreal QPieSeries::pieSize() const
315 {
317 {
316 Q_D(const QPieSeries);
318 Q_D(const QPieSeries);
317 return d->m_pieRelativeSize;
319 return d->m_pieRelativeSize;
318 }
320 }
319
321
320
322
321 void QPieSeries::setPieStartAngle(qreal angle)
323 void QPieSeries::setPieStartAngle(qreal angle)
322 {
324 {
323 Q_D(QPieSeries);
325 Q_D(QPieSeries);
324 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
326 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
325 d->updateDerivativeData();
327 d->updateDerivativeData();
326 }
328 }
327
329
328 qreal QPieSeries::pieStartAngle() const
330 qreal QPieSeries::pieStartAngle() const
329 {
331 {
330 Q_D(const QPieSeries);
332 Q_D(const QPieSeries);
331 return d->m_pieStartAngle;
333 return d->m_pieStartAngle;
332 }
334 }
333
335
334 /*!
336 /*!
335 Sets the end angle of the pie.
337 Sets the end angle of the pie.
336
338
337 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
339 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
338
340
339 \a angle must be greater than start angle.
341 \a angle must be greater than start angle.
340
342
341 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
343 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
342 */
344 */
343 void QPieSeries::setPieEndAngle(qreal angle)
345 void QPieSeries::setPieEndAngle(qreal angle)
344 {
346 {
345 Q_D(QPieSeries);
347 Q_D(QPieSeries);
346
348
347 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
349 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
348 d->updateDerivativeData();
350 d->updateDerivativeData();
349 }
351 }
350
352
351 /*!
353 /*!
352 Returns the end angle of the pie.
354 Returns the end angle of the pie.
353
355
354 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
356 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
355
357
356 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
358 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
357 */
359 */
358 qreal QPieSeries::pieEndAngle() const
360 qreal QPieSeries::pieEndAngle() const
359 {
361 {
360 Q_D(const QPieSeries);
362 Q_D(const QPieSeries);
361 return d->m_pieEndAngle;
363 return d->m_pieEndAngle;
362 }
364 }
363
365
364 /*!
366 /*!
365 Sets the all the slice labels \a visible or invisible.
367 Sets the all the slice labels \a visible or invisible.
366
368
367 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
369 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
368 */
370 */
369 void QPieSeries::setLabelsVisible(bool visible)
371 void QPieSeries::setLabelsVisible(bool visible)
370 {
372 {
371 Q_D(QPieSeries);
373 Q_D(QPieSeries);
372 foreach (QPieSlice* s, d->m_slices)
374 foreach (QPieSlice* s, d->m_slices)
373 s->setLabelVisible(visible);
375 s->setLabelVisible(visible);
374 }
376 }
375
377
376 /*!
378 /*!
377 Returns the sum of all slice values in this series.
379 Returns the sum of all slice values in this series.
378
380
379 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
381 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
380 */
382 */
381 qreal QPieSeries::sum() const
383 qreal QPieSeries::sum() const
382 {
384 {
383 Q_D(const QPieSeries);
385 Q_D(const QPieSeries);
384 return d->m_sum;
386 return d->m_sum;
385 }
387 }
386
388
387 /*!
389 /*!
388 \fn void QPieSeries::clicked(QPieSlice* slice)
390 \fn void QPieSeries::clicked(QPieSlice* slice)
389
391
390 This signal is emitted when a \a slice has been clicked.
392 This signal is emitted when a \a slice has been clicked.
391
393
392 \sa QPieSlice::clicked()
394 \sa QPieSlice::clicked()
393 */
395 */
394
396
395 /*!
397 /*!
396 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
398 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
397
399
398 This signal is emitted when user has hovered over or away from the \a slice.
400 This signal is emitted when user has hovered over or away from the \a slice.
399
401
400 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
402 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
401
403
402 \sa QPieSlice::hovered()
404 \sa QPieSlice::hovered()
403 */
405 */
404
406
405 /*!
407 /*!
406 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
408 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
407 Sets the \a model to be used as a data source
409 Sets the \a model to be used as a data source
408 */
410 */
409 bool QPieSeries::setModel(QAbstractItemModel* model)
411 bool QPieSeries::setModel(QAbstractItemModel* model)
410 {
412 {
411 Q_D(QPieSeries);
413 Q_D(QPieSeries);
412 // disconnect signals from old model
414 // disconnect signals from old model
413 if(d->m_model)
415 if(d->m_model)
414 {
416 {
415 disconnect(d->m_model, 0, this, 0);
417 disconnect(d->m_model, 0, this, 0);
416 d->m_mapValues = -1;
418 d->m_mapValues = -1;
417 d->m_mapLabels = -1;
419 d->m_mapLabels = -1;
418 d->m_mapOrientation = Qt::Vertical;
420 d->m_mapOrientation = Qt::Vertical;
419 }
421 }
420
422
421 // set new model
423 // set new model
422 if(model)
424 if(model)
423 {
425 {
424 d->m_model = model;
426 d->m_model = model;
425 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
427 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
426 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
428 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
427 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
429 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
428 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
430 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
429 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
431 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
430 return true;
432 return true;
431 }
433 }
432 else
434 else
433 {
435 {
434 d->m_model = 0;
436 d->m_model = 0;
435 return false;
437 return false;
436 }
438 }
437 }
439 }
438
440
439 /*!
441 /*!
440 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
442 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
441 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
443 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
442 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
444 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
443 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
445 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
444 The \a orientation parameter specifies whether the data is in columns or in rows.
446 The \a orientation parameter specifies whether the data is in columns or in rows.
445 */
447 */
446 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
448 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
447 {
449 {
448 Q_D(QPieSeries);
450 Q_D(QPieSeries);
449
451
450 if (d->m_model == 0)
452 if (d->m_model == 0)
451 return;
453 return;
452
454
453 d->m_mapValues = modelValuesLine;
455 d->m_mapValues = modelValuesLine;
454 d->m_mapLabels = modelLabelsLine;
456 d->m_mapLabels = modelLabelsLine;
455 d->m_mapOrientation = orientation;
457 d->m_mapOrientation = orientation;
456
458
457 d->initializePieFromModel();
459 d->initializePieFromModel();
458 // // connect the signals
460 // // connect the signals
459 // connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
461 // connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
460
462
461
463
462 // // create the initial slices set
464 // // create the initial slices set
463 // if (d->m_mapOrientation == Qt::Vertical) {
465 // if (d->m_mapOrientation == Qt::Vertical) {
464 // for (int i = 0; i < d->m_model->rowCount(); i++)
466 // for (int i = 0; i < d->m_model->rowCount(); i++)
465 // append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
467 // append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
466 // } else {
468 // } else {
467 // for (int i = 0; i < d->m_model->columnCount(); i++)
469 // for (int i = 0; i < d->m_model->columnCount(); i++)
468 // append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
470 // append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
469 // }
471 // }
470 }
472 }
471
473
472 void QPieSeries::setModelMappingRange(int first, int count)
474 void QPieSeries::setModelMappingRange(int first, int count)
473 {
475 {
474 Q_D(QPieSeries);
476 Q_D(QPieSeries);
475 d->m_mapFirst = first;
477 d->m_mapFirst = first;
476 d->m_mapCount = count;
478 d->m_mapCount = count;
477 }
479 }
478
480
479 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
481 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
480
482
481
483
482 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
484 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
483 QAbstractSeriesPrivate(parent),
485 QAbstractSeriesPrivate(parent),
484 m_pieRelativeHorPos(0.5),
486 m_pieRelativeHorPos(0.5),
485 m_pieRelativeVerPos(0.5),
487 m_pieRelativeVerPos(0.5),
486 m_pieRelativeSize(0.7),
488 m_pieRelativeSize(0.7),
487 m_pieStartAngle(0),
489 m_pieStartAngle(0),
488 m_pieEndAngle(360),
490 m_pieEndAngle(360),
489 m_sum(0),
491 m_sum(0),
490 m_mapValues(0),
492 m_mapValues(0),
491 m_mapLabels(0)
493 m_mapLabels(0)
492 {
494 {
493
495
494 }
496 }
495
497
496 QPieSeriesPrivate::~QPieSeriesPrivate()
498 QPieSeriesPrivate::~QPieSeriesPrivate()
497 {
499 {
498
500
499 }
501 }
500
502
501 void QPieSeriesPrivate::updateDerivativeData()
503 void QPieSeriesPrivate::updateDerivativeData()
502 {
504 {
503 m_sum = 0;
505 m_sum = 0;
504
506
505 // nothing to do?
507 // nothing to do?
506 if (m_slices.count() == 0)
508 if (m_slices.count() == 0)
507 return;
509 return;
508
510
509 // calculate sum of all slices
511 // calculate sum of all slices
510 foreach (QPieSlice* s, m_slices)
512 foreach (QPieSlice* s, m_slices)
511 m_sum += s->value();
513 m_sum += s->value();
512
514
513 // nothing to show..
515 // nothing to show..
514 if (qFuzzyIsNull(m_sum))
516 if (qFuzzyIsNull(m_sum))
515 return;
517 return;
516
518
517 // update slice attributes
519 // update slice attributes
518 qreal sliceAngle = m_pieStartAngle;
520 qreal sliceAngle = m_pieStartAngle;
519 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
521 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
520 QVector<QPieSlice*> changed;
522 QVector<QPieSlice*> changed;
521 foreach (QPieSlice* s, m_slices) {
523 foreach (QPieSlice* s, m_slices) {
522
524
523 PieSliceData data = PieSliceData::data(s);
525 PieSliceData data = PieSliceData::data(s);
524 data.m_percentage = s->value() / m_sum;
526 data.m_percentage = s->value() / m_sum;
525 data.m_angleSpan = pieSpan * data.m_percentage;
527 data.m_angleSpan = pieSpan * data.m_percentage;
526 data.m_startAngle = sliceAngle;
528 data.m_startAngle = sliceAngle;
527 sliceAngle += data.m_angleSpan;
529 sliceAngle += data.m_angleSpan;
528
530
529 if (PieSliceData::data(s) != data) {
531 if (PieSliceData::data(s) != data) {
530 PieSliceData::data(s) = data;
532 PieSliceData::data(s) = data;
531 changed << s;
533 changed << s;
532 }
534 }
533 }
535 }
534
536
535 // emit signals
537 // emit signals
536 foreach (QPieSlice* s, changed)
538 foreach (QPieSlice* s, changed)
537 PieSliceData::data(s).emitChangedSignal(s);
539 PieSliceData::data(s).emitChangedSignal(s);
538 }
540 }
539
541
540 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
542 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
541 {
543 {
542 return series.d_func();
544 return series.d_func();
543 }
545 }
544
546
545 void QPieSeriesPrivate::sliceChanged()
547 void QPieSeriesPrivate::sliceChanged()
546 {
548 {
547 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
549 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
548 updateDerivativeData();
550 updateDerivativeData();
549 }
551 }
550
552
551 void QPieSeriesPrivate::sliceClicked()
553 void QPieSeriesPrivate::sliceClicked()
552 {
554 {
553 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
555 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
554 Q_ASSERT(m_slices.contains(slice));
556 Q_ASSERT(m_slices.contains(slice));
555 Q_Q(QPieSeries);
557 Q_Q(QPieSeries);
556 emit q->clicked(slice);
558 emit q->clicked(slice);
557 }
559 }
558
560
559 void QPieSeriesPrivate::sliceHovered(bool state)
561 void QPieSeriesPrivate::sliceHovered(bool state)
560 {
562 {
561 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
563 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
562 Q_ASSERT(m_slices.contains(slice));
564 Q_ASSERT(m_slices.contains(slice));
563 Q_Q(QPieSeries);
565 Q_Q(QPieSeries);
564 emit q->hovered(slice, state);
566 emit q->hovered(slice, state);
565 }
567 }
566
568
567 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
569 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
568 {
570 {
569 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
571 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
570 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
572 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
571 if (m_mapOrientation == Qt::Vertical)
573 if (m_mapOrientation == Qt::Vertical)
572 {
574 {
573 if ( topLeft.row() >= m_mapFirst && (m_mapCount == - 1 || topLeft.row() < m_mapFirst + m_mapCount)) {
575 if ( topLeft.row() >= m_mapFirst && (m_mapCount == - 1 || topLeft.row() < m_mapFirst + m_mapCount)) {
574 if (topLeft.column() == m_mapValues)
576 if (topLeft.column() == m_mapValues)
575 m_slices.at(topLeft.row() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
577 m_slices.at(topLeft.row() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
576 if (topLeft.column() == m_mapLabels)
578 if (topLeft.column() == m_mapLabels)
577 m_slices.at(topLeft.row() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
579 m_slices.at(topLeft.row() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
578 }
580 }
579 }
581 }
580 else
582 else
581 {
583 {
582 if (topLeft.column() >= m_mapFirst && (m_mapCount == - 1 || topLeft.column() < m_mapFirst + m_mapCount)) {
584 if (topLeft.column() >= m_mapFirst && (m_mapCount == - 1 || topLeft.column() < m_mapFirst + m_mapCount)) {
583 if (topLeft.row() == m_mapValues)
585 if (topLeft.row() == m_mapValues)
584 m_slices.at(topLeft.column() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
586 m_slices.at(topLeft.column() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
585 if (topLeft.row() == m_mapLabels)
587 if (topLeft.row() == m_mapLabels)
586 m_slices.at(topLeft.column() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
588 m_slices.at(topLeft.column() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
587 }
589 }
588 }
590 }
589 }
591 }
590 }
592 }
591 }
593 }
592
594
593
595
594 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
596 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
595 {
597 {
596 Q_UNUSED(parent);
598 Q_UNUSED(parent);
597 if (m_mapOrientation == Qt::Vertical)
599 if (m_mapOrientation == Qt::Vertical)
598 insertData(start, end);
600 insertData(start, end);
599 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
601 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
600 initializePieFromModel();
602 initializePieFromModel();
601 }
603 }
602
604
603 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
605 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
604 {
606 {
605 Q_UNUSED(parent);
607 Q_UNUSED(parent);
606 if (m_mapOrientation == Qt::Vertical)
608 if (m_mapOrientation == Qt::Vertical)
607 removeData(start, end);
609 removeData(start, end);
608 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
610 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
609 initializePieFromModel();
611 initializePieFromModel();
610 }
612 }
611
613
612 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
614 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
613 {
615 {
614 Q_UNUSED(parent);
616 Q_UNUSED(parent);
615 if (m_mapOrientation == Qt::Horizontal)
617 if (m_mapOrientation == Qt::Horizontal)
616 insertData(start, end);
618 insertData(start, end);
617 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
619 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
618 initializePieFromModel();
620 initializePieFromModel();
619 }
621 }
620
622
621 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
623 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
622 {
624 {
623 Q_UNUSED(parent);
625 Q_UNUSED(parent);
624 if (m_mapOrientation == Qt::Horizontal)
626 if (m_mapOrientation == Qt::Horizontal)
625 removeData(start, end);
627 removeData(start, end);
626 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
628 else if (start <= m_mapValues || start <= m_mapLabels) // if the changes affect the map - reinitialize the pie
627 initializePieFromModel();
629 initializePieFromModel();
628 }
630 }
629
631
630 void QPieSeriesPrivate::insertData(int start, int end)
632 void QPieSeriesPrivate::insertData(int start, int end)
631 {
633 {
632 Q_Q(QPieSeries);
634 Q_Q(QPieSeries);
633 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
635 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
634 return;
636 return;
635 } else {
637 } else {
636 int addedCount = end - start + 1;
638 int addedCount = end - start + 1;
637 if (m_mapCount != -1 && addedCount > m_mapCount)
639 if (m_mapCount != -1 && addedCount > m_mapCount)
638 addedCount = m_mapCount;
640 addedCount = m_mapCount;
639 int first = qMax(start, m_mapFirst);
641 int first = qMax(start, m_mapFirst);
640 int last = qMin(first + addedCount - 1, m_mapOrientation == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
642 int last = qMin(first + addedCount - 1, m_mapOrientation == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
641 for (int i = first; i <= last; i++) {
643 for (int i = first; i <= last; i++) {
642 QPieSlice *slice = new QPieSlice;
644 QPieSlice *slice = new QPieSlice;
643 if (m_mapOrientation == Qt::Vertical) {
645 if (m_mapOrientation == Qt::Vertical) {
644 slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
646 slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
645 slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
647 slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
646 } else {
648 } else {
647 slice->setValue(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble());
649 slice->setValue(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble());
648 slice->setLabel(m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
650 slice->setLabel(m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
649 }
651 }
650 slice->setLabelVisible();
652 slice->setLabelVisible();
651 q->insert(i - m_mapFirst, slice);
653 q->insert(i - m_mapFirst, slice);
652 }
654 }
653 if (m_mapCount != -1 && m_slices.size() > m_mapCount)
655 if (m_mapCount != -1 && m_slices.size() > m_mapCount)
654 for (int i = m_slices.size() - 1; i >= m_mapCount; i--)
656 for (int i = m_slices.size() - 1; i >= m_mapCount; i--)
655 q->remove(q->slices().at(i));
657 q->remove(q->slices().at(i));
656 }
658 }
657 }
659 }
658
660
659 void QPieSeriesPrivate::removeData(int start, int end)
661 void QPieSeriesPrivate::removeData(int start, int end)
660 {
662 {
661 Q_Q(QPieSeries);
663 Q_Q(QPieSeries);
662 int removedCount = end - start + 1;
664 int removedCount = end - start + 1;
663 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
665 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
664 return;
666 return;
665 } else {
667 } else {
666 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
668 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
667 int first = qMax(start, m_mapFirst); // get the index of the first item that will be removed.
669 int first = qMax(start, m_mapFirst); // get the index of the first item that will be removed.
668 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapFirst - 1); // get the index of the last item that will be removed.
670 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapFirst - 1); // get the index of the last item that will be removed.
669 for (int i = last; i >= first; i--)
671 for (int i = last; i >= first; i--)
670 q->remove(q->slices().at(i - m_mapFirst));
672 q->remove(q->slices().at(i - m_mapFirst));
671
673
672 if (m_mapCount != -1) {
674 if (m_mapCount != -1) {
673 int itemsAvailable; // check how many are available to be added
675 int itemsAvailable; // check how many are available to be added
674 if (m_mapOrientation == Qt::Vertical)
676 if (m_mapOrientation == Qt::Vertical)
675 itemsAvailable = m_model->rowCount() - m_mapFirst - m_slices.size();
677 itemsAvailable = m_model->rowCount() - m_mapFirst - m_slices.size();
676 else
678 else
677 itemsAvailable = m_model->columnCount() - m_mapFirst - m_slices.size();
679 itemsAvailable = m_model->columnCount() - m_mapFirst - m_slices.size();
678 int toBeAdded = qMin(itemsAvailable, m_mapCount - m_slices.size()); // add not more items than there is space left to be filled.
680 int toBeAdded = qMin(itemsAvailable, m_mapCount - m_slices.size()); // add not more items than there is space left to be filled.
679 int currentSize = m_slices.size();
681 int currentSize = m_slices.size();
680 if (toBeAdded > 0)
682 if (toBeAdded > 0)
681 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
683 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
682 QPieSlice *slice = new QPieSlice;
684 QPieSlice *slice = new QPieSlice;
683 if (m_mapOrientation == Qt::Vertical) {
685 if (m_mapOrientation == Qt::Vertical) {
684 slice->setValue(m_model->data(m_model->index(i + m_mapFirst, m_mapValues), Qt::DisplayRole).toDouble());
686 slice->setValue(m_model->data(m_model->index(i + m_mapFirst, m_mapValues), Qt::DisplayRole).toDouble());
685 slice->setLabel(m_model->data(m_model->index(i + m_mapFirst, m_mapLabels), Qt::DisplayRole).toString());
687 slice->setLabel(m_model->data(m_model->index(i + m_mapFirst, m_mapLabels), Qt::DisplayRole).toString());
686 } else {
688 } else {
687 slice->setValue(m_model->data(m_model->index(m_mapValues, i + m_mapFirst), Qt::DisplayRole).toDouble());
689 slice->setValue(m_model->data(m_model->index(m_mapValues, i + m_mapFirst), Qt::DisplayRole).toDouble());
688 slice->setLabel(m_model->data(m_model->index(m_mapLabels, i + m_mapFirst), Qt::DisplayRole).toString());
690 slice->setLabel(m_model->data(m_model->index(m_mapLabels, i + m_mapFirst), Qt::DisplayRole).toString());
689 }
691 }
690 slice->setLabelVisible();
692 slice->setLabelVisible();
691 q->insert(i, slice);
693 q->insert(i, slice);
692 }
694 }
693 }
695 }
694 }
696 }
695 }
697 }
696
698
697 void QPieSeriesPrivate::initializePieFromModel()
699 void QPieSeriesPrivate::initializePieFromModel()
698 {
700 {
699 Q_Q(QPieSeries);
701 Q_Q(QPieSeries);
700 // clear current content
702 // clear current content
701 q->clear();
703 q->clear();
702
704
703 // create the initial slices set
705 // create the initial slices set
704 if (m_mapOrientation == Qt::Vertical) {
706 if (m_mapOrientation == Qt::Vertical) {
705 if (m_mapValues >= m_model->columnCount() || m_mapLabels >= m_model->columnCount())
707 if (m_mapValues >= m_model->columnCount() || m_mapLabels >= m_model->columnCount())
706 return; // mapped columns are not existing
708 return; // mapped columns are not existing
707
709
708 int sliceCount = 0;
710 int sliceCount = 0;
709 if(m_mapCount == -1)
711 if(m_mapCount == -1)
710 sliceCount = m_model->rowCount() - m_mapFirst;
712 sliceCount = m_model->rowCount() - m_mapFirst;
711 else
713 else
712 sliceCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst);
714 sliceCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst);
713 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
715 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
714 q->append(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
716 q->append(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
715 } else {
717 } else {
716 if (m_mapValues >= m_model->rowCount() || m_mapLabels >= m_model->rowCount())
718 if (m_mapValues >= m_model->rowCount() || m_mapLabels >= m_model->rowCount())
717 return; // mapped columns are not existing
719 return; // mapped columns are not existing
718
720
719 int sliceCount = 0;
721 int sliceCount = 0;
720 if(m_mapCount == -1)
722 if(m_mapCount == -1)
721 sliceCount = m_model->columnCount() - m_mapFirst;
723 sliceCount = m_model->columnCount() - m_mapFirst;
722 else
724 else
723 sliceCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst);
725 sliceCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst);
724 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
726 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
725 q->append(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
727 q->append(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
726 }
728 }
727 q->setLabelsVisible(true);
729 q->setLabelsVisible(true);
728 }
730 }
729
731
730 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
732 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
731 {
733 {
732 // Remove rounding errors
734 // Remove rounding errors
733 qreal roundedValue = newValue;
735 qreal roundedValue = newValue;
734 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
736 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
735 roundedValue = 0.0;
737 roundedValue = 0.0;
736 else if (qFuzzyCompare(newValue, max))
738 else if (qFuzzyCompare(newValue, max))
737 roundedValue = max;
739 roundedValue = max;
738 else if (qFuzzyCompare(newValue, min))
740 else if (qFuzzyCompare(newValue, min))
739 roundedValue = min;
741 roundedValue = min;
740
742
741 // Check if the position is valid after removing the rounding errors
743 // Check if the position is valid after removing the rounding errors
742 if (roundedValue < min || roundedValue > max) {
744 if (roundedValue < min || roundedValue > max) {
743 qWarning("QPieSeries: Illegal value");
745 qWarning("QPieSeries: Illegal value");
744 return false;
746 return false;
745 }
747 }
746
748
747 if (!qFuzzyIsNull(value - roundedValue)) {
749 if (!qFuzzyIsNull(value - roundedValue)) {
748 value = roundedValue;
750 value = roundedValue;
749 return true;
751 return true;
750 }
752 }
751
753
752 // The change was so small it is considered a rounding error
754 // The change was so small it is considered a rounding error
753 return false;
755 return false;
754 }
756 }
755
757
756 void QPieSeriesPrivate::scaleDomain(Domain& domain)
758 void QPieSeriesPrivate::scaleDomain(Domain& domain)
757 {
759 {
758 Q_UNUSED(domain);
760 Q_UNUSED(domain);
759 #ifndef QT_NO_DEBUG
761 #ifndef QT_NO_DEBUG
760 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
762 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
761 #endif
763 #endif
762 }
764 }
763
765
764 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
766 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
765 {
767 {
766 Q_Q(QPieSeries);
768 Q_Q(QPieSeries);
767 PieChartItem* pie = new PieChartItem(q,presenter);
769 PieChartItem* pie = new PieChartItem(q,presenter);
768 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
770 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
769 presenter->animator()->addAnimation(pie);
771 presenter->animator()->addAnimation(pie);
770 }
772 }
771 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
773 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
772 return pie;
774 return pie;
773 }
775 }
774
776
775 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
777 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
776 {
778 {
777 Q_Q(QPieSeries);
779 Q_Q(QPieSeries);
778 QList<LegendMarker*> markers;
780 QList<LegendMarker*> markers;
779 foreach(QPieSlice* slice, q->slices()) {
781 foreach(QPieSlice* slice, q->slices()) {
780 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
782 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
781 markers << marker;
783 markers << marker;
782 }
784 }
783 return markers;
785 return markers;
784 }
786 }
785
787
786 #include "moc_qpieseries.cpp"
788 #include "moc_qpieseries.cpp"
787 #include "moc_qpieseries_p.cpp"
789 #include "moc_qpieseries_p.cpp"
788
790
789 QTCOMMERCIALCHART_END_NAMESPACE
791 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now