##// END OF EJS Templates
pie: make slice added/removed signals public (again)
Jani Honkonen -
r1213:7e0a0b1297ee
parent child
Show More
@@ -1,461 +1,459
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 "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26
26
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qscatterseries.h"
31 #include "qscatterseries.h"
32 #include "qsplineseries.h"
32 #include "qsplineseries.h"
33 #include "qbarseries.h"
33 #include "qbarseries.h"
34 #include "qstackedbarseries.h"
34 #include "qstackedbarseries.h"
35 #include "qpercentbarseries.h"
35 #include "qpercentbarseries.h"
36 #include "qbarset.h"
36 #include "qbarset.h"
37 #include "qpieseries.h"
37 #include "qpieseries.h"
38 #include "qpieseries_p.h"
38 #include "qpieseries_p.h"
39 #include "qpieslice.h"
39 #include "qpieslice.h"
40 #include "chartpresenter_p.h"
40 #include "chartpresenter_p.h"
41 #include <QPainter>
41 #include <QPainter>
42 #include <QPen>
42 #include <QPen>
43 #include <QTimer>
43 #include <QTimer>
44
44
45 #include <QGraphicsSceneEvent>
45 #include <QGraphicsSceneEvent>
46
46
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48
48
49 /*!
49 /*!
50 \class QLegend
50 \class QLegend
51 \brief part of QtCommercial chart API.
51 \brief part of QtCommercial chart API.
52 \mainclass
52 \mainclass
53
53
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 handle the drawing manually.
56 handle the drawing manually.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58
58
59 \image examples_percentbarchart_legend.png
59 \image examples_percentbarchart_legend.png
60
60
61 \sa QChart
61 \sa QChart
62 */
62 */
63
63
64 /*!
64 /*!
65 \enum QLegend::Alignment
65 \enum QLegend::Alignment
66
66
67 This enum describes the possible position for legend inside chart.
67 This enum describes the possible position for legend inside chart.
68
68
69 \value AlignmentTop
69 \value AlignmentTop
70 \value AlignmentBottom
70 \value AlignmentBottom
71 \value AlignmentLeft
71 \value AlignmentLeft
72 \value AlignmentRight
72 \value AlignmentRight
73 */
73 */
74
74
75 /*!
75 /*!
76 \fn qreal QLegend::minWidth() const
76 \fn qreal QLegend::minWidth() const
77 Returns minimum width of the legend
77 Returns minimum width of the legend
78 */
78 */
79
79
80 /*!
80 /*!
81 \fn qreal QLegend::minHeight() const
81 \fn qreal QLegend::minHeight() const
82 Returns minimum height of the legend
82 Returns minimum height of the legend
83 */
83 */
84
84
85 /*!
85 /*!
86 Constructs the legend object and sets the parent to \a parent
86 Constructs the legend object and sets the parent to \a parent
87 */
87 */
88
88
89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
90 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
90 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
91 {
91 {
92 setZValue(ChartPresenter::LegendZValue);
92 setZValue(ChartPresenter::LegendZValue);
93 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
93 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
96 }
96 }
97
97
98 /*!
98 /*!
99 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
99 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
100 */
100 */
101 QLegend::~QLegend()
101 QLegend::~QLegend()
102 {
102 {
103 }
103 }
104
104
105 /*!
105 /*!
106 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
106 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
107 */
107 */
108
108
109 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
109 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 {
110 {
111 Q_UNUSED(option)
111 Q_UNUSED(option)
112 Q_UNUSED(widget)
112 Q_UNUSED(widget)
113 if(!d_ptr->m_backgroundVisible) return;
113 if(!d_ptr->m_backgroundVisible) return;
114
114
115 painter->setOpacity(opacity());
115 painter->setOpacity(opacity());
116 painter->setPen(d_ptr->m_pen);
116 painter->setPen(d_ptr->m_pen);
117 painter->setBrush(d_ptr->m_brush);
117 painter->setBrush(d_ptr->m_brush);
118 painter->drawRect(boundingRect());
118 painter->drawRect(boundingRect());
119 }
119 }
120
120
121 /*!
121 /*!
122 Bounding rect of legend.
122 Bounding rect of legend.
123 */
123 */
124
124
125 QRectF QLegend::boundingRect() const
125 QRectF QLegend::boundingRect() const
126 {
126 {
127 return d_ptr->m_rect;
127 return d_ptr->m_rect;
128 }
128 }
129
129
130 /*!
130 /*!
131 Sets the \a brush of legend. Brush affects the background of legend.
131 Sets the \a brush of legend. Brush affects the background of legend.
132 */
132 */
133 void QLegend::setBrush(const QBrush &brush)
133 void QLegend::setBrush(const QBrush &brush)
134 {
134 {
135 if (d_ptr->m_brush != brush) {
135 if (d_ptr->m_brush != brush) {
136 d_ptr->m_brush = brush;
136 d_ptr->m_brush = brush;
137 update();
137 update();
138 }
138 }
139 }
139 }
140
140
141 /*!
141 /*!
142 Returns the brush used by legend.
142 Returns the brush used by legend.
143 */
143 */
144 QBrush QLegend::brush() const
144 QBrush QLegend::brush() const
145 {
145 {
146 return d_ptr->m_brush;
146 return d_ptr->m_brush;
147 }
147 }
148
148
149 /*!
149 /*!
150 Sets the \a pen of legend. Pen affects the legend borders.
150 Sets the \a pen of legend. Pen affects the legend borders.
151 */
151 */
152 void QLegend::setPen(const QPen &pen)
152 void QLegend::setPen(const QPen &pen)
153 {
153 {
154 if (d_ptr->m_pen != pen) {
154 if (d_ptr->m_pen != pen) {
155 d_ptr->m_pen = pen;
155 d_ptr->m_pen = pen;
156 update();
156 update();
157 }
157 }
158 }
158 }
159
159
160 /*!
160 /*!
161 Returns the pen used by legend
161 Returns the pen used by legend
162 */
162 */
163
163
164 QPen QLegend::pen() const
164 QPen QLegend::pen() const
165 {
165 {
166 return d_ptr->m_pen;
166 return d_ptr->m_pen;
167 }
167 }
168
168
169 /*!
169 /*!
170 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
170 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
171 \sa QLegend::Alignment
171 \sa QLegend::Alignment
172 */
172 */
173 void QLegend::setAlignment(QLegend::Alignments alignment)
173 void QLegend::setAlignment(QLegend::Alignments alignment)
174 {
174 {
175 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
175 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
176 d_ptr->m_alignment = alignment;
176 d_ptr->m_alignment = alignment;
177 d_ptr->updateLayout();
177 d_ptr->updateLayout();
178 }
178 }
179 }
179 }
180
180
181 /*!
181 /*!
182 Returns the preferred layout for legend
182 Returns the preferred layout for legend
183 */
183 */
184 QLegend::Alignments QLegend::alignment() const
184 QLegend::Alignments QLegend::alignment() const
185 {
185 {
186 return d_ptr->m_alignment;
186 return d_ptr->m_alignment;
187 }
187 }
188
188
189 /*!
189 /*!
190 Detaches the legend from chart. Chart won't change layout of the legend.
190 Detaches the legend from chart. Chart won't change layout of the legend.
191 */
191 */
192 void QLegend::detachFromChart()
192 void QLegend::detachFromChart()
193 {
193 {
194 d_ptr->m_attachedToChart = false;
194 d_ptr->m_attachedToChart = false;
195 }
195 }
196
196
197 /*!
197 /*!
198 Attaches the legend to chart. Chart may change layout of the legend.
198 Attaches the legend to chart. Chart may change layout of the legend.
199 */
199 */
200 void QLegend::attachToChart()
200 void QLegend::attachToChart()
201 {
201 {
202 d_ptr->m_attachedToChart = true;
202 d_ptr->m_attachedToChart = true;
203 }
203 }
204
204
205 /*!
205 /*!
206 Returns true, if legend is attached to chart.
206 Returns true, if legend is attached to chart.
207 */
207 */
208 bool QLegend::isAttachedToChart()
208 bool QLegend::isAttachedToChart()
209 {
209 {
210 return d_ptr->m_attachedToChart;
210 return d_ptr->m_attachedToChart;
211 }
211 }
212
212
213 /*!
213 /*!
214 Sets the legend's scrolling offset to value defined by \a point.
214 Sets the legend's scrolling offset to value defined by \a point.
215 */
215 */
216 void QLegend::setOffset(const QPointF& point)
216 void QLegend::setOffset(const QPointF& point)
217 {
217 {
218 d_ptr->setOffset(point.x(),point.y());
218 d_ptr->setOffset(point.x(),point.y());
219 }
219 }
220
220
221 /*!
221 /*!
222 Returns the legend's scrolling offset.
222 Returns the legend's scrolling offset.
223 */
223 */
224 QPointF QLegend::offset() const
224 QPointF QLegend::offset() const
225 {
225 {
226 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
226 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
227 }
227 }
228
228
229 /*!
229 /*!
230 Sets the visibility of legend background to \a visible
230 Sets the visibility of legend background to \a visible
231 */
231 */
232 void QLegend::setBackgroundVisible(bool visible)
232 void QLegend::setBackgroundVisible(bool visible)
233 {
233 {
234 if(d_ptr->m_backgroundVisible!=visible)
234 if(d_ptr->m_backgroundVisible!=visible)
235 {
235 {
236 d_ptr->m_backgroundVisible=visible;
236 d_ptr->m_backgroundVisible=visible;
237 update();
237 update();
238 }
238 }
239 }
239 }
240
240
241 /*!
241 /*!
242 Returns the visibility of legend background
242 Returns the visibility of legend background
243 */
243 */
244 bool QLegend::isBackgroundVisible() const
244 bool QLegend::isBackgroundVisible() const
245 {
245 {
246 return d_ptr->m_backgroundVisible;
246 return d_ptr->m_backgroundVisible;
247 }
247 }
248
248
249 /*!
249 /*!
250 \internal \a event see QGraphicsWidget for details
250 \internal \a event see QGraphicsWidget for details
251 */
251 */
252 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
252 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
253 {
253 {
254 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
254 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
255 QGraphicsWidget::resizeEvent(event);
255 QGraphicsWidget::resizeEvent(event);
256 if(d_ptr->m_rect != rect) {
256 if(d_ptr->m_rect != rect) {
257 d_ptr->m_rect = rect;
257 d_ptr->m_rect = rect;
258 d_ptr->updateLayout();
258 d_ptr->updateLayout();
259 }
259 }
260 }
260 }
261
261
262 /*!
262 /*!
263 \internal \a event see QGraphicsWidget for details
263 \internal \a event see QGraphicsWidget for details
264 */
264 */
265 void QLegend::hideEvent(QHideEvent *event)
265 void QLegend::hideEvent(QHideEvent *event)
266 {
266 {
267 QGraphicsWidget::hideEvent(event);
267 QGraphicsWidget::hideEvent(event);
268 setEnabled(false);
268 setEnabled(false);
269 d_ptr->updateLayout();
269 d_ptr->updateLayout();
270 }
270 }
271
271
272 /*!
272 /*!
273 \internal \a event see QGraphicsWidget for details
273 \internal \a event see QGraphicsWidget for details
274 */
274 */
275 void QLegend::showEvent(QShowEvent *event)
275 void QLegend::showEvent(QShowEvent *event)
276 {
276 {
277 QGraphicsWidget::showEvent(event);
277 QGraphicsWidget::showEvent(event);
278 setEnabled(true);
278 setEnabled(true);
279 d_ptr->updateLayout();
279 d_ptr->updateLayout();
280 }
280 }
281
281
282 qreal QLegend::minWidth() const
282 qreal QLegend::minWidth() const
283 {
283 {
284 return d_ptr->m_minWidth;
284 return d_ptr->m_minWidth;
285 }
285 }
286
286
287 qreal QLegend::minHeight() const
287 qreal QLegend::minHeight() const
288 {
288 {
289 return d_ptr->m_minHeight;
289 return d_ptr->m_minHeight;
290 }
290 }
291
291
292 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
292 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293
293
294 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
294 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
295 q_ptr(q),
295 q_ptr(q),
296 m_presenter(presenter),
296 m_presenter(presenter),
297 m_markers(new QGraphicsItemGroup(q)),
297 m_markers(new QGraphicsItemGroup(q)),
298 m_alignment(QLegend::AlignmentTop),
298 m_alignment(QLegend::AlignmentTop),
299 m_offsetX(0),
299 m_offsetX(0),
300 m_offsetY(0),
300 m_offsetY(0),
301 m_minWidth(0),
301 m_minWidth(0),
302 m_minHeight(0),
302 m_minHeight(0),
303 m_width(0),
303 m_width(0),
304 m_height(0),
304 m_height(0),
305 m_attachedToChart(true),
305 m_attachedToChart(true),
306 m_backgroundVisible(false)
306 m_backgroundVisible(false)
307 {
307 {
308
308
309 }
309 }
310
310
311 QLegendPrivate::~QLegendPrivate()
311 QLegendPrivate::~QLegendPrivate()
312 {
312 {
313
313
314 }
314 }
315
315
316 void QLegendPrivate::setOffset(qreal x, qreal y)
316 void QLegendPrivate::setOffset(qreal x, qreal y)
317 {
317 {
318
318
319 switch(m_alignment) {
319 switch(m_alignment) {
320
320
321 case QLegend::AlignmentTop:
321 case QLegend::AlignmentTop:
322 case QLegend::AlignmentBottom: {
322 case QLegend::AlignmentBottom: {
323 if(m_width<=m_rect.width()) return;
323 if(m_width<=m_rect.width()) return;
324
324
325 if (x != m_offsetX) {
325 if (x != m_offsetX) {
326 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
326 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
327 m_markers->setPos(-m_offsetX,m_rect.top());
327 m_markers->setPos(-m_offsetX,m_rect.top());
328 }
328 }
329 break;
329 break;
330 }
330 }
331 case QLegend::AlignmentLeft:
331 case QLegend::AlignmentLeft:
332 case QLegend::AlignmentRight: {
332 case QLegend::AlignmentRight: {
333
333
334 if(m_height<=m_rect.height()) return;
334 if(m_height<=m_rect.height()) return;
335
335
336 if (y != m_offsetY) {
336 if (y != m_offsetY) {
337 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
337 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
338 m_markers->setPos(m_rect.left(),-m_offsetY);
338 m_markers->setPos(m_rect.left(),-m_offsetY);
339 }
339 }
340 break;
340 break;
341 }
341 }
342 }
342 }
343 }
343 }
344
344
345
345
346 void QLegendPrivate::updateLayout()
346 void QLegendPrivate::updateLayout()
347 {
347 {
348 m_offsetX=0;
348 m_offsetX=0;
349 QList<QGraphicsItem *> items = m_markers->childItems();
349 QList<QGraphicsItem *> items = m_markers->childItems();
350
350
351 if(items.isEmpty()) return;
351 if(items.isEmpty()) return;
352
352
353 m_minWidth=0;
353 m_minWidth=0;
354 m_minHeight=0;
354 m_minHeight=0;
355
355
356 switch(m_alignment) {
356 switch(m_alignment) {
357
357
358 case QLegend::AlignmentTop:
358 case QLegend::AlignmentTop:
359 case QLegend::AlignmentBottom: {
359 case QLegend::AlignmentBottom: {
360 QPointF point = m_rect.topLeft();
360 QPointF point = m_rect.topLeft();
361 m_width = 0;
361 m_width = 0;
362 foreach (QGraphicsItem *item, items) {
362 foreach (QGraphicsItem *item, items) {
363 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
363 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
364 const QRectF& rect = item->boundingRect();
364 const QRectF& rect = item->boundingRect();
365 qreal w = rect.width();
365 qreal w = rect.width();
366 m_minWidth=qMax(m_minWidth,w);
366 m_minWidth=qMax(m_minWidth,w);
367 m_minHeight=qMax(m_minHeight,rect.height());
367 m_minHeight=qMax(m_minHeight,rect.height());
368 m_width+=w;
368 m_width+=w;
369 point.setX(point.x() + w);
369 point.setX(point.x() + w);
370 }
370 }
371 if(m_width<m_rect.width()) {
371 if(m_width<m_rect.width()) {
372 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
372 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
373 }
373 }
374 else {
374 else {
375 m_markers->setPos(m_rect.topLeft());
375 m_markers->setPos(m_rect.topLeft());
376 }
376 }
377 m_height=m_minHeight;
377 m_height=m_minHeight;
378 }
378 }
379 break;
379 break;
380 case QLegend::AlignmentLeft:
380 case QLegend::AlignmentLeft:
381 case QLegend::AlignmentRight: {
381 case QLegend::AlignmentRight: {
382 QPointF point = m_rect.topLeft();
382 QPointF point = m_rect.topLeft();
383 m_height = 0;
383 m_height = 0;
384 foreach (QGraphicsItem *item, items) {
384 foreach (QGraphicsItem *item, items) {
385 item->setPos(point);
385 item->setPos(point);
386 const QRectF& rect = item->boundingRect();
386 const QRectF& rect = item->boundingRect();
387 qreal h = rect.height();
387 qreal h = rect.height();
388 m_minWidth=qMax(m_minWidth,rect.width());
388 m_minWidth=qMax(m_minWidth,rect.width());
389 m_minHeight=qMax(m_minHeight,h);
389 m_minHeight=qMax(m_minHeight,h);
390 m_height+=h;
390 m_height+=h;
391 point.setY(point.y() + h);
391 point.setY(point.y() + h);
392 }
392 }
393 if(m_height<m_rect.height()) {
393 if(m_height<m_rect.height()) {
394 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
394 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
395 }
395 }
396 else {
396 else {
397 m_markers->setPos(m_rect.topLeft());
397 m_markers->setPos(m_rect.topLeft());
398 }
398 }
399 m_width=m_minWidth;
399 m_width=m_minWidth;
400 }
400 }
401 break;
401 break;
402 }
402 }
403
403
404 m_presenter->updateLayout();
404 m_presenter->updateLayout();
405 }
405 }
406
406
407 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
407 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
408 {
408 {
409 Q_UNUSED(domain)
409 Q_UNUSED(domain)
410
410
411 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
411 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
412 foreach(LegendMarker* marker , markers)
412 foreach(LegendMarker* marker , markers)
413 m_markers->addToGroup(marker);
413 m_markers->addToGroup(marker);
414
414
415 if(series->type() == QAbstractSeries::SeriesTypePie)
415 if(series->type() == QAbstractSeries::SeriesTypePie)
416 {
416 {
417 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
417 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
418 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*pieSeries);
418 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
419 QObject::connect(d, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
419 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
420 QObject::connect(d, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
421 }
420 }
422
421
423 updateLayout();
422 updateLayout();
424 }
423 }
425
424
426 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
425 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
427 {
426 {
428
427
429 QList<QGraphicsItem *> items = m_markers->childItems();
428 QList<QGraphicsItem *> items = m_markers->childItems();
430
429
431 foreach (QGraphicsItem *markers, items) {
430 foreach (QGraphicsItem *markers, items) {
432 LegendMarker *marker = static_cast<LegendMarker*>(markers);
431 LegendMarker *marker = static_cast<LegendMarker*>(markers);
433 if (marker->series() == series) {
432 if (marker->series() == series) {
434 delete marker;
433 delete marker;
435 }
434 }
436 }
435 }
437
436
438 if(series->type() == QAbstractSeries::SeriesTypePie)
437 if(series->type() == QAbstractSeries::SeriesTypePie)
439 {
438 {
440 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
439 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
441 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*pieSeries);
440 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
442 QObject::disconnect(d, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
441 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
443 QObject::disconnect(d, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
444 }
442 }
445
443
446 updateLayout();
444 updateLayout();
447 }
445 }
448
446
449 void QLegendPrivate::handleUpdatePieSeries()
447 void QLegendPrivate::handleUpdatePieSeries()
450 {
448 {
451 //TODO: reimplement to be optimal
449 //TODO: reimplement to be optimal
452 QPieSeriesPrivate* d = qobject_cast<QPieSeriesPrivate *> (sender());
450 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
453 Q_ASSERT(d->q_func());
451 Q_ASSERT(series);
454 handleSeriesRemoved(d->q_func());
452 handleSeriesRemoved(series);
455 handleSeriesAdded(d->q_func(), 0);
453 handleSeriesAdded(series, 0);
456 }
454 }
457
455
458 #include "moc_qlegend.cpp"
456 #include "moc_qlegend.cpp"
459 #include "moc_qlegend_p.cpp"
457 #include "moc_qlegend_p.cpp"
460
458
461 QTCOMMERCIALCHART_END_NAMESPACE
459 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,185 +1,185
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 "piechartitem_p.h"
21 #include "piechartitem_p.h"
22 #include "piesliceitem_p.h"
22 #include "piesliceitem_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "qpieseries.h"
24 #include "qpieseries.h"
25 #include "qpieseries_p.h"
25 #include "qpieseries_p.h"
26 #include "chartpresenter_p.h"
26 #include "chartpresenter_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "chartanimator_p.h"
28 #include "chartanimator_p.h"
29 #include <QPainter>
29 #include <QPainter>
30 #include <QTimer>
30 #include <QTimer>
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
34 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
35 :ChartItem(presenter),
35 :ChartItem(presenter),
36 m_series(series)
36 m_series(series)
37 {
37 {
38 Q_ASSERT(series);
38 Q_ASSERT(series);
39
39
40 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
41 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
40 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*series);
42 QPieSeriesPrivate *d = QPieSeriesPrivate::seriesData(*series);
41 connect(d, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
42 connect(d, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
43 connect(d, SIGNAL(piePositionChanged()), this, SLOT(updateLayout()));
43 connect(d, SIGNAL(piePositionChanged()), this, SLOT(updateLayout()));
44 connect(d, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
44 connect(d, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
45
45
46 QTimer::singleShot(0, this, SLOT(initialize())); // TODO: get rid of this
46 QTimer::singleShot(0, this, SLOT(initialize())); // TODO: get rid of this
47
47
48 // Note: the following does not affect as long as the item does not have anything to paint
48 // Note: the following does not affect as long as the item does not have anything to paint
49 setZValue(ChartPresenter::PieSeriesZValue);
49 setZValue(ChartPresenter::PieSeriesZValue);
50 }
50 }
51
51
52 PieChartItem::~PieChartItem()
52 PieChartItem::~PieChartItem()
53 {
53 {
54 // slices deleted automatically through QGraphicsItem
54 // slices deleted automatically through QGraphicsItem
55 }
55 }
56
56
57 void PieChartItem::handleGeometryChanged(const QRectF& rect)
57 void PieChartItem::handleGeometryChanged(const QRectF& rect)
58 {
58 {
59 prepareGeometryChange();
59 prepareGeometryChange();
60 m_rect = rect;
60 m_rect = rect;
61 updateLayout();
61 updateLayout();
62 }
62 }
63
63
64 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
64 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
65 {
65 {
66 Q_UNUSED(minX);
66 Q_UNUSED(minX);
67 Q_UNUSED(maxX);
67 Q_UNUSED(maxX);
68 Q_UNUSED(minY);
68 Q_UNUSED(minY);
69 Q_UNUSED(maxY);
69 Q_UNUSED(maxY);
70 // does not apply to pie
70 // does not apply to pie
71 }
71 }
72
72
73 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
73 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
74 {
74 {
75 Q_UNUSED(min);
75 Q_UNUSED(min);
76 Q_UNUSED(max);
76 Q_UNUSED(max);
77 Q_UNUSED(tickXCount);
77 Q_UNUSED(tickXCount);
78 // does not apply to pie
78 // does not apply to pie
79 }
79 }
80
80
81 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
81 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
82 {
82 {
83 Q_UNUSED(min);
83 Q_UNUSED(min);
84 Q_UNUSED(max);
84 Q_UNUSED(max);
85 Q_UNUSED(tickYCount);
85 Q_UNUSED(tickYCount);
86 // does not apply to pie
86 // does not apply to pie
87 }
87 }
88
88
89 void PieChartItem::initialize()
89 void PieChartItem::initialize()
90 {
90 {
91 handleSlicesAdded(m_series->slices());
91 handleSlicesAdded(m_series->slices());
92 }
92 }
93
93
94 void PieChartItem::updateLayout()
94 void PieChartItem::updateLayout()
95 {
95 {
96 // find pie center coordinates
96 // find pie center coordinates
97 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
97 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
98 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
98 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
99
99
100 // find maximum radius for pie
100 // find maximum radius for pie
101 m_pieRadius = m_rect.height() / 2;
101 m_pieRadius = m_rect.height() / 2;
102 if (m_rect.width() < m_rect.height())
102 if (m_rect.width() < m_rect.height())
103 m_pieRadius = m_rect.width() / 2;
103 m_pieRadius = m_rect.width() / 2;
104
104
105 // apply size factor
105 // apply size factor
106 m_pieRadius *= m_series->pieSize();
106 m_pieRadius *= m_series->pieSize();
107
107
108 // set layouts for existing slice items
108 // set layouts for existing slice items
109 foreach (QPieSlice* slice, m_series->slices()) {
109 foreach (QPieSlice* slice, m_series->slices()) {
110 PieSliceItem *sliceItem = m_sliceItems.value(slice);
110 PieSliceItem *sliceItem = m_sliceItems.value(slice);
111 if (sliceItem) {
111 if (sliceItem) {
112 PieSliceData sliceData = updateSliceGeometry(slice);
112 PieSliceData sliceData = updateSliceGeometry(slice);
113 if (animator())
113 if (animator())
114 animator()->updateAnimation(this, sliceItem, sliceData);
114 animator()->updateAnimation(this, sliceItem, sliceData);
115 else
115 else
116 sliceItem->setLayout(sliceData);
116 sliceItem->setLayout(sliceData);
117 }
117 }
118 }
118 }
119
119
120 update();
120 update();
121 }
121 }
122
122
123 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
123 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
124 {
124 {
125 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
125 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
126
126
127 bool startupAnimation = m_sliceItems.isEmpty();
127 bool startupAnimation = m_sliceItems.isEmpty();
128
128
129 foreach (QPieSlice *slice, slices) {
129 foreach (QPieSlice *slice, slices) {
130 PieSliceItem* sliceItem = new PieSliceItem(this);
130 PieSliceItem* sliceItem = new PieSliceItem(this);
131 m_sliceItems.insert(slice, sliceItem);
131 m_sliceItems.insert(slice, sliceItem);
132 connect(slice, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
132 connect(slice, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
133 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
133 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
134 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
134 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
135
135
136 PieSliceData sliceData = updateSliceGeometry(slice);
136 PieSliceData sliceData = updateSliceGeometry(slice);
137 if (animator())
137 if (animator())
138 animator()->addAnimation(this, sliceItem, sliceData, startupAnimation);
138 animator()->addAnimation(this, sliceItem, sliceData, startupAnimation);
139 else
139 else
140 sliceItem->setLayout(sliceData);
140 sliceItem->setLayout(sliceData);
141 }
141 }
142 }
142 }
143
143
144 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
144 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
145 {
145 {
146 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
146 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
147
147
148 foreach (QPieSlice *slice, slices) {
148 foreach (QPieSlice *slice, slices) {
149 PieSliceItem *sliceItem = m_sliceItems.value(slice);
149 PieSliceItem *sliceItem = m_sliceItems.value(slice);
150 Q_ASSERT(sliceItem);
150 Q_ASSERT(sliceItem);
151 m_sliceItems.remove(slice);
151 m_sliceItems.remove(slice);
152
152
153 if (animator())
153 if (animator())
154 animator()->removeAnimation(this, sliceItem); // animator deletes the PieSliceItem
154 animator()->removeAnimation(this, sliceItem); // animator deletes the PieSliceItem
155 else
155 else
156 delete sliceItem;
156 delete sliceItem;
157 }
157 }
158 }
158 }
159
159
160 void PieChartItem::handleSliceChanged()
160 void PieChartItem::handleSliceChanged()
161 {
161 {
162 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
162 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
163 Q_ASSERT(m_sliceItems.contains(slice));
163 Q_ASSERT(m_sliceItems.contains(slice));
164
164
165 PieSliceItem *sliceItem = m_sliceItems.value(slice);
165 PieSliceItem *sliceItem = m_sliceItems.value(slice);
166 PieSliceData sliceData = updateSliceGeometry(slice);
166 PieSliceData sliceData = updateSliceGeometry(slice);
167 if (animator())
167 if (animator())
168 animator()->updateAnimation(this, sliceItem, sliceData);
168 animator()->updateAnimation(this, sliceItem, sliceData);
169 else
169 else
170 sliceItem->setLayout(sliceData);
170 sliceItem->setLayout(sliceData);
171
171
172 update();
172 update();
173 }
173 }
174
174
175 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
175 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
176 {
176 {
177 PieSliceData &sliceData = PieSliceData::data(slice);
177 PieSliceData &sliceData = PieSliceData::data(slice);
178 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
178 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
179 sliceData.m_radius = m_pieRadius;
179 sliceData.m_radius = m_pieRadius;
180 return sliceData;
180 return sliceData;
181 }
181 }
182
182
183 #include "moc_piechartitem_p.cpp"
183 #include "moc_piechartitem_p.cpp"
184
184
185 QTCOMMERCIALCHART_END_NAMESPACE
185 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,816 +1,816
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 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 label.
194 Appends a single slice to the series with give \a value and \a label.
195 Slice ownership is passed to the series.
195 Slice ownership is passed to the series.
196 */
196 */
197 QPieSlice* QPieSeries::append(QString label, qreal value)
197 QPieSlice* QPieSeries::append(QString label, qreal value)
198 {
198 {
199 QPieSlice* slice = new QPieSlice(label, value);
199 QPieSlice* slice = new QPieSlice(label, value);
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 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 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 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 (qFuzzyIsNull(d->m_pieStartAngle - angle))
344 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
345 return;
345 return;
346 d->m_pieStartAngle = angle;
346 d->m_pieStartAngle = angle;
347 d->updateDerivativeData();
347 d->updateDerivativeData();
348 }
348 }
349
349
350 qreal QPieSeries::pieStartAngle() const
350 qreal QPieSeries::pieStartAngle() const
351 {
351 {
352 Q_D(const QPieSeries);
352 Q_D(const QPieSeries);
353 return d->m_pieStartAngle;
353 return d->m_pieStartAngle;
354 }
354 }
355
355
356 /*!
356 /*!
357 Sets the end angle of the pie.
357 Sets the end angle of the pie.
358
358
359 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
359 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
360
360
361 \a angle must be greater than start angle.
361 \a angle must be greater than start angle.
362
362
363 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
363 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
364 */
364 */
365 void QPieSeries::setPieEndAngle(qreal angle)
365 void QPieSeries::setPieEndAngle(qreal angle)
366 {
366 {
367 Q_D(QPieSeries);
367 Q_D(QPieSeries);
368 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
368 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
369 return;
369 return;
370 d->m_pieEndAngle = angle;
370 d->m_pieEndAngle = angle;
371 d->updateDerivativeData();
371 d->updateDerivativeData();
372 }
372 }
373
373
374 /*!
374 /*!
375 Returns the end angle of the pie.
375 Returns the end angle of the pie.
376
376
377 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
377 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
378
378
379 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
379 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
380 */
380 */
381 qreal QPieSeries::pieEndAngle() const
381 qreal QPieSeries::pieEndAngle() const
382 {
382 {
383 Q_D(const QPieSeries);
383 Q_D(const QPieSeries);
384 return d->m_pieEndAngle;
384 return d->m_pieEndAngle;
385 }
385 }
386
386
387 /*!
387 /*!
388 Sets the all the slice labels \a visible or invisible.
388 Sets the all the slice labels \a visible or invisible.
389
389
390 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
390 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
391 */
391 */
392 void QPieSeries::setLabelsVisible(bool visible)
392 void QPieSeries::setLabelsVisible(bool visible)
393 {
393 {
394 Q_D(QPieSeries);
394 Q_D(QPieSeries);
395 foreach (QPieSlice* s, d->m_slices)
395 foreach (QPieSlice* s, d->m_slices)
396 s->setLabelVisible(visible);
396 s->setLabelVisible(visible);
397 }
397 }
398
398
399 /*!
399 /*!
400 Returns the sum of all slice values in this series.
400 Returns the sum of all slice values in this series.
401
401
402 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
402 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
403 */
403 */
404 qreal QPieSeries::sum() const
404 qreal QPieSeries::sum() const
405 {
405 {
406 Q_D(const QPieSeries);
406 Q_D(const QPieSeries);
407 return d->m_sum;
407 return d->m_sum;
408 }
408 }
409
409
410 /*!
410 /*!
411 \fn void QPieSeries::clicked(QPieSlice* slice)
411 \fn void QPieSeries::clicked(QPieSlice* slice)
412
412
413 This signal is emitted when a \a slice has been clicked.
413 This signal is emitted when a \a slice has been clicked.
414
414
415 \sa QPieSlice::clicked()
415 \sa QPieSlice::clicked()
416 */
416 */
417
417
418 /*!
418 /*!
419 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
419 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
420
420
421 This signal is emitted when user has hovered over or away from the \a slice.
421 This signal is emitted when user has hovered over or away from the \a slice.
422
422
423 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
423 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
424
424
425 \sa QPieSlice::hovered()
425 \sa QPieSlice::hovered()
426 */
426 */
427
427
428 /*!
428 /*!
429 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
429 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
430 Sets the \a model to be used as a data source
430 Sets the \a model to be used as a data source
431 */
431 */
432 void QPieSeries::setModel(QAbstractItemModel* model)
432 void QPieSeries::setModel(QAbstractItemModel* model)
433 {
433 {
434 Q_D(QPieSeries);
434 Q_D(QPieSeries);
435 // disconnect signals from old model
435 // disconnect signals from old model
436 if(d->m_model)
436 if(d->m_model)
437 {
437 {
438 disconnect(d->m_model, 0, this, 0);
438 disconnect(d->m_model, 0, this, 0);
439 }
439 }
440
440
441 // set new model
441 // set new model
442 if(model)
442 if(model)
443 {
443 {
444 d->m_model = model;
444 d->m_model = model;
445 // connect signals from the model
445 // connect signals from the model
446 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
446 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
447 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
447 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
448 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
448 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
449 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
449 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
450 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
450 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
451
451
452 if (d->m_mapper)
452 if (d->m_mapper)
453 d->initializePieFromModel();
453 d->initializePieFromModel();
454 }
454 }
455 else
455 else
456 {
456 {
457 d->m_model = 0;
457 d->m_model = 0;
458 }
458 }
459 }
459 }
460
460
461 void QPieSeries::setModelMapper(QPieModelMapper *mapper)
461 void QPieSeries::setModelMapper(QPieModelMapper *mapper)
462 {
462 {
463 Q_D(QPieSeries);
463 Q_D(QPieSeries);
464 // disconnect signals from old mapper
464 // disconnect signals from old mapper
465 if (d->m_mapper) {
465 if (d->m_mapper) {
466 QObject::disconnect(d->m_mapper, 0, this, 0);
466 QObject::disconnect(d->m_mapper, 0, this, 0);
467 }
467 }
468
468
469 if (mapper) {
469 if (mapper) {
470 d->m_mapper = mapper;
470 d->m_mapper = mapper;
471 // connect the signal from the mapper
471 // connect the signal from the mapper
472 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
472 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
473
473
474 if (d->m_model)
474 if (d->m_model)
475 d->initializePieFromModel();
475 d->initializePieFromModel();
476 } else {
476 } else {
477 d->m_mapper = 0;
477 d->m_mapper = 0;
478 }
478 }
479 }
479 }
480
480
481 QPieModelMapper* QPieSeries::modelMapper() const
481 QPieModelMapper* QPieSeries::modelMapper() const
482 {
482 {
483 Q_D(const QPieSeries);
483 Q_D(const QPieSeries);
484 return d->m_mapper;
484 return d->m_mapper;
485 }
485 }
486
486
487 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
487 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
488
488
489
489
490 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
490 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
491 QAbstractSeriesPrivate(parent),
491 QAbstractSeriesPrivate(parent),
492 m_pieRelativeHorPos(0.5),
492 m_pieRelativeHorPos(0.5),
493 m_pieRelativeVerPos(0.5),
493 m_pieRelativeVerPos(0.5),
494 m_pieRelativeSize(0.7),
494 m_pieRelativeSize(0.7),
495 m_pieStartAngle(0),
495 m_pieStartAngle(0),
496 m_pieEndAngle(360),
496 m_pieEndAngle(360),
497 m_sum(0),
497 m_sum(0),
498 m_mapper(0)
498 m_mapper(0)
499 {
499 {
500
500
501 }
501 }
502
502
503 QPieSeriesPrivate::~QPieSeriesPrivate()
503 QPieSeriesPrivate::~QPieSeriesPrivate()
504 {
504 {
505
505
506 }
506 }
507
507
508 void QPieSeriesPrivate::updateDerivativeData()
508 void QPieSeriesPrivate::updateDerivativeData()
509 {
509 {
510 m_sum = 0;
510 m_sum = 0;
511
511
512 // nothing to do?
512 // nothing to do?
513 if (m_slices.count() == 0)
513 if (m_slices.count() == 0)
514 return;
514 return;
515
515
516 // calculate sum of all slices
516 // calculate sum of all slices
517 foreach (QPieSlice* s, m_slices)
517 foreach (QPieSlice* s, m_slices)
518 m_sum += s->value();
518 m_sum += s->value();
519
519
520 // nothing to show..
520 // nothing to show..
521 if (qFuzzyIsNull(m_sum))
521 if (qFuzzyIsNull(m_sum))
522 return;
522 return;
523
523
524 // update slice attributes
524 // update slice attributes
525 qreal sliceAngle = m_pieStartAngle;
525 qreal sliceAngle = m_pieStartAngle;
526 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
526 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
527 QVector<QPieSlice*> changed;
527 QVector<QPieSlice*> changed;
528 foreach (QPieSlice* s, m_slices) {
528 foreach (QPieSlice* s, m_slices) {
529
529
530 PieSliceData data = PieSliceData::data(s);
530 PieSliceData data = PieSliceData::data(s);
531 data.m_percentage = s->value() / m_sum;
531 data.m_percentage = s->value() / m_sum;
532 data.m_angleSpan = pieSpan * data.m_percentage;
532 data.m_angleSpan = pieSpan * data.m_percentage;
533 data.m_startAngle = sliceAngle;
533 data.m_startAngle = sliceAngle;
534 sliceAngle += data.m_angleSpan;
534 sliceAngle += data.m_angleSpan;
535
535
536 if (PieSliceData::data(s) != data) {
536 if (PieSliceData::data(s) != data) {
537 PieSliceData::data(s) = data;
537 PieSliceData::data(s) = data;
538 changed << s;
538 changed << s;
539 }
539 }
540 }
540 }
541
541
542 // emit signals
542 // emit signals
543 foreach (QPieSlice* s, changed)
543 foreach (QPieSlice* s, changed)
544 PieSliceData::data(s).emitChangedSignal(s);
544 PieSliceData::data(s).emitChangedSignal(s);
545 }
545 }
546
546
547 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
547 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
548 {
548 {
549 return series.d_func();
549 return series.d_func();
550 }
550 }
551
551
552 void QPieSeriesPrivate::sliceChanged()
552 void QPieSeriesPrivate::sliceChanged()
553 {
553 {
554 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
554 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
555 updateDerivativeData();
555 updateDerivativeData();
556 }
556 }
557
557
558 void QPieSeriesPrivate::sliceClicked()
558 void QPieSeriesPrivate::sliceClicked()
559 {
559 {
560 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
560 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
561 Q_ASSERT(m_slices.contains(slice));
561 Q_ASSERT(m_slices.contains(slice));
562 Q_Q(QPieSeries);
562 Q_Q(QPieSeries);
563 emit q->clicked(slice);
563 emit q->clicked(slice);
564 }
564 }
565
565
566 void QPieSeriesPrivate::sliceHovered(bool state)
566 void QPieSeriesPrivate::sliceHovered(bool state)
567 {
567 {
568 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
568 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
569 Q_ASSERT(m_slices.contains(slice));
569 Q_ASSERT(m_slices.contains(slice));
570 Q_Q(QPieSeries);
570 Q_Q(QPieSeries);
571 emit q->hovered(slice, state);
571 emit q->hovered(slice, state);
572 }
572 }
573
573
574 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
574 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
575 {
575 {
576 if (m_mapper) {
576 if (m_mapper) {
577 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
577 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
578 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
578 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
579 if (m_mapper->orientation() == Qt::Vertical)
579 if (m_mapper->orientation() == Qt::Vertical)
580 {
580 {
581 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
581 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
582 if (topLeft.column() == m_mapper->mapValues())
582 if (topLeft.column() == m_mapper->mapValues())
583 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
583 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
584 if (topLeft.column() == m_mapper->mapLabels())
584 if (topLeft.column() == m_mapper->mapLabels())
585 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
585 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
586 }
586 }
587 }
587 }
588 else
588 else
589 {
589 {
590 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
590 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
591 if (topLeft.row() == m_mapper->mapValues())
591 if (topLeft.row() == m_mapper->mapValues())
592 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
592 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
593 if (topLeft.row() == m_mapper->mapLabels())
593 if (topLeft.row() == m_mapper->mapLabels())
594 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
594 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
595 }
595 }
596 }
596 }
597 }
597 }
598 }
598 }
599 }
599 }
600 }
600 }
601
601
602
602
603 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
603 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
604 {
604 {
605 Q_UNUSED(parent);
605 Q_UNUSED(parent);
606 if (m_mapper) {
606 if (m_mapper) {
607 if (m_mapper->orientation() == Qt::Vertical)
607 if (m_mapper->orientation() == Qt::Vertical)
608 insertData(start, end);
608 insertData(start, end);
609 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
609 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
610 initializePieFromModel();
610 initializePieFromModel();
611 }
611 }
612 }
612 }
613
613
614 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
614 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
615 {
615 {
616 Q_UNUSED(parent);
616 Q_UNUSED(parent);
617 if (m_mapper) {
617 if (m_mapper) {
618 if (m_mapper->orientation() == Qt::Vertical)
618 if (m_mapper->orientation() == Qt::Vertical)
619 removeData(start, end);
619 removeData(start, end);
620 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
620 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
621 initializePieFromModel();
621 initializePieFromModel();
622 }
622 }
623 }
623 }
624
624
625 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
625 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
626 {
626 {
627 Q_UNUSED(parent);
627 Q_UNUSED(parent);
628 if (m_mapper) {
628 if (m_mapper) {
629 if (m_mapper->orientation() == Qt::Horizontal)
629 if (m_mapper->orientation() == Qt::Horizontal)
630 insertData(start, end);
630 insertData(start, end);
631 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
631 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
632 initializePieFromModel();
632 initializePieFromModel();
633 }
633 }
634 }
634 }
635
635
636 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
636 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
637 {
637 {
638 Q_UNUSED(parent);
638 Q_UNUSED(parent);
639 if (m_mapper) {
639 if (m_mapper) {
640 if (m_mapper->orientation() == Qt::Horizontal)
640 if (m_mapper->orientation() == Qt::Horizontal)
641 removeData(start, end);
641 removeData(start, end);
642 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
642 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
643 initializePieFromModel();
643 initializePieFromModel();
644 }
644 }
645 }
645 }
646
646
647 void QPieSeriesPrivate::insertData(int start, int end)
647 void QPieSeriesPrivate::insertData(int start, int end)
648 {
648 {
649 Q_Q(QPieSeries);
649 Q_Q(QPieSeries);
650 if (m_mapper) {
650 if (m_mapper) {
651 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
651 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
652 return;
652 return;
653 } else {
653 } else {
654 int addedCount = end - start + 1;
654 int addedCount = end - start + 1;
655 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
655 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
656 addedCount = m_mapper->count();
656 addedCount = m_mapper->count();
657 int first = qMax(start, m_mapper->first());
657 int first = qMax(start, m_mapper->first());
658 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
658 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
659 for (int i = first; i <= last; i++) {
659 for (int i = first; i <= last; i++) {
660 QPieSlice *slice = new QPieSlice;
660 QPieSlice *slice = new QPieSlice;
661 if (m_mapper->orientation() == Qt::Vertical) {
661 if (m_mapper->orientation() == Qt::Vertical) {
662 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
662 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
663 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
663 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
664 } else {
664 } else {
665 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
665 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
666 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
666 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
667 }
667 }
668 slice->setLabelVisible();
668 slice->setLabelVisible();
669 q->insert(i - m_mapper->first(), slice);
669 q->insert(i - m_mapper->first(), slice);
670 }
670 }
671 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
671 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
672 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
672 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
673 q->remove(q->slices().at(i));
673 q->remove(q->slices().at(i));
674 }
674 }
675 }
675 }
676 }
676 }
677
677
678 void QPieSeriesPrivate::removeData(int start, int end)
678 void QPieSeriesPrivate::removeData(int start, int end)
679 {
679 {
680 Q_Q(QPieSeries);
680 Q_Q(QPieSeries);
681 if (m_mapper) {
681 if (m_mapper) {
682 int removedCount = end - start + 1;
682 int removedCount = end - start + 1;
683 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
683 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
684 return;
684 return;
685 } else {
685 } else {
686 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
686 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
687 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
687 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
688 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
688 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
689 for (int i = last; i >= first; i--)
689 for (int i = last; i >= first; i--)
690 q->remove(q->slices().at(i - m_mapper->first()));
690 q->remove(q->slices().at(i - m_mapper->first()));
691
691
692 if (m_mapper->count() != -1) {
692 if (m_mapper->count() != -1) {
693 int itemsAvailable; // check how many are available to be added
693 int itemsAvailable; // check how many are available to be added
694 if (m_mapper->orientation() == Qt::Vertical)
694 if (m_mapper->orientation() == Qt::Vertical)
695 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
695 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
696 else
696 else
697 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
697 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
698 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
698 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
699 int currentSize = m_slices.size();
699 int currentSize = m_slices.size();
700 if (toBeAdded > 0)
700 if (toBeAdded > 0)
701 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
701 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
702 QPieSlice *slice = new QPieSlice;
702 QPieSlice *slice = new QPieSlice;
703 if (m_mapper->orientation() == Qt::Vertical) {
703 if (m_mapper->orientation() == Qt::Vertical) {
704 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
704 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
705 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
705 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
706 } else {
706 } else {
707 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
707 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
708 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
708 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
709 }
709 }
710 slice->setLabelVisible();
710 slice->setLabelVisible();
711 q->insert(i, slice);
711 q->insert(i, slice);
712 }
712 }
713 }
713 }
714 }
714 }
715 }
715 }
716 }
716 }
717
717
718 void QPieSeriesPrivate::initializePieFromModel()
718 void QPieSeriesPrivate::initializePieFromModel()
719 {
719 {
720 Q_Q(QPieSeries);
720 Q_Q(QPieSeries);
721
721
722 // clear current content
722 // clear current content
723 q->clear();
723 q->clear();
724
724
725 if (m_model == 0 || m_mapper == 0)
725 if (m_model == 0 || m_mapper == 0)
726 return;
726 return;
727
727
728 // check if mappings are set
728 // check if mappings are set
729 if (m_mapper->mapValues() == -1 || m_mapper->mapLabels() == -1)
729 if (m_mapper->mapValues() == -1 || m_mapper->mapLabels() == -1)
730 return;
730 return;
731
731
732 // create the initial slices set
732 // create the initial slices set
733 if (m_mapper->orientation() == Qt::Vertical) {
733 if (m_mapper->orientation() == Qt::Vertical) {
734 if (m_mapper->mapValues() >= m_model->columnCount() || m_mapper->mapLabels() >= m_model->columnCount())
734 if (m_mapper->mapValues() >= m_model->columnCount() || m_mapper->mapLabels() >= m_model->columnCount())
735 return; // mapped columns are not existing
735 return; // mapped columns are not existing
736
736
737 int sliceCount = 0;
737 int sliceCount = 0;
738 if(m_mapper->count() == -1)
738 if(m_mapper->count() == -1)
739 sliceCount = m_model->rowCount() - m_mapper->first();
739 sliceCount = m_model->rowCount() - m_mapper->first();
740 else
740 else
741 sliceCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
741 sliceCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
742 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
742 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
743 q->append(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString(), m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
743 q->append(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString(), m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
744 } else {
744 } else {
745 if (m_mapper->mapValues() >= m_model->rowCount() || m_mapper->mapLabels() >= m_model->rowCount())
745 if (m_mapper->mapValues() >= m_model->rowCount() || m_mapper->mapLabels() >= m_model->rowCount())
746 return; // mapped columns are not existing
746 return; // mapped columns are not existing
747
747
748 int sliceCount = 0;
748 int sliceCount = 0;
749 if(m_mapper->count() == -1)
749 if(m_mapper->count() == -1)
750 sliceCount = m_model->columnCount() - m_mapper->first();
750 sliceCount = m_model->columnCount() - m_mapper->first();
751 else
751 else
752 sliceCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
752 sliceCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
753 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
753 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
754 q->append(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString(), m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
754 q->append(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString(), m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
755 }
755 }
756 q->setLabelsVisible(true);
756 q->setLabelsVisible(true);
757 }
757 }
758
758
759 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
759 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
760 {
760 {
761 // Remove rounding errors
761 // Remove rounding errors
762 qreal roundedValue = newValue;
762 qreal roundedValue = newValue;
763 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
763 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
764 roundedValue = 0.0;
764 roundedValue = 0.0;
765 else if (qFuzzyCompare(newValue, max))
765 else if (qFuzzyCompare(newValue, max))
766 roundedValue = max;
766 roundedValue = max;
767 else if (qFuzzyCompare(newValue, min))
767 else if (qFuzzyCompare(newValue, min))
768 roundedValue = min;
768 roundedValue = min;
769
769
770 // Check if the position is valid after removing the rounding errors
770 // Check if the position is valid after removing the rounding errors
771 if (roundedValue < min || roundedValue > max) {
771 if (roundedValue < min || roundedValue > max) {
772 qWarning("QPieSeries: Illegal value");
772 qWarning("QPieSeries: Illegal value");
773 return false;
773 return false;
774 }
774 }
775
775
776 if (!qFuzzyIsNull(value - roundedValue)) {
776 if (!qFuzzyIsNull(value - roundedValue)) {
777 value = roundedValue;
777 value = roundedValue;
778 return true;
778 return true;
779 }
779 }
780
780
781 // The change was so small it is considered a rounding error
781 // The change was so small it is considered a rounding error
782 return false;
782 return false;
783 }
783 }
784
784
785 void QPieSeriesPrivate::scaleDomain(Domain& domain)
785 void QPieSeriesPrivate::scaleDomain(Domain& domain)
786 {
786 {
787 Q_UNUSED(domain);
787 Q_UNUSED(domain);
788 // does not apply to pie
788 // does not apply to pie
789 }
789 }
790
790
791 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
791 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
792 {
792 {
793 Q_Q(QPieSeries);
793 Q_Q(QPieSeries);
794 PieChartItem* pie = new PieChartItem(q,presenter);
794 PieChartItem* pie = new PieChartItem(q,presenter);
795 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
795 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
796 presenter->animator()->addAnimation(pie);
796 presenter->animator()->addAnimation(pie);
797 }
797 }
798 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
798 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
799 return pie;
799 return pie;
800 }
800 }
801
801
802 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
802 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
803 {
803 {
804 Q_Q(QPieSeries);
804 Q_Q(QPieSeries);
805 QList<LegendMarker*> markers;
805 QList<LegendMarker*> markers;
806 foreach(QPieSlice* slice, q->slices()) {
806 foreach(QPieSlice* slice, q->slices()) {
807 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
807 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
808 markers << marker;
808 markers << marker;
809 }
809 }
810 return markers;
810 return markers;
811 }
811 }
812
812
813 #include "moc_qpieseries.cpp"
813 #include "moc_qpieseries.cpp"
814 #include "moc_qpieseries_p.cpp"
814 #include "moc_qpieseries_p.cpp"
815
815
816 QTCOMMERCIALCHART_END_NAMESPACE
816 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,92 +1,94
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 #ifndef PIESERIES_H
21 #ifndef PIESERIES_H
22 #define PIESERIES_H
22 #define PIESERIES_H
23
23
24 #include <qabstractseries.h>
24 #include <qabstractseries.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 class QPieSeriesPrivate;
27 class QPieSeriesPrivate;
28 class QPieSlice;
28 class QPieSlice;
29 class QPieModelMapper;
29 class QPieModelMapper;
30
30
31 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
31 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
32 {
32 {
33 Q_OBJECT
33 Q_OBJECT
34 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
34 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
35 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
35 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
36 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
36 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
37 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
37 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
38 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
38 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
39 Q_PROPERTY(int count READ count)
39 Q_PROPERTY(int count READ count)
40 Q_PROPERTY(QPieModelMapper *modelMapper READ modelMapper)
40 Q_PROPERTY(QPieModelMapper *modelMapper READ modelMapper)
41
41
42 public:
42 public:
43 explicit QPieSeries(QObject *parent = 0);
43 explicit QPieSeries(QObject *parent = 0);
44 virtual ~QPieSeries();
44 virtual ~QPieSeries();
45
45
46 QAbstractSeries::SeriesType type() const;
46 QAbstractSeries::SeriesType type() const;
47
47
48 bool append(QPieSlice* slice);
48 bool append(QPieSlice* slice);
49 bool append(QList<QPieSlice*> slices);
49 bool append(QList<QPieSlice*> slices);
50 QPieSeries& operator << (QPieSlice* slice);
50 QPieSeries& operator << (QPieSlice* slice);
51 QPieSlice* append(QString label, qreal value);
51 QPieSlice* append(QString label, qreal value);
52 bool insert(int index, QPieSlice* slice);
52 bool insert(int index, QPieSlice* slice);
53 bool remove(QPieSlice* slice);
53 bool remove(QPieSlice* slice);
54 void clear();
54 void clear();
55
55
56 QList<QPieSlice*> slices() const;
56 QList<QPieSlice*> slices() const;
57 int count() const;
57 int count() const;
58 bool isEmpty() const;
58 bool isEmpty() const;
59
59
60 qreal sum() const;
60 qreal sum() const;
61
61
62 void setHorizontalPosition(qreal relativePosition);
62 void setHorizontalPosition(qreal relativePosition);
63 qreal horizontalPosition() const;
63 qreal horizontalPosition() const;
64 void setVerticalPosition(qreal relativePosition);
64 void setVerticalPosition(qreal relativePosition);
65 qreal verticalPosition() const;
65 qreal verticalPosition() const;
66
66
67 void setPieSize(qreal relativeSize);
67 void setPieSize(qreal relativeSize);
68 qreal pieSize() const;
68 qreal pieSize() const;
69
69
70 void setPieStartAngle(qreal startAngle);
70 void setPieStartAngle(qreal startAngle);
71 qreal pieStartAngle() const;
71 qreal pieStartAngle() const;
72 void setPieEndAngle(qreal endAngle);
72 void setPieEndAngle(qreal endAngle);
73 qreal pieEndAngle() const;
73 qreal pieEndAngle() const;
74
74
75 void setLabelsVisible(bool visible = true);
75 void setLabelsVisible(bool visible = true);
76
76
77 void setModel(QAbstractItemModel* model);
77 void setModel(QAbstractItemModel* model);
78 void setModelMapper(QPieModelMapper *mapper);
78 void setModelMapper(QPieModelMapper *mapper);
79 QPieModelMapper* modelMapper() const;
79 QPieModelMapper* modelMapper() const;
80
80
81 Q_SIGNALS:
81 Q_SIGNALS:
82 void added(QList<QPieSlice*> slices);
83 void removed(QList<QPieSlice*> slices);
82 void clicked(QPieSlice* slice);
84 void clicked(QPieSlice* slice);
83 void hovered(QPieSlice* slice, bool state);
85 void hovered(QPieSlice* slice, bool state);
84
86
85 private:
87 private:
86 Q_DECLARE_PRIVATE(QPieSeries)
88 Q_DECLARE_PRIVATE(QPieSeries)
87 Q_DISABLE_COPY(QPieSeries)
89 Q_DISABLE_COPY(QPieSeries)
88 };
90 };
89
91
90 QTCOMMERCIALCHART_END_NAMESPACE
92 QTCOMMERCIALCHART_END_NAMESPACE
91
93
92 #endif // PIESERIES_H
94 #endif // PIESERIES_H
@@ -1,94 +1,92
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 #ifndef QPIESERIES_P_H
21 #ifndef QPIESERIES_P_H
22 #define QPIESERIES_P_H
22 #define QPIESERIES_P_H
23
23
24 #include "qpieseries.h"
24 #include "qpieseries.h"
25 #include "qabstractseries_p.h"
25 #include "qabstractseries_p.h"
26
26
27 class QModelIndex;
27 class QModelIndex;
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 class QLegendPrivate;
30 class QLegendPrivate;
31 class QPieModelMapper;
31 class QPieModelMapper;
32
32
33 class QPieSeriesPrivate : public QAbstractSeriesPrivate
33 class QPieSeriesPrivate : public QAbstractSeriesPrivate
34 {
34 {
35 Q_OBJECT
35 Q_OBJECT
36
36
37 public:
37 public:
38 QPieSeriesPrivate(QPieSeries *parent);
38 QPieSeriesPrivate(QPieSeries *parent);
39 ~QPieSeriesPrivate();
39 ~QPieSeriesPrivate();
40
40
41 void scaleDomain(Domain& domain);
41 void scaleDomain(Domain& domain);
42 Chart* createGraphics(ChartPresenter *presenter);
42 Chart* createGraphics(ChartPresenter *presenter);
43 QList<LegendMarker*> createLegendMarker(QLegend *legend);
43 QList<LegendMarker*> createLegendMarker(QLegend *legend);
44
44
45 void updateDerivativeData();
45 void updateDerivativeData();
46
46
47 static QPieSeriesPrivate* seriesData(QPieSeries &series);
47 static QPieSeriesPrivate* seriesData(QPieSeries &series);
48
48
49 Q_SIGNALS:
49 Q_SIGNALS:
50 void added(QList<QPieSlice*> slices);
51 void removed(QList<QPieSlice*> slices);
52 void piePositionChanged();
50 void piePositionChanged();
53 void pieSizeChanged();
51 void pieSizeChanged();
54
52
55 public Q_SLOTS:
53 public Q_SLOTS:
56 void sliceChanged();
54 void sliceChanged();
57 void sliceClicked();
55 void sliceClicked();
58 void sliceHovered(bool state);
56 void sliceHovered(bool state);
59 void initializePieFromModel();
57 void initializePieFromModel();
60 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
58 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
61 void modelRowsAdded(QModelIndex parent, int start, int end);
59 void modelRowsAdded(QModelIndex parent, int start, int end);
62 void modelRowsRemoved(QModelIndex parent, int start, int end);
60 void modelRowsRemoved(QModelIndex parent, int start, int end);
63 void modelColumnsAdded(QModelIndex parent, int start, int end);
61 void modelColumnsAdded(QModelIndex parent, int start, int end);
64 void modelColumnsRemoved(QModelIndex parent, int start, int end);
62 void modelColumnsRemoved(QModelIndex parent, int start, int end);
65 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
63 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
66
64
67 private:
65 private:
68 void doClear();
66 void doClear();
69 void doRemove(QPieSlice* slice);
67 void doRemove(QPieSlice* slice);
70 void doInsert(int index, QPieSlice* slice);
68 void doInsert(int index, QPieSlice* slice);
71 void insertData(int start, int end);
69 void insertData(int start, int end);
72 void removeData(int start, int end);
70 void removeData(int start, int end);
73
71
74 public:
72 public:
75 QList<QPieSlice*> m_slices;
73 QList<QPieSlice*> m_slices;
76 qreal m_pieRelativeHorPos;
74 qreal m_pieRelativeHorPos;
77 qreal m_pieRelativeVerPos;
75 qreal m_pieRelativeVerPos;
78 qreal m_pieRelativeSize;
76 qreal m_pieRelativeSize;
79 qreal m_pieStartAngle;
77 qreal m_pieStartAngle;
80 qreal m_pieEndAngle;
78 qreal m_pieEndAngle;
81 qreal m_sum;
79 qreal m_sum;
82
80
83 // model
81 // model
84 QAbstractItemModel *m_model;
82 QAbstractItemModel *m_model;
85 QPieModelMapper *m_mapper;
83 QPieModelMapper *m_mapper;
86
84
87 private:
85 private:
88 friend class QLegendPrivate;
86 friend class QLegendPrivate;
89 Q_DECLARE_PUBLIC(QPieSeries)
87 Q_DECLARE_PUBLIC(QPieSeries)
90 };
88 };
91
89
92 QTCOMMERCIALCHART_END_NAMESPACE
90 QTCOMMERCIALCHART_END_NAMESPACE
93
91
94 #endif // QPIESERIES_P_H
92 #endif // QPIESERIES_P_H
General Comments 0
You need to be logged in to leave comments. Login now