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