##// END OF EJS Templates
bugfix: pie does not disconnect signals when a slice is taken (not deleted)
Jani Honkonen -
r2084:8911fa47051b
parent child
Show More
@@ -1,248 +1,250
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 "qpieslice_p.h"
24 #include "qpieslice_p.h"
25 #include "qpieseries.h"
25 #include "qpieseries.h"
26 #include "qpieseries_p.h"
26 #include "qpieseries_p.h"
27 #include "chartpresenter_p.h"
27 #include "chartpresenter_p.h"
28 #include "chartdataset_p.h"
28 #include "chartdataset_p.h"
29 #include "pieanimation_p.h"
29 #include "pieanimation_p.h"
30 #include <QPainter>
30 #include <QPainter>
31 #include <QTimer>
31 #include <QTimer>
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
34
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
36 :ChartItem(presenter),
36 :ChartItem(presenter),
37 m_series(series),
37 m_series(series),
38 m_animation(0)
38 m_animation(0)
39 {
39 {
40 Q_ASSERT(series);
40 Q_ASSERT(series);
41
41
42 QPieSeriesPrivate *p = QPieSeriesPrivate::fromSeries(series);
42 QPieSeriesPrivate *p = QPieSeriesPrivate::fromSeries(series);
43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
43 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
44 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
44 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
45 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
45 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
46 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
46 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
47 connect(p, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
47 connect(p, SIGNAL(horizontalPositionChanged()), this, SLOT(updateLayout()));
48 connect(p, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
48 connect(p, SIGNAL(verticalPositionChanged()), this, SLOT(updateLayout()));
49 connect(p, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
49 connect(p, SIGNAL(pieSizeChanged()), this, SLOT(updateLayout()));
50 connect(p, SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
50 connect(p, SIGNAL(calculatedDataChanged()), this, SLOT(updateLayout()));
51
51
52 // Note: the following does not affect as long as the item does not have anything to paint
52 // Note: the following does not affect as long as the item does not have anything to paint
53 setZValue(ChartPresenter::PieSeriesZValue);
53 setZValue(ChartPresenter::PieSeriesZValue);
54
54
55 // Note: will not create slice items until we have a proper rectangle to draw on.
55 // Note: will not create slice items until we have a proper rectangle to draw on.
56 }
56 }
57
57
58 PieChartItem::~PieChartItem()
58 PieChartItem::~PieChartItem()
59 {
59 {
60 // slices deleted automatically through QGraphicsItem
60 // slices deleted automatically through QGraphicsItem
61 }
61 }
62
62
63 void PieChartItem::setAnimation(PieAnimation* animation)
63 void PieChartItem::setAnimation(PieAnimation* animation)
64 {
64 {
65 m_animation=animation;
65 m_animation=animation;
66 }
66 }
67
67
68 ChartAnimation* PieChartItem::animation() const
68 ChartAnimation* PieChartItem::animation() const
69 {
69 {
70 return m_animation;
70 return m_animation;
71 }
71 }
72
72
73 void PieChartItem::handleGeometryChanged(const QRectF& rect)
73 void PieChartItem::handleGeometryChanged(const QRectF& rect)
74 {
74 {
75 prepareGeometryChange();
75 prepareGeometryChange();
76 m_rect = rect;
76 m_rect = rect;
77 updateLayout();
77 updateLayout();
78
78
79 // This is for delayed initialization of the slice items during startup.
79 // This is for delayed initialization of the slice items during startup.
80 // It ensures that startup animation originates from the correct position.
80 // It ensures that startup animation originates from the correct position.
81 if (m_sliceItems.isEmpty())
81 if (m_sliceItems.isEmpty())
82 handleSlicesAdded(m_series->slices());
82 handleSlicesAdded(m_series->slices());
83 }
83 }
84
84
85 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
85 void PieChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
86 {
86 {
87 Q_UNUSED(minX);
87 Q_UNUSED(minX);
88 Q_UNUSED(maxX);
88 Q_UNUSED(maxX);
89 Q_UNUSED(minY);
89 Q_UNUSED(minY);
90 Q_UNUSED(maxY);
90 Q_UNUSED(maxY);
91 // does not apply to pie
91 // does not apply to pie
92 }
92 }
93
93
94 void PieChartItem::handleDomainUpdated()
94 void PieChartItem::handleDomainUpdated()
95 {
95 {
96 // does not apply to pie
96 // does not apply to pie
97 }
97 }
98
98
99 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
99 void PieChartItem::rangeXChanged(qreal min, qreal max, int tickXCount)
100 {
100 {
101 Q_UNUSED(min);
101 Q_UNUSED(min);
102 Q_UNUSED(max);
102 Q_UNUSED(max);
103 Q_UNUSED(tickXCount);
103 Q_UNUSED(tickXCount);
104 // does not apply to pie
104 // does not apply to pie
105 }
105 }
106
106
107 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
107 void PieChartItem::rangeYChanged(qreal min, qreal max, int tickYCount)
108 {
108 {
109 Q_UNUSED(min);
109 Q_UNUSED(min);
110 Q_UNUSED(max);
110 Q_UNUSED(max);
111 Q_UNUSED(tickYCount);
111 Q_UNUSED(tickYCount);
112 // does not apply to pie
112 // does not apply to pie
113 }
113 }
114
114
115 void PieChartItem::updateLayout()
115 void PieChartItem::updateLayout()
116 {
116 {
117 // find pie center coordinates
117 // find pie center coordinates
118 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
118 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition()));
119 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
119 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition()));
120
120
121 // find maximum radius for pie
121 // find maximum radius for pie
122 m_pieRadius = m_rect.height() / 2;
122 m_pieRadius = m_rect.height() / 2;
123 if (m_rect.width() < m_rect.height())
123 if (m_rect.width() < m_rect.height())
124 m_pieRadius = m_rect.width() / 2;
124 m_pieRadius = m_rect.width() / 2;
125
125
126 m_holeSize = m_pieRadius;
126 m_holeSize = m_pieRadius;
127 // apply size factor
127 // apply size factor
128 m_pieRadius *= m_series->pieSize();
128 m_pieRadius *= m_series->pieSize();
129 m_holeSize *= m_series->holeSize();
129 m_holeSize *= m_series->holeSize();
130
130
131 // set layouts for existing slice items
131 // set layouts for existing slice items
132 foreach (QPieSlice* slice, m_series->slices()) {
132 foreach (QPieSlice* slice, m_series->slices()) {
133 PieSliceItem *sliceItem = m_sliceItems.value(slice);
133 PieSliceItem *sliceItem = m_sliceItems.value(slice);
134 if (sliceItem) {
134 if (sliceItem) {
135 PieSliceData sliceData = updateSliceGeometry(slice);
135 PieSliceData sliceData = updateSliceGeometry(slice);
136 if (m_animation){
136 if (m_animation){
137 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
137 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
138 }
138 }
139 else
139 else
140 sliceItem->setLayout(sliceData);
140 sliceItem->setLayout(sliceData);
141 }
141 }
142 }
142 }
143
143
144 update();
144 update();
145 }
145 }
146
146
147 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
147 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
148 {
148 {
149 // delay creating slice items until there is a proper rectangle
149 // delay creating slice items until there is a proper rectangle
150 if (!m_rect.isValid() && m_sliceItems.isEmpty())
150 if (!m_rect.isValid() && m_sliceItems.isEmpty())
151 return;
151 return;
152
152
153 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
153 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
154
154
155 bool startupAnimation = m_sliceItems.isEmpty();
155 bool startupAnimation = m_sliceItems.isEmpty();
156
156
157 foreach (QPieSlice *slice, slices) {
157 foreach (QPieSlice *slice, slices) {
158 PieSliceItem* sliceItem = new PieSliceItem(this);
158 PieSliceItem* sliceItem = new PieSliceItem(this);
159 m_sliceItems.insert(slice, sliceItem);
159 m_sliceItems.insert(slice, sliceItem);
160
160
161 // Note: no need to connect to slice valueChanged() etc.
161 // Note: no need to connect to slice valueChanged() etc.
162 // This is handled through calculatedDataChanged signal.
162 // This is handled through calculatedDataChanged signal.
163 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
163 connect(slice, SIGNAL(labelChanged()), this, SLOT(handleSliceChanged()));
164 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
164 connect(slice, SIGNAL(labelVisibleChanged()), this, SLOT(handleSliceChanged()));
165 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
165 connect(slice, SIGNAL(penChanged()), this, SLOT(handleSliceChanged()));
166 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
166 connect(slice, SIGNAL(brushChanged()), this, SLOT(handleSliceChanged()));
167 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
167 connect(slice, SIGNAL(labelBrushChanged()), this, SLOT(handleSliceChanged()));
168 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
168 connect(slice, SIGNAL(labelFontChanged()), this, SLOT(handleSliceChanged()));
169
169
170 QPieSlicePrivate *p = QPieSlicePrivate::fromSlice(slice);
170 QPieSlicePrivate *p = QPieSlicePrivate::fromSlice(slice);
171 connect(p, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
171 connect(p, SIGNAL(labelPositionChanged()), this, SLOT(handleSliceChanged()));
172 connect(p, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
172 connect(p, SIGNAL(explodedChanged()), this, SLOT(handleSliceChanged()));
173 connect(p, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
173 connect(p, SIGNAL(labelArmLengthFactorChanged()), this, SLOT(handleSliceChanged()));
174 connect(p, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
174 connect(p, SIGNAL(explodeDistanceFactorChanged()), this, SLOT(handleSliceChanged()));
175
175
176 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
176 connect(sliceItem, SIGNAL(clicked(Qt::MouseButtons)), slice, SIGNAL(clicked()));
177 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
177 connect(sliceItem, SIGNAL(hovered(bool)), slice, SIGNAL(hovered(bool)));
178
178
179 PieSliceData sliceData = updateSliceGeometry(slice);
179 PieSliceData sliceData = updateSliceGeometry(slice);
180 if (m_animation)
180 if (m_animation)
181 presenter()->startAnimation(m_animation->addSlice(sliceItem, sliceData, startupAnimation));
181 presenter()->startAnimation(m_animation->addSlice(sliceItem, sliceData, startupAnimation));
182 else
182 else
183 sliceItem->setLayout(sliceData);
183 sliceItem->setLayout(sliceData);
184 }
184 }
185 }
185 }
186
186
187 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
187 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
188 {
188 {
189 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
189 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
190
190
191 foreach (QPieSlice *slice, slices) {
191 foreach (QPieSlice *slice, slices) {
192
192
193 PieSliceItem *sliceItem = m_sliceItems.value(slice);
193 PieSliceItem *sliceItem = m_sliceItems.value(slice);
194
194
195 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
195 // this can happen if you call append() & remove() in a row so that PieSliceItem is not even created
196 if (!sliceItem)
196 if (!sliceItem)
197 continue;
197 continue;
198
198
199 m_sliceItems.remove(slice);
199 m_sliceItems.remove(slice);
200 slice->disconnect(this);
201 QPieSlicePrivate::fromSlice(slice)->disconnect(this);
200
202
201 if (m_animation)
203 if (m_animation)
202 presenter()->startAnimation(m_animation->removeSlice(sliceItem)); // animator deletes the PieSliceItem
204 presenter()->startAnimation(m_animation->removeSlice(sliceItem)); // animator deletes the PieSliceItem
203 else
205 else
204 delete sliceItem;
206 delete sliceItem;
205 }
207 }
206 }
208 }
207
209
208 void PieChartItem::handleSliceChanged()
210 void PieChartItem::handleSliceChanged()
209 {
211 {
210 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
212 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
211 if (!slice) {
213 if (!slice) {
212 QPieSlicePrivate* slicep = qobject_cast<QPieSlicePrivate *>(sender());
214 QPieSlicePrivate* slicep = qobject_cast<QPieSlicePrivate *>(sender());
213 slice = slicep->q_ptr;
215 slice = slicep->q_ptr;
214 }
216 }
215 Q_ASSERT(m_sliceItems.contains(slice));
217 Q_ASSERT(m_sliceItems.contains(slice));
216
218
217 PieSliceItem *sliceItem = m_sliceItems.value(slice);
219 PieSliceItem *sliceItem = m_sliceItems.value(slice);
218 PieSliceData sliceData = updateSliceGeometry(slice);
220 PieSliceData sliceData = updateSliceGeometry(slice);
219 if (m_animation)
221 if (m_animation)
220 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
222 presenter()->startAnimation(m_animation->updateValue(sliceItem, sliceData));
221 else
223 else
222 sliceItem->setLayout(sliceData);
224 sliceItem->setLayout(sliceData);
223
225
224 update();
226 update();
225 }
227 }
226
228
227 void PieChartItem::handleSeriesVisibleChanged()
229 void PieChartItem::handleSeriesVisibleChanged()
228 {
230 {
229 setVisible(m_series->isVisible());
231 setVisible(m_series->isVisible());
230 }
232 }
231
233
232 void PieChartItem::handleOpacityChanged()
234 void PieChartItem::handleOpacityChanged()
233 {
235 {
234 setOpacity(m_series->opacity());
236 setOpacity(m_series->opacity());
235 }
237 }
236
238
237 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
239 PieSliceData PieChartItem::updateSliceGeometry(QPieSlice *slice)
238 {
240 {
239 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
241 PieSliceData &sliceData = QPieSlicePrivate::fromSlice(slice)->m_data;
240 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
242 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
241 sliceData.m_radius = m_pieRadius;
243 sliceData.m_radius = m_pieRadius;
242 sliceData.m_holeRadius = m_holeSize;
244 sliceData.m_holeRadius = m_holeSize;
243 return sliceData;
245 return sliceData;
244 }
246 }
245
247
246 #include "moc_piechartitem_p.cpp"
248 #include "moc_piechartitem_p.cpp"
247
249
248 QTCOMMERCIALCHART_END_NAMESPACE
250 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,896 +1,898
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 "qpieslice_p.h"
24 #include "qpieslice_p.h"
25 #include "pieslicedata_p.h"
25 #include "pieslicedata_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "charttheme_p.h"
27 #include "charttheme_p.h"
28 #include "legendmarker_p.h"
28 #include "legendmarker_p.h"
29 #include "qabstractaxis.h"
29 #include "qabstractaxis.h"
30 #include "pieanimation_p.h"
30 #include "pieanimation_p.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} or \l {DonutChart Example} {donut chart example} to learn how to use QPieSeries.
49 See the \l {PieChart Example} {pie chart example} or \l {DonutChart Example} {donut chart example} to learn how to use QPieSeries.
50 \table 100%
50 \table 100%
51 \row
51 \row
52 \o \image examples_piechart.png
52 \o \image examples_piechart.png
53 \o \image examples_donut.png
53 \o \image examples_donut.png
54 \endtable
54 \endtable
55 */
55 */
56 /*!
56 /*!
57 \qmlclass PieSeries QPieSeries
57 \qmlclass PieSeries QPieSeries
58 \inherits AbstractSeries
58 \inherits AbstractSeries
59
59
60 The following QML shows how to create a simple pie chart.
60 The following QML shows how to create a simple pie chart.
61
61
62 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
62 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
63
63
64 \beginfloatleft
64 \beginfloatleft
65 \image demos_qmlchart1.png
65 \image demos_qmlchart1.png
66 \endfloat
66 \endfloat
67 \clearfloat
67 \clearfloat
68 */
68 */
69
69
70 /*!
70 /*!
71 \property QPieSeries::horizontalPosition
71 \property QPieSeries::horizontalPosition
72 \brief Defines the horizontal position of the pie.
72 \brief Defines the horizontal position of the pie.
73
73
74 The value is a relative value to the chart rectangle where:
74 The value is a relative value to the chart rectangle where:
75
75
76 \list
76 \list
77 \o 0.0 is the absolute left.
77 \o 0.0 is the absolute left.
78 \o 1.0 is the absolute right.
78 \o 1.0 is the absolute right.
79 \endlist
79 \endlist
80 Default value is 0.5 (center).
80 Default value is 0.5 (center).
81 \sa verticalPosition
81 \sa verticalPosition
82 */
82 */
83
83
84 /*!
84 /*!
85 \qmlproperty real PieSeries::horizontalPosition
85 \qmlproperty real PieSeries::horizontalPosition
86
86
87 Defines the horizontal position of the pie.
87 Defines the horizontal position of the pie.
88
88
89 The value is a relative value to the chart rectangle where:
89 The value is a relative value to the chart rectangle where:
90
90
91 \list
91 \list
92 \o 0.0 is the absolute left.
92 \o 0.0 is the absolute left.
93 \o 1.0 is the absolute right.
93 \o 1.0 is the absolute right.
94 \endlist
94 \endlist
95 Default value is 0.5 (center).
95 Default value is 0.5 (center).
96 \sa verticalPosition
96 \sa verticalPosition
97 */
97 */
98
98
99 /*!
99 /*!
100 \property QPieSeries::verticalPosition
100 \property QPieSeries::verticalPosition
101 \brief Defines the vertical position of the pie.
101 \brief Defines the vertical position of the pie.
102
102
103 The value is a relative value to the chart rectangle where:
103 The value is a relative value to the chart rectangle where:
104
104
105 \list
105 \list
106 \o 0.0 is the absolute top.
106 \o 0.0 is the absolute top.
107 \o 1.0 is the absolute bottom.
107 \o 1.0 is the absolute bottom.
108 \endlist
108 \endlist
109 Default value is 0.5 (center).
109 Default value is 0.5 (center).
110 \sa horizontalPosition
110 \sa horizontalPosition
111 */
111 */
112
112
113 /*!
113 /*!
114 \qmlproperty real PieSeries::verticalPosition
114 \qmlproperty real PieSeries::verticalPosition
115
115
116 Defines the vertical position of the pie.
116 Defines the vertical position of the pie.
117
117
118 The value is a relative value to the chart rectangle where:
118 The value is a relative value to the chart rectangle where:
119
119
120 \list
120 \list
121 \o 0.0 is the absolute top.
121 \o 0.0 is the absolute top.
122 \o 1.0 is the absolute bottom.
122 \o 1.0 is the absolute bottom.
123 \endlist
123 \endlist
124 Default value is 0.5 (center).
124 Default value is 0.5 (center).
125 \sa horizontalPosition
125 \sa horizontalPosition
126 */
126 */
127
127
128 /*!
128 /*!
129 \property QPieSeries::size
129 \property QPieSeries::size
130 \brief Defines the pie size.
130 \brief Defines the pie size.
131
131
132 The value is a relative value to the chart rectangle where:
132 The value is a relative value to the chart rectangle where:
133
133
134 \list
134 \list
135 \o 0.0 is the minimum size (pie not drawn).
135 \o 0.0 is the minimum size (pie not drawn).
136 \o 1.0 is the maximum size that can fit the chart.
136 \o 1.0 is the maximum size that can fit the chart.
137 \endlist
137 \endlist
138
138
139 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
139 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
140
140
141 Default value is 0.7.
141 Default value is 0.7.
142 */
142 */
143
143
144 /*!
144 /*!
145 \qmlproperty real PieSeries::size
145 \qmlproperty real PieSeries::size
146
146
147 Defines the pie size.
147 Defines the pie size.
148
148
149 The value is a relative value to the chart rectangle where:
149 The value is a relative value to the chart rectangle where:
150
150
151 \list
151 \list
152 \o 0.0 is the minimum size (pie not drawn).
152 \o 0.0 is the minimum size (pie not drawn).
153 \o 1.0 is the maximum size that can fit the chart.
153 \o 1.0 is the maximum size that can fit the chart.
154 \endlist
154 \endlist
155
155
156 Default value is 0.7.
156 Default value is 0.7.
157 */
157 */
158
158
159 /*!
159 /*!
160 \property QPieSeries::holeSize
160 \property QPieSeries::holeSize
161 \brief Defines the donut hole size.
161 \brief Defines the donut hole size.
162
162
163 The value is a relative value to the chart rectangle where:
163 The value is a relative value to the chart rectangle where:
164
164
165 \list
165 \list
166 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
166 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
167 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
167 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
168 \endlist
168 \endlist
169
169
170 The value is never greater then size property.
170 The value is never greater then size property.
171 Default value is 0.0.
171 Default value is 0.0.
172 */
172 */
173
173
174 /*!
174 /*!
175 \qmlproperty real PieSeries::holeSize
175 \qmlproperty real PieSeries::holeSize
176
176
177 Defines the donut hole size.
177 Defines the donut hole size.
178
178
179 The value is a relative value to the chart rectangle where:
179 The value is a relative value to the chart rectangle where:
180
180
181 \list
181 \list
182 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
182 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
183 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
183 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
184 \endlist
184 \endlist
185
185
186 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
186 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
187
187
188 Default value is 0.0.
188 Default value is 0.0.
189 */
189 */
190
190
191 /*!
191 /*!
192 \property QPieSeries::startAngle
192 \property QPieSeries::startAngle
193 \brief Defines the starting angle of the pie.
193 \brief Defines the starting angle of the pie.
194
194
195 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
195 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
196
196
197 Default is value is 0.
197 Default is value is 0.
198 */
198 */
199
199
200 /*!
200 /*!
201 \qmlproperty real PieSeries::startAngle
201 \qmlproperty real PieSeries::startAngle
202
202
203 Defines the starting angle of the pie.
203 Defines the starting angle of the pie.
204
204
205 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
205 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
206
206
207 Default is value is 0.
207 Default is value is 0.
208 */
208 */
209
209
210 /*!
210 /*!
211 \property QPieSeries::endAngle
211 \property QPieSeries::endAngle
212 \brief Defines the ending angle of the pie.
212 \brief Defines the ending angle of the pie.
213
213
214 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
214 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
215
215
216 Default is value is 360.
216 Default is value is 360.
217 */
217 */
218
218
219 /*!
219 /*!
220 \qmlproperty real PieSeries::endAngle
220 \qmlproperty real PieSeries::endAngle
221
221
222 Defines the ending angle of the pie.
222 Defines the ending angle of the pie.
223
223
224 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
224 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
225
225
226 Default is value is 360.
226 Default is value is 360.
227 */
227 */
228
228
229 /*!
229 /*!
230 \property QPieSeries::count
230 \property QPieSeries::count
231
231
232 Number of slices in the series.
232 Number of slices in the series.
233 */
233 */
234
234
235 /*!
235 /*!
236 \qmlproperty int PieSeries::count
236 \qmlproperty int PieSeries::count
237
237
238 Number of slices in the series.
238 Number of slices in the series.
239 */
239 */
240
240
241 /*!
241 /*!
242 \fn void QPieSeries::countChanged()
242 \fn void QPieSeries::countChanged()
243 Emitted when the slice count has changed.
243 Emitted when the slice count has changed.
244 \sa count
244 \sa count
245 */
245 */
246 /*!
246 /*!
247 \qmlsignal PieSeries::onCountChanged()
247 \qmlsignal PieSeries::onCountChanged()
248 Emitted when the slice count has changed.
248 Emitted when the slice count has changed.
249 */
249 */
250
250
251 /*!
251 /*!
252 \property QPieSeries::sum
252 \property QPieSeries::sum
253
253
254 Sum of all slices.
254 Sum of all slices.
255
255
256 The series keeps track of the sum of all slices it holds.
256 The series keeps track of the sum of all slices it holds.
257 */
257 */
258
258
259 /*!
259 /*!
260 \qmlproperty real PieSeries::sum
260 \qmlproperty real PieSeries::sum
261
261
262 Sum of all slices.
262 Sum of all slices.
263
263
264 The series keeps track of the sum of all slices it holds.
264 The series keeps track of the sum of all slices it holds.
265 */
265 */
266
266
267 /*!
267 /*!
268 \fn void QPieSeries::sumChanged()
268 \fn void QPieSeries::sumChanged()
269 Emitted when the sum of all slices has changed.
269 Emitted when the sum of all slices has changed.
270 \sa sum
270 \sa sum
271 */
271 */
272 /*!
272 /*!
273 \qmlsignal PieSeries::onSumChanged()
273 \qmlsignal PieSeries::onSumChanged()
274 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
274 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
275 change value of a slice.
275 change value of a slice.
276 */
276 */
277
277
278 /*!
278 /*!
279 \fn void QPieSeries::added(QList<QPieSlice*> slices)
279 \fn void QPieSeries::added(QList<QPieSlice*> slices)
280
280
281 This signal is emitted when \a slices have been added to the series.
281 This signal is emitted when \a slices have been added to the series.
282
282
283 \sa append(), insert()
283 \sa append(), insert()
284 */
284 */
285 /*!
285 /*!
286 \qmlsignal PieSeries::onAdded(PieSlice slice)
286 \qmlsignal PieSeries::onAdded(PieSlice slice)
287 Emitted when \a slice has been added to the series.
287 Emitted when \a slice has been added to the series.
288 */
288 */
289
289
290 /*!
290 /*!
291 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
291 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
292 This signal is emitted when \a slices have been removed from the series.
292 This signal is emitted when \a slices have been removed from the series.
293 \sa remove()
293 \sa remove()
294 */
294 */
295 /*!
295 /*!
296 \qmlsignal PieSeries::onRemoved(PieSlice slice)
296 \qmlsignal PieSeries::onRemoved(PieSlice slice)
297 Emitted when \a slice has been removed from the series.
297 Emitted when \a slice has been removed from the series.
298 */
298 */
299
299
300 /*!
300 /*!
301 \fn void QPieSeries::clicked(QPieSlice* slice)
301 \fn void QPieSeries::clicked(QPieSlice* slice)
302 This signal is emitted when a \a slice has been clicked.
302 This signal is emitted when a \a slice has been clicked.
303 \sa QPieSlice::clicked()
303 \sa QPieSlice::clicked()
304 */
304 */
305 /*!
305 /*!
306 \qmlsignal PieSeries::onClicked(PieSlice slice)
306 \qmlsignal PieSeries::onClicked(PieSlice slice)
307 This signal is emitted when a \a slice has been clicked.
307 This signal is emitted when a \a slice has been clicked.
308 */
308 */
309
309
310 /*!
310 /*!
311 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
311 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
312 This signal is emitted when user has hovered over or away from the \a slice.
312 This signal is emitted when user has hovered over or away from the \a slice.
313 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
313 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
314 \sa QPieSlice::hovered()
314 \sa QPieSlice::hovered()
315 */
315 */
316 /*!
316 /*!
317 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
317 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
318 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
318 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
319 over the slice and false when hover has moved away from the slice.
319 over the slice and false when hover has moved away from the slice.
320 */
320 */
321
321
322 /*!
322 /*!
323 \qmlmethod PieSlice PieSeries::at(int index)
323 \qmlmethod PieSlice PieSeries::at(int index)
324 Returns slice at \a index. Returns null if the index is not valid.
324 Returns slice at \a index. Returns null if the index is not valid.
325 */
325 */
326
326
327 /*!
327 /*!
328 \qmlmethod PieSlice PieSeries::find(string label)
328 \qmlmethod PieSlice PieSeries::find(string label)
329 Returns the first slice with \a label. Returns null if the index is not valid.
329 Returns the first slice with \a label. Returns null if the index is not valid.
330 */
330 */
331
331
332 /*!
332 /*!
333 \qmlmethod PieSlice PieSeries::append(string label, real value)
333 \qmlmethod PieSlice PieSeries::append(string label, real value)
334 Adds a new slice with \a label and \a value to the pie.
334 Adds a new slice with \a label and \a value to the pie.
335 */
335 */
336
336
337 /*!
337 /*!
338 \qmlmethod bool PieSeries::remove(PieSlice slice)
338 \qmlmethod bool PieSeries::remove(PieSlice slice)
339 Removes the \a slice from the pie. Returns true if the removal was successful, false otherwise.
339 Removes the \a slice from the pie. Returns true if the removal was successful, false otherwise.
340 */
340 */
341
341
342 /*!
342 /*!
343 \qmlmethod PieSeries::clear()
343 \qmlmethod PieSeries::clear()
344 Removes all slices from the pie.
344 Removes all slices from the pie.
345 */
345 */
346
346
347 /*!
347 /*!
348 Constructs a series object which is a child of \a parent.
348 Constructs a series object which is a child of \a parent.
349 */
349 */
350 QPieSeries::QPieSeries(QObject *parent) :
350 QPieSeries::QPieSeries(QObject *parent) :
351 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
351 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
352 {
352 {
353
353
354 }
354 }
355
355
356 /*!
356 /*!
357 Destroys the series and its slices.
357 Destroys the series and its slices.
358 */
358 */
359 QPieSeries::~QPieSeries()
359 QPieSeries::~QPieSeries()
360 {
360 {
361 // NOTE: d_prt destroyed by QObject
361 // NOTE: d_prt destroyed by QObject
362 }
362 }
363
363
364 /*!
364 /*!
365 Returns QChartSeries::SeriesTypePie.
365 Returns QChartSeries::SeriesTypePie.
366 */
366 */
367 QAbstractSeries::SeriesType QPieSeries::type() const
367 QAbstractSeries::SeriesType QPieSeries::type() const
368 {
368 {
369 return QAbstractSeries::SeriesTypePie;
369 return QAbstractSeries::SeriesTypePie;
370 }
370 }
371
371
372 /*!
372 /*!
373 Appends a single \a slice to the series.
373 Appends a single \a slice to the series.
374 Slice ownership is passed to the series.
374 Slice ownership is passed to the series.
375
375
376 Returns true if append was succesfull.
376 Returns true if append was succesfull.
377 */
377 */
378 bool QPieSeries::append(QPieSlice* slice)
378 bool QPieSeries::append(QPieSlice* slice)
379 {
379 {
380 return append(QList<QPieSlice*>() << slice);
380 return append(QList<QPieSlice*>() << slice);
381 }
381 }
382
382
383 /*!
383 /*!
384 Appends an array of \a slices to the series.
384 Appends an array of \a slices to the series.
385 Slice ownership is passed to the series.
385 Slice ownership is passed to the series.
386
386
387 Returns true if append was successful.
387 Returns true if append was successful.
388 */
388 */
389 bool QPieSeries::append(QList<QPieSlice*> slices)
389 bool QPieSeries::append(QList<QPieSlice*> slices)
390 {
390 {
391 Q_D(QPieSeries);
391 Q_D(QPieSeries);
392
392
393 if (slices.count() == 0)
393 if (slices.count() == 0)
394 return false;
394 return false;
395
395
396 foreach (QPieSlice* s, slices) {
396 foreach (QPieSlice* s, slices) {
397 if (!s || d->m_slices.contains(s))
397 if (!s || d->m_slices.contains(s))
398 return false;
398 return false;
399 if (s->series()) // already added to some series
399 if (s->series()) // already added to some series
400 return false;
400 return false;
401 }
401 }
402
402
403 foreach (QPieSlice* s, slices) {
403 foreach (QPieSlice* s, slices) {
404 s->setParent(this);
404 s->setParent(this);
405 QPieSlicePrivate::fromSlice(s)->m_series = this;
405 QPieSlicePrivate::fromSlice(s)->m_series = this;
406 d->m_slices << s;
406 d->m_slices << s;
407 }
407 }
408
408
409 d->updateDerivativeData();
409 d->updateDerivativeData();
410
410
411 foreach (QPieSlice* s, slices) {
411 foreach (QPieSlice* s, slices) {
412 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
412 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
413 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
413 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
414 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
414 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
415
415
416 connect(s, SIGNAL(labelChanged()), d, SLOT(updateLegendProperties()));
416 connect(s, SIGNAL(labelChanged()), d, SLOT(updateLegendProperties()));
417 connect(s, SIGNAL(penChanged()), d, SLOT(updateLegendProperties()));
417 connect(s, SIGNAL(penChanged()), d, SLOT(updateLegendProperties()));
418 connect(s, SIGNAL(brushChanged()), d, SLOT(updateLegendProperties()));
418 connect(s, SIGNAL(brushChanged()), d, SLOT(updateLegendProperties()));
419 connect(s, SIGNAL(labelBrushChanged()), d, SLOT(updateLegendProperties()));
419 connect(s, SIGNAL(labelBrushChanged()), d, SLOT(updateLegendProperties()));
420 connect(s, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
420 connect(s, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
421 connect(s, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
421 connect(s, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
422 }
422 }
423
423
424 emit added(slices);
424 emit added(slices);
425 emit countChanged();
425 emit countChanged();
426
426
427 return true;
427 return true;
428 }
428 }
429
429
430 /*!
430 /*!
431 Appends a single \a slice to the series and returns a reference to the series.
431 Appends a single \a slice to the series and returns a reference to the series.
432 Slice ownership is passed to the series.
432 Slice ownership is passed to the series.
433 */
433 */
434 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
434 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
435 {
435 {
436 append(slice);
436 append(slice);
437 return *this;
437 return *this;
438 }
438 }
439
439
440
440
441 /*!
441 /*!
442 Appends a single slice to the series with give \a value and \a label.
442 Appends a single slice to the series with give \a value and \a label.
443 Slice ownership is passed to the series.
443 Slice ownership is passed to the series.
444 */
444 */
445 QPieSlice* QPieSeries::append(QString label, qreal value)
445 QPieSlice* QPieSeries::append(QString label, qreal value)
446 {
446 {
447 QPieSlice* slice = new QPieSlice(label, value);
447 QPieSlice* slice = new QPieSlice(label, value);
448 append(slice);
448 append(slice);
449 return slice;
449 return slice;
450 }
450 }
451
451
452 /*!
452 /*!
453 Inserts a single \a slice to the series before the slice at \a index position.
453 Inserts a single \a slice to the series before the slice at \a index position.
454 Slice ownership is passed to the series.
454 Slice ownership is passed to the series.
455
455
456 Returns true if insert was successful.
456 Returns true if insert was successful.
457 */
457 */
458 bool QPieSeries::insert(int index, QPieSlice* slice)
458 bool QPieSeries::insert(int index, QPieSlice* slice)
459 {
459 {
460 Q_D(QPieSeries);
460 Q_D(QPieSeries);
461
461
462 if (index < 0 || index > d->m_slices.count())
462 if (index < 0 || index > d->m_slices.count())
463 return false;
463 return false;
464
464
465 if (!slice || d->m_slices.contains(slice))
465 if (!slice || d->m_slices.contains(slice))
466 return false;
466 return false;
467
467
468 if (slice->series()) // already added to some series
468 if (slice->series()) // already added to some series
469 return false;
469 return false;
470
470
471 slice->setParent(this);
471 slice->setParent(this);
472 QPieSlicePrivate::fromSlice(slice)->m_series = this;
472 QPieSlicePrivate::fromSlice(slice)->m_series = this;
473 d->m_slices.insert(index, slice);
473 d->m_slices.insert(index, slice);
474
474
475 d->updateDerivativeData();
475 d->updateDerivativeData();
476
476
477 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
477 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
478 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
478 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
479 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
479 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
480
480
481 connect(slice, SIGNAL(labelChanged()), d, SLOT(updateLegendProperties()));
481 connect(slice, SIGNAL(labelChanged()), d, SLOT(updateLegendProperties()));
482 connect(slice, SIGNAL(penChanged()), d, SLOT(updateLegendProperties()));
482 connect(slice, SIGNAL(penChanged()), d, SLOT(updateLegendProperties()));
483 connect(slice, SIGNAL(brushChanged()), d, SLOT(updateLegendProperties()));
483 connect(slice, SIGNAL(brushChanged()), d, SLOT(updateLegendProperties()));
484 connect(slice, SIGNAL(labelBrushChanged()), d, SLOT(updateLegendProperties()));
484 connect(slice, SIGNAL(labelBrushChanged()), d, SLOT(updateLegendProperties()));
485 connect(slice, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
485 connect(slice, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
486 connect(slice, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
486 connect(slice, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
487
487
488 emit added(QList<QPieSlice*>() << slice);
488 emit added(QList<QPieSlice*>() << slice);
489 emit countChanged();
489 emit countChanged();
490
490
491 return true;
491 return true;
492 }
492 }
493
493
494 /*!
494 /*!
495 Removes a single \a slice from the series and deletes the slice.
495 Removes a single \a slice from the series and deletes the slice.
496
496
497 Do not reference the pointer after this call.
497 Do not reference the pointer after this call.
498
498
499 Returns true if remove was successful.
499 Returns true if remove was successful.
500 */
500 */
501 bool QPieSeries::remove(QPieSlice* slice)
501 bool QPieSeries::remove(QPieSlice* slice)
502 {
502 {
503 Q_D(QPieSeries);
503 Q_D(QPieSeries);
504
504
505 if (!d->m_slices.removeOne(slice))
505 if (!d->m_slices.removeOne(slice))
506 return false;
506 return false;
507
507
508 d->updateDerivativeData();
508 d->updateDerivativeData();
509
509
510 emit removed(QList<QPieSlice*>() << slice);
510 emit removed(QList<QPieSlice*>() << slice);
511 emit countChanged();
511 emit countChanged();
512
512
513 delete slice;
513 delete slice;
514 slice = 0;
514 slice = 0;
515
515
516 return true;
516 return true;
517 }
517 }
518
518
519 /*!
519 /*!
520 Takes a single \a slice from the series. Does not destroy the slice object.
520 Takes a single \a slice from the series. Does not destroy the slice object.
521
521
522 NOTE: The series remains as the slice's parent object. You must set the
522 NOTE: The series remains as the slice's parent object. You must set the
523 parent object to take full ownership.
523 parent object to take full ownership.
524
524
525 Returns true if take was successful.
525 Returns true if take was successful.
526 */
526 */
527 bool QPieSeries::take(QPieSlice* slice)
527 bool QPieSeries::take(QPieSlice* slice)
528 {
528 {
529 Q_D(QPieSeries);
529 Q_D(QPieSeries);
530
530
531 if (!d->m_slices.removeOne(slice))
531 if (!d->m_slices.removeOne(slice))
532 return false;
532 return false;
533
533
534 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
534 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
535 slice->disconnect(d);
535
536
536 d->updateDerivativeData();
537 d->updateDerivativeData();
537
538
538 emit removed(QList<QPieSlice*>() << slice);
539 emit removed(QList<QPieSlice*>() << slice);
539 emit countChanged();
540 emit countChanged();
540
541
541 return true;
542 return true;
542 }
543 }
543
544
544 /*!
545 /*!
545 Clears all slices from the series.
546 Clears all slices from the series.
546 */
547 */
547 void QPieSeries::clear()
548 void QPieSeries::clear()
548 {
549 {
549 Q_D(QPieSeries);
550 Q_D(QPieSeries);
550 if (d->m_slices.count() == 0)
551 if (d->m_slices.count() == 0)
551 return;
552 return;
552
553
553 QList<QPieSlice*> slices = d->m_slices;
554 QList<QPieSlice*> slices = d->m_slices;
554 foreach (QPieSlice* s, d->m_slices) {
555 foreach (QPieSlice* s, d->m_slices)
555 d->m_slices.removeOne(s);
556 d->m_slices.removeOne(s);
556 delete s;
557 }
558
557
559 d->updateDerivativeData();
558 d->updateDerivativeData();
560
559
561 emit removed(slices);
560 emit removed(slices);
562 emit countChanged();
561 emit countChanged();
562
563 foreach (QPieSlice* s, slices)
564 delete s;
563 }
565 }
564
566
565 /*!
567 /*!
566 Returns a list of slices that belong to this series.
568 Returns a list of slices that belong to this series.
567 */
569 */
568 QList<QPieSlice*> QPieSeries::slices() const
570 QList<QPieSlice*> QPieSeries::slices() const
569 {
571 {
570 Q_D(const QPieSeries);
572 Q_D(const QPieSeries);
571 return d->m_slices;
573 return d->m_slices;
572 }
574 }
573
575
574 /*!
576 /*!
575 returns the number of the slices in this series.
577 returns the number of the slices in this series.
576 */
578 */
577 int QPieSeries::count() const
579 int QPieSeries::count() const
578 {
580 {
579 Q_D(const QPieSeries);
581 Q_D(const QPieSeries);
580 return d->m_slices.count();
582 return d->m_slices.count();
581 }
583 }
582
584
583 /*!
585 /*!
584 Returns true is the series is empty.
586 Returns true is the series is empty.
585 */
587 */
586 bool QPieSeries::isEmpty() const
588 bool QPieSeries::isEmpty() const
587 {
589 {
588 Q_D(const QPieSeries);
590 Q_D(const QPieSeries);
589 return d->m_slices.isEmpty();
591 return d->m_slices.isEmpty();
590 }
592 }
591
593
592 /*!
594 /*!
593 Returns the sum of all slice values in this series.
595 Returns the sum of all slice values in this series.
594
596
595 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
597 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
596 */
598 */
597 qreal QPieSeries::sum() const
599 qreal QPieSeries::sum() const
598 {
600 {
599 Q_D(const QPieSeries);
601 Q_D(const QPieSeries);
600 return d->m_sum;
602 return d->m_sum;
601 }
603 }
602
604
603 void QPieSeries::setHoleSize(qreal holeSize)
605 void QPieSeries::setHoleSize(qreal holeSize)
604 {
606 {
605 Q_D(QPieSeries);
607 Q_D(QPieSeries);
606 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
608 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
607 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
609 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
608 }
610 }
609
611
610 qreal QPieSeries::holeSize() const
612 qreal QPieSeries::holeSize() const
611 {
613 {
612 Q_D(const QPieSeries);
614 Q_D(const QPieSeries);
613 return d->m_holeRelativeSize;
615 return d->m_holeRelativeSize;
614 }
616 }
615
617
616 void QPieSeries::setHorizontalPosition(qreal relativePosition)
618 void QPieSeries::setHorizontalPosition(qreal relativePosition)
617 {
619 {
618 Q_D(QPieSeries);
620 Q_D(QPieSeries);
619
621
620 if (relativePosition < 0.0)
622 if (relativePosition < 0.0)
621 relativePosition = 0.0;
623 relativePosition = 0.0;
622 if (relativePosition > 1.0)
624 if (relativePosition > 1.0)
623 relativePosition = 1.0;
625 relativePosition = 1.0;
624
626
625 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
627 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
626 d->m_pieRelativeHorPos = relativePosition;
628 d->m_pieRelativeHorPos = relativePosition;
627 emit d->horizontalPositionChanged();
629 emit d->horizontalPositionChanged();
628 }
630 }
629 }
631 }
630
632
631 qreal QPieSeries::horizontalPosition() const
633 qreal QPieSeries::horizontalPosition() const
632 {
634 {
633 Q_D(const QPieSeries);
635 Q_D(const QPieSeries);
634 return d->m_pieRelativeHorPos;
636 return d->m_pieRelativeHorPos;
635 }
637 }
636
638
637 void QPieSeries::setVerticalPosition(qreal relativePosition)
639 void QPieSeries::setVerticalPosition(qreal relativePosition)
638 {
640 {
639 Q_D(QPieSeries);
641 Q_D(QPieSeries);
640
642
641 if (relativePosition < 0.0)
643 if (relativePosition < 0.0)
642 relativePosition = 0.0;
644 relativePosition = 0.0;
643 if (relativePosition > 1.0)
645 if (relativePosition > 1.0)
644 relativePosition = 1.0;
646 relativePosition = 1.0;
645
647
646 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
648 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
647 d->m_pieRelativeVerPos = relativePosition;
649 d->m_pieRelativeVerPos = relativePosition;
648 emit d->verticalPositionChanged();
650 emit d->verticalPositionChanged();
649 }
651 }
650 }
652 }
651
653
652 qreal QPieSeries::verticalPosition() const
654 qreal QPieSeries::verticalPosition() const
653 {
655 {
654 Q_D(const QPieSeries);
656 Q_D(const QPieSeries);
655 return d->m_pieRelativeVerPos;
657 return d->m_pieRelativeVerPos;
656 }
658 }
657
659
658 void QPieSeries::setPieSize(qreal relativeSize)
660 void QPieSeries::setPieSize(qreal relativeSize)
659 {
661 {
660 Q_D(QPieSeries);
662 Q_D(QPieSeries);
661 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
663 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
662 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
664 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
663
665
664 }
666 }
665
667
666 qreal QPieSeries::pieSize() const
668 qreal QPieSeries::pieSize() const
667 {
669 {
668 Q_D(const QPieSeries);
670 Q_D(const QPieSeries);
669 return d->m_pieRelativeSize;
671 return d->m_pieRelativeSize;
670 }
672 }
671
673
672
674
673 void QPieSeries::setPieStartAngle(qreal angle)
675 void QPieSeries::setPieStartAngle(qreal angle)
674 {
676 {
675 Q_D(QPieSeries);
677 Q_D(QPieSeries);
676 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
678 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
677 return;
679 return;
678 d->m_pieStartAngle = angle;
680 d->m_pieStartAngle = angle;
679 d->updateDerivativeData();
681 d->updateDerivativeData();
680 emit d->pieStartAngleChanged();
682 emit d->pieStartAngleChanged();
681 }
683 }
682
684
683 qreal QPieSeries::pieStartAngle() const
685 qreal QPieSeries::pieStartAngle() const
684 {
686 {
685 Q_D(const QPieSeries);
687 Q_D(const QPieSeries);
686 return d->m_pieStartAngle;
688 return d->m_pieStartAngle;
687 }
689 }
688
690
689 /*!
691 /*!
690 Sets the end angle of the pie.
692 Sets the end angle of the pie.
691
693
692 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
694 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
693
695
694 \a angle must be greater than start angle.
696 \a angle must be greater than start angle.
695
697
696 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
698 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
697 */
699 */
698 void QPieSeries::setPieEndAngle(qreal angle)
700 void QPieSeries::setPieEndAngle(qreal angle)
699 {
701 {
700 Q_D(QPieSeries);
702 Q_D(QPieSeries);
701 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
703 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
702 return;
704 return;
703 d->m_pieEndAngle = angle;
705 d->m_pieEndAngle = angle;
704 d->updateDerivativeData();
706 d->updateDerivativeData();
705 emit d->pieEndAngleChanged();
707 emit d->pieEndAngleChanged();
706 }
708 }
707
709
708 /*!
710 /*!
709 Returns the end angle of the pie.
711 Returns the end angle of the pie.
710
712
711 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
713 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
712
714
713 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
715 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
714 */
716 */
715 qreal QPieSeries::pieEndAngle() const
717 qreal QPieSeries::pieEndAngle() const
716 {
718 {
717 Q_D(const QPieSeries);
719 Q_D(const QPieSeries);
718 return d->m_pieEndAngle;
720 return d->m_pieEndAngle;
719 }
721 }
720
722
721 /*!
723 /*!
722 Sets the all the slice labels \a visible or invisible.
724 Sets the all the slice labels \a visible or invisible.
723
725
724 Note that this affects only the current slices in the series.
726 Note that this affects only the current slices in the series.
725 If user adds a new slice the default label visibility is false.
727 If user adds a new slice the default label visibility is false.
726
728
727 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
729 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
728 */
730 */
729 void QPieSeries::setLabelsVisible(bool visible)
731 void QPieSeries::setLabelsVisible(bool visible)
730 {
732 {
731 Q_D(QPieSeries);
733 Q_D(QPieSeries);
732 foreach (QPieSlice* s, d->m_slices)
734 foreach (QPieSlice* s, d->m_slices)
733 s->setLabelVisible(visible);
735 s->setLabelVisible(visible);
734 }
736 }
735
737
736 /*!
738 /*!
737 Sets the all the slice labels \a position
739 Sets the all the slice labels \a position
738
740
739 Note that this affects only the current slices in the series.
741 Note that this affects only the current slices in the series.
740 If user adds a new slice the default label position is LabelOutside
742 If user adds a new slice the default label position is LabelOutside
741
743
742 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
744 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
743 */
745 */
744 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
746 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
745 {
747 {
746 Q_D(QPieSeries);
748 Q_D(QPieSeries);
747 foreach (QPieSlice* s, d->m_slices)
749 foreach (QPieSlice* s, d->m_slices)
748 s->setLabelPosition(position);
750 s->setLabelPosition(position);
749 }
751 }
750
752
751 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
753 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
752
754
753
755
754 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
756 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
755 QAbstractSeriesPrivate(parent),
757 QAbstractSeriesPrivate(parent),
756 m_pieRelativeHorPos(0.5),
758 m_pieRelativeHorPos(0.5),
757 m_pieRelativeVerPos(0.5),
759 m_pieRelativeVerPos(0.5),
758 m_pieRelativeSize(0.7),
760 m_pieRelativeSize(0.7),
759 m_pieStartAngle(0),
761 m_pieStartAngle(0),
760 m_pieEndAngle(360),
762 m_pieEndAngle(360),
761 m_sum(0),
763 m_sum(0),
762 m_holeRelativeSize(0.0)
764 m_holeRelativeSize(0.0)
763 {
765 {
764 }
766 }
765
767
766 QPieSeriesPrivate::~QPieSeriesPrivate()
768 QPieSeriesPrivate::~QPieSeriesPrivate()
767 {
769 {
768 }
770 }
769
771
770 void QPieSeriesPrivate::updateDerivativeData()
772 void QPieSeriesPrivate::updateDerivativeData()
771 {
773 {
772 // calculate sum of all slices
774 // calculate sum of all slices
773 qreal sum = 0;
775 qreal sum = 0;
774 foreach (QPieSlice* s, m_slices)
776 foreach (QPieSlice* s, m_slices)
775 sum += s->value();
777 sum += s->value();
776
778
777 if (!qFuzzyIsNull(m_sum - sum)) {
779 if (!qFuzzyIsNull(m_sum - sum)) {
778 m_sum = sum;
780 m_sum = sum;
779 emit q_func()->sumChanged();
781 emit q_func()->sumChanged();
780 }
782 }
781
783
782 // nothing to show..
784 // nothing to show..
783 if (qFuzzyIsNull(m_sum))
785 if (qFuzzyIsNull(m_sum))
784 return;
786 return;
785
787
786 // update slice attributes
788 // update slice attributes
787 qreal sliceAngle = m_pieStartAngle;
789 qreal sliceAngle = m_pieStartAngle;
788 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
790 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
789 QVector<QPieSlice*> changed;
791 QVector<QPieSlice*> changed;
790 foreach (QPieSlice* s, m_slices) {
792 foreach (QPieSlice* s, m_slices) {
791 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
793 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
792 d->setPercentage(s->value() / m_sum);
794 d->setPercentage(s->value() / m_sum);
793 d->setStartAngle(sliceAngle);
795 d->setStartAngle(sliceAngle);
794 d->setAngleSpan(pieSpan * s->percentage());
796 d->setAngleSpan(pieSpan * s->percentage());
795 sliceAngle += s->angleSpan();
797 sliceAngle += s->angleSpan();
796 }
798 }
797
799
798
800
799 emit calculatedDataChanged();
801 emit calculatedDataChanged();
800 }
802 }
801
803
802 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
804 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
803 {
805 {
804 bool changed = false;
806 bool changed = false;
805
807
806 if (!qFuzzyIsNull(m_holeRelativeSize - innerSize)) {
808 if (!qFuzzyIsNull(m_holeRelativeSize - innerSize)) {
807 m_holeRelativeSize = innerSize;
809 m_holeRelativeSize = innerSize;
808 changed = true;
810 changed = true;
809 }
811 }
810
812
811 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
813 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
812 m_pieRelativeSize = outerSize;
814 m_pieRelativeSize = outerSize;
813 changed = true;
815 changed = true;
814 }
816 }
815
817
816 if (changed)
818 if (changed)
817 emit pieSizeChanged();
819 emit pieSizeChanged();
818 }
820 }
819
821
820 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
822 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
821 {
823 {
822 return series->d_func();
824 return series->d_func();
823 }
825 }
824
826
825 void QPieSeriesPrivate::sliceValueChanged()
827 void QPieSeriesPrivate::sliceValueChanged()
826 {
828 {
827 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
829 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
828 updateDerivativeData();
830 updateDerivativeData();
829 }
831 }
830
832
831 void QPieSeriesPrivate::sliceClicked()
833 void QPieSeriesPrivate::sliceClicked()
832 {
834 {
833 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
835 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
834 Q_ASSERT(m_slices.contains(slice));
836 Q_ASSERT(m_slices.contains(slice));
835 Q_Q(QPieSeries);
837 Q_Q(QPieSeries);
836 emit q->clicked(slice);
838 emit q->clicked(slice);
837 }
839 }
838
840
839 void QPieSeriesPrivate::sliceHovered(bool state)
841 void QPieSeriesPrivate::sliceHovered(bool state)
840 {
842 {
841 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
843 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
842 Q_ASSERT(m_slices.contains(slice));
844 Q_ASSERT(m_slices.contains(slice));
843 Q_Q(QPieSeries);
845 Q_Q(QPieSeries);
844 emit q->hovered(slice, state);
846 emit q->hovered(slice, state);
845 }
847 }
846
848
847 void QPieSeriesPrivate::updateLegendProperties()
849 void QPieSeriesPrivate::updateLegendProperties()
848 {
850 {
849 // This slot listens to all properties of slices, which may interest legend and signals it.
851 // This slot listens to all properties of slices, which may interest legend and signals it.
850 Q_Q(QPieSeries);
852 Q_Q(QPieSeries);
851 emit legendPropertiesUpdated(q);
853 emit legendPropertiesUpdated(q);
852 }
854 }
853
855
854 void QPieSeriesPrivate::scaleDomain(Domain& domain)
856 void QPieSeriesPrivate::scaleDomain(Domain& domain)
855 {
857 {
856 Q_UNUSED(domain);
858 Q_UNUSED(domain);
857 // does not apply to pie
859 // does not apply to pie
858 }
860 }
859
861
860 ChartElement* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
862 ChartElement* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
861 {
863 {
862 Q_Q(QPieSeries);
864 Q_Q(QPieSeries);
863 PieChartItem* pie = new PieChartItem(q,presenter);
865 PieChartItem* pie = new PieChartItem(q,presenter);
864 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
866 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
865 pie->setAnimation(new PieAnimation(pie));
867 pie->setAnimation(new PieAnimation(pie));
866 }
868 }
867 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
869 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
868 return pie;
870 return pie;
869 }
871 }
870
872
871 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
873 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
872 {
874 {
873 Q_Q(QPieSeries);
875 Q_Q(QPieSeries);
874 QList<LegendMarker*> markers;
876 QList<LegendMarker*> markers;
875 foreach(QPieSlice* slice, q->slices()) {
877 foreach(QPieSlice* slice, q->slices()) {
876 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
878 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
877 markers << marker;
879 markers << marker;
878 }
880 }
879 return markers;
881 return markers;
880 }
882 }
881
883
882 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
884 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
883 {
885 {
884 Q_UNUSED(axis);
886 Q_UNUSED(axis);
885 }
887 }
886
888
887 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
889 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
888 {
890 {
889 Q_UNUSED(orientation);
891 Q_UNUSED(orientation);
890 return QAbstractAxis::AxisTypeNoAxis;
892 return QAbstractAxis::AxisTypeNoAxis;
891 }
893 }
892
894
893 #include "moc_qpieseries.cpp"
895 #include "moc_qpieseries.cpp"
894 #include "moc_qpieseries_p.cpp"
896 #include "moc_qpieseries_p.cpp"
895
897
896 QTCOMMERCIALCHART_END_NAMESPACE
898 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now