##// END OF EJS Templates
Refactoring QPieSlice private implementation. Removes the useless QPieSlicePrivate layer and uses PieSliceData directly.
Jani Honkonen -
r818:5bf1dbd3a89a
parent child
Show More
@@ -1,392 +1,393
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 "charttheme_p.h"
21 #include "charttheme_p.h"
22 #include "qchart.h"
22 #include "qchart.h"
23 #include "qchartview.h"
23 #include "qchartview.h"
24 #include "qlegend.h"
24 #include "qlegend.h"
25 #include "qchartaxis.h"
25 #include "qchartaxis.h"
26 #include <QTime>
26 #include <QTime>
27
27
28 //series
28 //series
29 #include "qbarset.h"
29 #include "qbarset.h"
30 #include "qbarseries.h"
30 #include "qbarseries.h"
31 #include "qstackedbarseries.h"
31 #include "qstackedbarseries.h"
32 #include "qpercentbarseries.h"
32 #include "qpercentbarseries.h"
33 #include "qlineseries.h"
33 #include "qlineseries.h"
34 #include "qareaseries.h"
34 #include "qareaseries.h"
35 #include "qscatterseries.h"
35 #include "qscatterseries.h"
36 #include "qpieseries.h"
36 #include "qpieseries.h"
37 #include "qpieslice.h"
37 #include "qpieslice.h"
38 #include "qsplineseries.h"
38 #include "qsplineseries.h"
39
39
40 //items
40 //items
41 #include "axisitem_p.h"
41 #include "axisitem_p.h"
42 #include "barchartitem_p.h"
42 #include "barchartitem_p.h"
43 #include "stackedbarchartitem_p.h"
43 #include "stackedbarchartitem_p.h"
44 #include "percentbarchartitem_p.h"
44 #include "percentbarchartitem_p.h"
45 #include "linechartitem_p.h"
45 #include "linechartitem_p.h"
46 #include "areachartitem_p.h"
46 #include "areachartitem_p.h"
47 #include "scatterchartitem_p.h"
47 #include "scatterchartitem_p.h"
48 #include "piechartitem_p.h"
48 #include "piechartitem_p.h"
49 #include "splinechartitem_p.h"
49 #include "splinechartitem_p.h"
50
50
51 //themes
51 //themes
52 #include "chartthemedefault_p.h"
52 #include "chartthemedefault_p.h"
53 #include "chartthemelight_p.h"
53 #include "chartthemelight_p.h"
54 #include "chartthemebluecerulean_p.h"
54 #include "chartthemebluecerulean_p.h"
55 #include "chartthemedark_p.h"
55 #include "chartthemedark_p.h"
56 #include "chartthemebrownsand_p.h"
56 #include "chartthemebrownsand_p.h"
57 #include "chartthemebluencs_p.h"
57 #include "chartthemebluencs_p.h"
58 #include "chartthemehighcontrast_p.h"
58 #include "chartthemehighcontrast_p.h"
59 #include "chartthemeblueicy_p.h"
59 #include "chartthemeblueicy_p.h"
60
60
61 QTCOMMERCIALCHART_BEGIN_NAMESPACE
61 QTCOMMERCIALCHART_BEGIN_NAMESPACE
62
62
63 ChartTheme::ChartTheme(QChart::ChartTheme id) :
63 ChartTheme::ChartTheme(QChart::ChartTheme id) :
64 m_masterFont(QFont("arial", 12)),
64 m_masterFont(QFont("arial", 12)),
65 m_labelFont(QFont("arial", 10)),
65 m_labelFont(QFont("arial", 10)),
66 m_titleBrush(QColor(QRgb(0x000000))),
66 m_titleBrush(QColor(QRgb(0x000000))),
67 m_axisLinePen(QPen(QRgb(0x000000))),
67 m_axisLinePen(QPen(QRgb(0x000000))),
68 m_axisLabelBrush(QColor(QRgb(0x000000))),
68 m_axisLabelBrush(QColor(QRgb(0x000000))),
69 m_backgroundShadesPen(Qt::NoPen),
69 m_backgroundShadesPen(Qt::NoPen),
70 m_backgroundShadesBrush(Qt::NoBrush),
70 m_backgroundShadesBrush(Qt::NoBrush),
71 m_backgroundShades(BackgroundShadesNone),
71 m_backgroundShades(BackgroundShadesNone),
72 m_gridLinePen(QPen(QRgb(0x000000)))
72 m_gridLinePen(QPen(QRgb(0x000000)))
73 {
73 {
74 m_id = id;
74 m_id = id;
75 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
75 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
76 }
76 }
77
77
78
78
79 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
79 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
80 {
80 {
81 switch(theme) {
81 switch(theme) {
82 case QChart::ChartThemeLight:
82 case QChart::ChartThemeLight:
83 return new ChartThemeLight();
83 return new ChartThemeLight();
84 case QChart::ChartThemeBlueCerulean:
84 case QChart::ChartThemeBlueCerulean:
85 return new ChartThemeBlueCerulean();
85 return new ChartThemeBlueCerulean();
86 case QChart::ChartThemeDark:
86 case QChart::ChartThemeDark:
87 return new ChartThemeDark();
87 return new ChartThemeDark();
88 case QChart::ChartThemeBrownSand:
88 case QChart::ChartThemeBrownSand:
89 return new ChartThemeBrownSand();
89 return new ChartThemeBrownSand();
90 case QChart::ChartThemeBlueNcs:
90 case QChart::ChartThemeBlueNcs:
91 return new ChartThemeBlueNcs();
91 return new ChartThemeBlueNcs();
92 case QChart::ChartThemeHighContrast:
92 case QChart::ChartThemeHighContrast:
93 return new ChartThemeHighContrast();
93 return new ChartThemeHighContrast();
94 case QChart::ChartThemeBlueIcy:
94 case QChart::ChartThemeBlueIcy:
95 return new ChartThemeBlueIcy();
95 return new ChartThemeBlueIcy();
96 default:
96 default:
97 return new ChartThemeDefault();
97 return new ChartThemeDefault();
98 }
98 }
99 }
99 }
100
100
101 void ChartTheme::decorate(QChart* chart,bool force)
101 void ChartTheme::decorate(QChart* chart,bool force)
102 {
102 {
103 QBrush brush;
103 QBrush brush;
104
104
105 if(brush == chart->backgroundBrush() || force)
105 if(brush == chart->backgroundBrush() || force)
106 chart->setBackgroundBrush(m_chartBackgroundGradient);
106 chart->setBackgroundBrush(m_chartBackgroundGradient);
107 chart->setTitleFont(m_masterFont);
107 chart->setTitleFont(m_masterFont);
108 chart->setTitleBrush(m_titleBrush);
108 chart->setTitleBrush(m_titleBrush);
109 }
109 }
110
110
111 void ChartTheme::decorate(QLegend* legend,bool force)
111 void ChartTheme::decorate(QLegend* legend,bool force)
112 {
112 {
113 QPen pen;
113 QPen pen;
114 QBrush brush;
114 QBrush brush;
115
115
116 if (pen == legend->pen() || force){
116 if (pen == legend->pen() || force){
117 legend->setPen(Qt::NoPen);
117 legend->setPen(Qt::NoPen);
118 }
118 }
119
119
120
120
121 if (brush == legend->brush() || force) {
121 if (brush == legend->brush() || force) {
122 legend->setBrush(m_chartBackgroundGradient);
122 legend->setBrush(m_chartBackgroundGradient);
123 }
123 }
124 }
124 }
125
125
126 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
126 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
127 {
127 {
128 QPen pen;
128 QPen pen;
129 QBrush brush;
129 QBrush brush;
130
130
131 if (pen == series->pen() || force){
131 if (pen == series->pen() || force){
132 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
132 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
133 pen.setWidthF(2);
133 pen.setWidthF(2);
134 series->setPen(pen);
134 series->setPen(pen);
135 }
135 }
136
136
137 if (brush == series->brush() || force) {
137 if (brush == series->brush() || force) {
138 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
138 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
139 series->setBrush(brush);
139 series->setBrush(brush);
140 }
140 }
141 }
141 }
142
142
143
143
144 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
144 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
145 {
145 {
146 QPen pen;
146 QPen pen;
147 if(pen == series->pen() || force ){
147 if(pen == series->pen() || force ){
148 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
148 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
149 pen.setWidthF(2);
149 pen.setWidthF(2);
150 series->setPen(pen);
150 series->setPen(pen);
151 }
151 }
152 }
152 }
153
153
154 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
154 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
155 {
155 {
156 QBrush brush;
156 QBrush brush;
157 QPen pen;
157 QPen pen;
158 QList<QBarSet*> sets = series->barSets();
158 QList<QBarSet*> sets = series->barSets();
159
159
160 qreal takeAtPos = 0.5;
160 qreal takeAtPos = 0.5;
161 qreal step = 0.2;
161 qreal step = 0.2;
162 if (sets.count() > 1 ) {
162 if (sets.count() > 1 ) {
163 step = 1.0 / (qreal) sets.count();
163 step = 1.0 / (qreal) sets.count();
164 if (sets.count() % m_seriesGradients.count())
164 if (sets.count() % m_seriesGradients.count())
165 step *= m_seriesGradients.count();
165 step *= m_seriesGradients.count();
166 else
166 else
167 step *= (m_seriesGradients.count() - 1);
167 step *= (m_seriesGradients.count() - 1);
168 }
168 }
169
169
170 for (int i(0); i < sets.count(); i++) {
170 for (int i(0); i < sets.count(); i++) {
171 int colorIndex = (index + i) % m_seriesGradients.count();
171 int colorIndex = (index + i) % m_seriesGradients.count();
172 if (i > 0 && i % m_seriesGradients.count() == 0) {
172 if (i > 0 && i % m_seriesGradients.count() == 0) {
173 // There is no dedicated base color for each sets, generate more colors
173 // There is no dedicated base color for each sets, generate more colors
174 takeAtPos += step;
174 takeAtPos += step;
175 if (takeAtPos == 1.0)
175 if (takeAtPos == 1.0)
176 takeAtPos += step;
176 takeAtPos += step;
177 takeAtPos -= (int) takeAtPos;
177 takeAtPos -= (int) takeAtPos;
178 }
178 }
179 qDebug() << "pos:" << takeAtPos;
179 qDebug() << "pos:" << takeAtPos;
180 if (brush == sets.at(i)->brush() || force )
180 if (brush == sets.at(i)->brush() || force )
181 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
181 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
182
182
183 // Pick label color from the opposite end of the gradient.
183 // Pick label color from the opposite end of the gradient.
184 // 0.3 as a boundary seems to work well.
184 // 0.3 as a boundary seems to work well.
185 if (takeAtPos < 0.3)
185 if (takeAtPos < 0.3)
186 sets.at(i)->setValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
186 sets.at(i)->setValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
187 else
187 else
188 sets.at(i)->setValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
188 sets.at(i)->setValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
189
189
190 if (pen == sets.at(i)->pen() || force) {
190 if (pen == sets.at(i)->pen() || force) {
191 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
191 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
192 sets.at(i)->setPen(c);
192 sets.at(i)->setPen(c);
193 }
193 }
194 }
194 }
195 }
195 }
196
196
197 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
197 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
198 {
198 {
199 QPen pen;
199 QPen pen;
200 QBrush brush;
200 QBrush brush;
201
201
202 if (pen == series->pen() || force) {
202 if (pen == series->pen() || force) {
203 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
203 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
204 pen.setWidthF(2);
204 pen.setWidthF(2);
205 series->setPen(pen);
205 series->setPen(pen);
206 }
206 }
207
207
208 if (brush == series->brush() || force) {
208 if (brush == series->brush() || force) {
209 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
209 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
210 series->setBrush(brush);
210 series->setBrush(brush);
211 }
211 }
212 }
212 }
213
213
214 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
214 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
215 {
215 {
216
216 for (int i(0); i < series->slices().count(); i++) {
217 for (int i(0); i < series->slices().count(); i++) {
217
218
218 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
219 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
219
220
220 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
221 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
221 qreal pos = (qreal) (i + 1) / (qreal) series->count();
222 qreal pos = (qreal) (i + 1) / (qreal) series->count();
222 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
223 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
223
224
224 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
225 QPieSlice *s = series->slices().at(i);
225 PieSliceData data = s->m_data;
226 PieSliceData data = *s->data_ptr();
226
227
227 if (data.m_slicePen.isThemed() || force) {
228 if (data.m_slicePen.isThemed() || force) {
228 data.m_slicePen = penColor;
229 data.m_slicePen = penColor;
229 data.m_slicePen.setThemed(true);
230 data.m_slicePen.setThemed(true);
230 }
231 }
231
232
232 if (data.m_sliceBrush.isThemed() || force) {
233 if (data.m_sliceBrush.isThemed() || force) {
233 data.m_sliceBrush = brushColor;
234 data.m_sliceBrush = brushColor;
234 data.m_sliceBrush.setThemed(true);
235 data.m_sliceBrush.setThemed(true);
235 }
236 }
236
237
237 if (data.m_labelPen.isThemed() || force) {
238 if (data.m_labelPen.isThemed() || force) {
238 data.m_labelPen = QPen(m_titleBrush.color());
239 data.m_labelPen = QPen(m_titleBrush.color());
239 data.m_labelPen.setThemed(true);
240 data.m_labelPen.setThemed(true);
240 }
241 }
241
242
242 if (data.m_labelFont.isThemed() || force) {
243 if (data.m_labelFont.isThemed() || force) {
243 data.m_labelFont = m_labelFont;
244 data.m_labelFont = m_labelFont;
244 data.m_labelFont.setThemed(true);
245 data.m_labelFont.setThemed(true);
245 }
246 }
246
247
247 if (s->m_data != data) {
248 if (*s->data_ptr() != data) {
248 s->m_data = data;
249 *s->data_ptr() = data;
249 emit s->changed();
250 emit s->data_ptr()->emitChangedSignal(s);
250 }
251 }
251 }
252 }
252 }
253 }
253
254
254 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
255 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
255 {
256 {
256 QPen pen;
257 QPen pen;
257 if(pen == series->pen() || force){
258 if(pen == series->pen() || force){
258 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
259 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
259 pen.setWidthF(2);
260 pen.setWidthF(2);
260 series->setPen(pen);
261 series->setPen(pen);
261 }
262 }
262 }
263 }
263
264
264 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
265 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
265 {
266 {
266 QPen pen;
267 QPen pen;
267 QBrush brush;
268 QBrush brush;
268 QFont font;
269 QFont font;
269
270
270 if (axis->isAxisVisible()) {
271 if (axis->isAxisVisible()) {
271
272
272 if(brush == axis->labelsBrush() || force){
273 if(brush == axis->labelsBrush() || force){
273 axis->setLabelsBrush(m_axisLabelBrush);
274 axis->setLabelsBrush(m_axisLabelBrush);
274 }
275 }
275 if(pen == axis->labelsPen() || force){
276 if(pen == axis->labelsPen() || force){
276 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
277 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
277 }
278 }
278
279
279
280
280 if (axis->shadesVisible() || force) {
281 if (axis->shadesVisible() || force) {
281
282
282 if(brush == axis->shadesBrush() || force){
283 if(brush == axis->shadesBrush() || force){
283 axis->setShadesBrush(m_backgroundShadesBrush);
284 axis->setShadesBrush(m_backgroundShadesBrush);
284 }
285 }
285
286
286 if(pen == axis->shadesPen() || force){
287 if(pen == axis->shadesPen() || force){
287 axis->setShadesPen(m_backgroundShadesPen);
288 axis->setShadesPen(m_backgroundShadesPen);
288 }
289 }
289
290
290 if(force && (m_backgroundShades == BackgroundShadesBoth
291 if(force && (m_backgroundShades == BackgroundShadesBoth
291 || (m_backgroundShades == BackgroundShadesVertical && axisX)
292 || (m_backgroundShades == BackgroundShadesVertical && axisX)
292 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
293 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
293 axis->setShadesVisible(true);
294 axis->setShadesVisible(true);
294
295
295 }
296 }
296 }
297 }
297
298
298 if(pen == axis->axisPen() || force){
299 if(pen == axis->axisPen() || force){
299 axis->setAxisPen(m_axisLinePen);
300 axis->setAxisPen(m_axisLinePen);
300 }
301 }
301
302
302 if(pen == axis->gridLinePen() || force){
303 if(pen == axis->gridLinePen() || force){
303 axis->setGridLinePen(m_gridLinePen);
304 axis->setGridLinePen(m_gridLinePen);
304 }
305 }
305
306
306 if(font == axis->labelsFont() || force){
307 if(font == axis->labelsFont() || force){
307 axis->setLabelsFont(m_labelFont);
308 axis->setLabelsFont(m_labelFont);
308 }
309 }
309 }
310 }
310 }
311 }
311
312
312 void ChartTheme::generateSeriesGradients()
313 void ChartTheme::generateSeriesGradients()
313 {
314 {
314 // Generate gradients in HSV color space
315 // Generate gradients in HSV color space
315 foreach (QColor color, m_seriesColors) {
316 foreach (QColor color, m_seriesColors) {
316 QLinearGradient g;
317 QLinearGradient g;
317 qreal h = color.hsvHueF();
318 qreal h = color.hsvHueF();
318 qreal s = color.hsvSaturationF();
319 qreal s = color.hsvSaturationF();
319
320
320 // TODO: tune the algorithm to give nice results with most base colors defined in
321 // TODO: tune the algorithm to give nice results with most base colors defined in
321 // most themes. The rest of the gradients we can define manually in theme specific
322 // most themes. The rest of the gradients we can define manually in theme specific
322 // implementation.
323 // implementation.
323 QColor start = color;
324 QColor start = color;
324 start.setHsvF(h, 0.0, 1.0);
325 start.setHsvF(h, 0.0, 1.0);
325 g.setColorAt(0.0, start);
326 g.setColorAt(0.0, start);
326
327
327 g.setColorAt(0.5, color);
328 g.setColorAt(0.5, color);
328
329
329 QColor end = color;
330 QColor end = color;
330 end.setHsvF(h, s, 0.25);
331 end.setHsvF(h, s, 0.25);
331 g.setColorAt(1.0, end);
332 g.setColorAt(1.0, end);
332
333
333 m_seriesGradients << g;
334 m_seriesGradients << g;
334 }
335 }
335 }
336 }
336
337
337
338
338 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
339 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
339 {
340 {
340 Q_ASSERT(pos >=0.0 && pos <= 1.0);
341 Q_ASSERT(pos >=0.0 && pos <= 1.0);
341 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
342 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
342 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
343 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
343 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
344 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
344 QColor c;
345 QColor c;
345 c.setRgbF(r, g, b);
346 c.setRgbF(r, g, b);
346 return c;
347 return c;
347 }
348 }
348
349
349 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
350 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
350 {
351 {
351 Q_ASSERT(pos >=0 && pos <= 1.0);
352 Q_ASSERT(pos >=0 && pos <= 1.0);
352
353
353 // another possibility:
354 // another possibility:
354 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
355 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
355
356
356 QGradientStops stops = gradient.stops();
357 QGradientStops stops = gradient.stops();
357 int count = stops.count();
358 int count = stops.count();
358
359
359 // find previous stop relative to position
360 // find previous stop relative to position
360 QGradientStop prev = stops.first();
361 QGradientStop prev = stops.first();
361 for (int i=0; i<count; i++) {
362 for (int i=0; i<count; i++) {
362 QGradientStop stop = stops.at(i);
363 QGradientStop stop = stops.at(i);
363 if (pos > stop.first)
364 if (pos > stop.first)
364 prev = stop;
365 prev = stop;
365
366
366 // given position is actually a stop position?
367 // given position is actually a stop position?
367 if (pos == stop.first) {
368 if (pos == stop.first) {
368 //qDebug() << "stop color" << pos;
369 //qDebug() << "stop color" << pos;
369 return stop.second;
370 return stop.second;
370 }
371 }
371 }
372 }
372
373
373 // find next stop relative to position
374 // find next stop relative to position
374 QGradientStop next = stops.last();
375 QGradientStop next = stops.last();
375 for (int i=count-1; i>=0; i--) {
376 for (int i=count-1; i>=0; i--) {
376 QGradientStop stop = stops.at(i);
377 QGradientStop stop = stops.at(i);
377 if (pos < stop.first)
378 if (pos < stop.first)
378 next = stop;
379 next = stop;
379 }
380 }
380
381
381 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
382 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
382
383
383 qreal range = next.first - prev.first;
384 qreal range = next.first - prev.first;
384 qreal posDelta = pos - prev.first;
385 qreal posDelta = pos - prev.first;
385 qreal relativePos = posDelta / range;
386 qreal relativePos = posDelta / range;
386
387
387 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
388 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
388
389
389 return colorAt(prev.second, next.second, relativePos);
390 return colorAt(prev.second, next.second, relativePos);
390 }
391 }
391
392
392 QTCOMMERCIALCHART_END_NAMESPACE
393 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,19 +1,18
1 INCLUDEPATH += $$PWD
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
2 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/qpieseries.cpp \
5 $$PWD/qpieseries.cpp \
6 $$PWD/piesliceitem.cpp \
6 $$PWD/piesliceitem.cpp \
7 $$PWD/piechartitem.cpp \
7 $$PWD/piechartitem.cpp \
8 $$PWD/qpieslice.cpp
8 $$PWD/qpieslice.cpp
9
9
10 PRIVATE_HEADERS += \
10 PRIVATE_HEADERS += \
11 $$PWD/pieslicedata_p.h \
11 $$PWD/pieslicedata_p.h \
12 $$PWD/piechartitem_p.h \
12 $$PWD/piechartitem_p.h \
13 $$PWD/piesliceitem_p.h \
13 $$PWD/piesliceitem_p.h \
14 $$PWD/qpiesliceprivate_p.h \
15 $$PWD/qpieseriesprivate_p.h
14 $$PWD/qpieseriesprivate_p.h
16
15
17 PUBLIC_HEADERS += \
16 PUBLIC_HEADERS += \
18 $$PWD/qpieseries.h \
17 $$PWD/qpieseries.h \
19 $$PWD/qpieslice.h
18 $$PWD/qpieslice.h
@@ -1,211 +1,211
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 "qpiesliceprivate_p.h"
25 #include "qpieseries.h"
24 #include "qpieseries.h"
26 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
27 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
28 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
29 #include <QDebug>
28 #include <QDebug>
30 #include <QPainter>
29 #include <QPainter>
31 #include <QTimer>
30 #include <QTimer>
32
31
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
33
35 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
34 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
36 :ChartItem(presenter),
35 :ChartItem(presenter),
37 m_series(series)
36 m_series(series)
38 {
37 {
39 Q_ASSERT(series);
38 Q_ASSERT(series);
40 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
39 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
41 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
40 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
42 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
41 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
43 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
42 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
44
43
45 QTimer::singleShot(0, this, SLOT(initialize()));
44 QTimer::singleShot(0, this, SLOT(initialize()));
46
45
47 // Note: the following does not affect as long as the item does not have anything to paint
46 // Note: the following does not affect as long as the item does not have anything to paint
48 setZValue(ChartPresenter::PieSeriesZValue);
47 setZValue(ChartPresenter::PieSeriesZValue);
49 }
48 }
50
49
51 PieChartItem::~PieChartItem()
50 PieChartItem::~PieChartItem()
52 {
51 {
53 // slices deleted automatically through QGraphicsItem
52 // slices deleted automatically through QGraphicsItem
54 }
53 }
55
54
56 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
55 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
57 {
56 {
58 Q_UNUSED(painter)
57 Q_UNUSED(painter)
59 // TODO: paint shadows for all components
58 // TODO: paint shadows for all components
60 // - get paths from items & merge & offset and draw with shadow color?
59 // - get paths from items & merge & offset and draw with shadow color?
61 //painter->setBrush(QBrush(Qt::red));
60 //painter->setBrush(QBrush(Qt::red));
62 //painter->drawRect(m_debugRect);
61 //painter->drawRect(m_debugRect);
63 }
62 }
64
63
65 void PieChartItem::initialize()
64 void PieChartItem::initialize()
66 {
65 {
67 handleSlicesAdded(m_series->slices());
66 handleSlicesAdded(m_series->slices());
68 }
67 }
69
68
70 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
69 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
71 {
70 {
72 bool isEmpty = m_slices.isEmpty();
71 bool isEmpty = m_slices.isEmpty();
73
72
74 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
73 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
75
74
76 foreach (QPieSlice *s, slices) {
75 foreach (QPieSlice *s, slices) {
77 PieSliceItem* item = new PieSliceItem(this);
76 PieSliceItem* item = new PieSliceItem(this);
78 m_slices.insert(s, item);
77 m_slices.insert(s, item);
79 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
78 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
80 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons)));
79 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons)));
81 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
80 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
82 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
81 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
83
82
84 PieSliceData data = sliceData(s);
83 PieSliceData data = sliceData(s);
85
84
86 if (animator())
85 if (animator())
87 animator()->addAnimation(this, s, data, isEmpty);
86 animator()->addAnimation(this, s, data, isEmpty);
88 else
87 else
89 setLayout(s, data);
88 setLayout(s, data);
90 }
89 }
91 }
90 }
92
91
93 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
92 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
94 {
93 {
95 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
94 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
96
95
97 foreach (QPieSlice *s, slices) {
96 foreach (QPieSlice *s, slices) {
98 if (animator())
97 if (animator())
99 animator()->removeAnimation(this, s);
98 animator()->removeAnimation(this, s);
100 else
99 else
101 destroySlice(s);
100 destroySlice(s);
102 }
101 }
103 }
102 }
104
103
105 void PieChartItem::handlePieLayoutChanged()
104 void PieChartItem::handlePieLayoutChanged()
106 {
105 {
107 PieLayout layout = calculateLayout();
106 PieLayout layout = calculateLayout();
108 applyLayout(layout);
107 applyLayout(layout);
109 update();
108 update();
110 }
109 }
111
110
112 void PieChartItem::handleSliceChanged()
111 void PieChartItem::handleSliceChanged()
113 {
112 {
114 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
115 Q_ASSERT(m_slices.contains(slice));
114 Q_ASSERT(m_slices.contains(slice));
116 PieSliceData data = sliceData(slice);
115 PieSliceData data = sliceData(slice);
117 updateLayout(slice, data);
116 updateLayout(slice, data);
118 update();
117 update();
119 }
118 }
120
119
121 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
120 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
122 {
121 {
123 // TODO
122 // TODO
124 }
123 }
125
124
126 void PieChartItem::handleGeometryChanged(const QRectF& rect)
125 void PieChartItem::handleGeometryChanged(const QRectF& rect)
127 {
126 {
128 prepareGeometryChange();
127 prepareGeometryChange();
129 m_rect = rect;
128 m_rect = rect;
130 handlePieLayoutChanged();
129 handlePieLayoutChanged();
131 }
130 }
132
131
133 void PieChartItem::calculatePieLayout()
132 void PieChartItem::calculatePieLayout()
134 {
133 {
135 // find pie center coordinates
134 // find pie center coordinates
136 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
135 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
137 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
136 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
138
137
139 // find maximum radius for pie
138 // find maximum radius for pie
140 m_pieRadius = m_rect.height() / 2;
139 m_pieRadius = m_rect.height() / 2;
141 if (m_rect.width() < m_rect.height())
140 if (m_rect.width() < m_rect.height())
142 m_pieRadius = m_rect.width() / 2;
141 m_pieRadius = m_rect.width() / 2;
143
142
144 // apply size factor
143 // apply size factor
145 m_pieRadius *= m_series->pieSize();
144 m_pieRadius *= m_series->pieSize();
146 }
145 }
147
146
148 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
147 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
149 {
148 {
150 PieSliceData sliceData = slice->data_ptr()->m_data;
149 // TODO: This function is kid of useless now. Refactor.
150 PieSliceData sliceData = *slice->data_ptr();
151 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
151 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
152 sliceData.m_radius = m_pieRadius;
152 sliceData.m_radius = m_pieRadius;
153 return sliceData;
153 return sliceData;
154 }
154 }
155
155
156 PieLayout PieChartItem::calculateLayout()
156 PieLayout PieChartItem::calculateLayout()
157 {
157 {
158 calculatePieLayout();
158 calculatePieLayout();
159 PieLayout layout;
159 PieLayout layout;
160 foreach (QPieSlice* s, m_series->slices()) {
160 foreach (QPieSlice* s, m_series->slices()) {
161 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
161 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
162 layout.insert(s, sliceData(s));
162 layout.insert(s, sliceData(s));
163 }
163 }
164 return layout;
164 return layout;
165 }
165 }
166
166
167 void PieChartItem::applyLayout(const PieLayout &layout)
167 void PieChartItem::applyLayout(const PieLayout &layout)
168 {
168 {
169 if (animator())
169 if (animator())
170 animator()->updateLayout(this, layout);
170 animator()->updateLayout(this, layout);
171 else
171 else
172 setLayout(layout);
172 setLayout(layout);
173 }
173 }
174
174
175 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
175 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
176 {
176 {
177 if (animator())
177 if (animator())
178 animator()->updateLayout(this, slice, sliceData);
178 animator()->updateLayout(this, slice, sliceData);
179 else
179 else
180 setLayout(slice, sliceData);
180 setLayout(slice, sliceData);
181 }
181 }
182
182
183 void PieChartItem::setLayout(const PieLayout &layout)
183 void PieChartItem::setLayout(const PieLayout &layout)
184 {
184 {
185 foreach (QPieSlice *slice, layout.keys()) {
185 foreach (QPieSlice *slice, layout.keys()) {
186 PieSliceItem *item = m_slices.value(slice);
186 PieSliceItem *item = m_slices.value(slice);
187 Q_ASSERT(item);
187 Q_ASSERT(item);
188 item->setSliceData(layout.value(slice));
188 item->setSliceData(layout.value(slice));
189 item->updateGeometry();
189 item->updateGeometry();
190 item->update();
190 item->update();
191 }
191 }
192 }
192 }
193
193
194 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
194 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
195 {
195 {
196 // find slice
196 // find slice
197 PieSliceItem *item = m_slices.value(slice);
197 PieSliceItem *item = m_slices.value(slice);
198 Q_ASSERT(item);
198 Q_ASSERT(item);
199 item->setSliceData(sliceData);
199 item->setSliceData(sliceData);
200 item->updateGeometry();
200 item->updateGeometry();
201 item->update();
201 item->update();
202 }
202 }
203
203
204 void PieChartItem::destroySlice(QPieSlice *slice)
204 void PieChartItem::destroySlice(QPieSlice *slice)
205 {
205 {
206 delete m_slices.take(slice);
206 delete m_slices.take(slice);
207 }
207 }
208
208
209 #include "moc_piechartitem_p.cpp"
209 #include "moc_piechartitem_p.cpp"
210
210
211 QTCOMMERCIALCHART_END_NAMESPACE
211 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,130 +1,136
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 PIESLICEDATA_P_H
21 #ifndef PIESLICEDATA_P_H
22 #define PIESLICEDATA_P_H
22 #define PIESLICEDATA_P_H
23
23
24 #include <qchartglobal.h>
24 #include "qchartglobal.h"
25 #include "qpieslice.h"
25 #include <QPen>
26 #include <QPen>
26 #include <QBrush>
27 #include <QBrush>
27 #include <QDebug>
28 #include <QDebug>
28
29
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
31
31 template <class T>
32 template <class T>
32 class Themed : public T
33 class Themed : public T
33 {
34 {
34 public:
35 public:
35 Themed():m_isThemed(true) {}
36 Themed():m_isThemed(true) {}
36
37
37 inline T &operator=(const T &other) { return T::operator =(other); }
38 inline T &operator=(const T &other) { return T::operator =(other); }
38
39
39 inline bool operator!=(const T &other) const { return T::operator !=(other); }
40 inline bool operator!=(const T &other) const { return T::operator !=(other); }
40 inline bool operator!=(const Themed &other) const
41 inline bool operator!=(const Themed &other) const
41 {
42 {
42 if (T::operator !=(other))
43 if (T::operator !=(other))
43 return true;
44 return true;
44
45
45 if (m_isThemed != other.m_isThemed)
46 if (m_isThemed != other.m_isThemed)
46 return true;
47 return true;
47
48
48 return false;
49 return false;
49 }
50 }
50
51
51 inline void setThemed(bool state) { m_isThemed = state; }
52 inline void setThemed(bool state) { m_isThemed = state; }
52 inline bool isThemed() const { return m_isThemed; }
53 inline bool isThemed() const { return m_isThemed; }
53
54
54 private:
55 private:
55 bool m_isThemed;
56 bool m_isThemed;
56 };
57 };
57
58
58 class PieSliceData
59 class PieSliceData
59 {
60 {
60 public:
61 public:
61 PieSliceData()
62 PieSliceData()
62 {
63 {
63 m_value = 0;
64 m_value = 0;
64
65
65 m_isExploded = false;
66 m_isExploded = false;
66 m_explodeDistanceFactor = 0.15;
67 m_explodeDistanceFactor = 0.15;
67
68
68 m_isLabelVisible = false;
69 m_isLabelVisible = false;
69 m_labelArmLengthFactor = 0.15;
70 m_labelArmLengthFactor = 0.15;
70
71
71 m_percentage = 0;
72 m_percentage = 0;
72 m_radius = 0;
73 m_radius = 0;
73 m_startAngle = 0;
74 m_startAngle = 0;
74 m_angleSpan = 0;
75 m_angleSpan = 0;
75 }
76 }
76
77
77 bool operator!=(const PieSliceData &other) const
78 bool operator!=(const PieSliceData &other) const
78 {
79 {
79 if (!qFuzzyIsNull(m_value - other.m_value))
80 if (!qFuzzyIsNull(m_value - other.m_value))
80 return true;
81 return true;
81
82
82 if (m_slicePen != other.m_slicePen ||
83 if (m_slicePen != other.m_slicePen ||
83 m_sliceBrush != other.m_sliceBrush)
84 m_sliceBrush != other.m_sliceBrush)
84 return true;
85 return true;
85
86
86 if (m_isExploded != other.m_isExploded ||
87 if (m_isExploded != other.m_isExploded ||
87 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
88 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
88 return true;
89 return true;
89
90
90 if (m_isLabelVisible != other.m_isLabelVisible ||
91 if (m_isLabelVisible != other.m_isLabelVisible ||
91 m_labelText != other.m_labelText ||
92 m_labelText != other.m_labelText ||
92 m_labelFont != other.m_labelFont ||
93 m_labelFont != other.m_labelFont ||
93 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
94 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
94 m_labelPen != other.m_labelPen)
95 m_labelPen != other.m_labelPen)
95 return true;
96 return true;
96
97
97 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
98 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
98 m_center != other.m_center ||
99 m_center != other.m_center ||
99 !qFuzzyIsNull(m_radius - other.m_radius) ||
100 !qFuzzyIsNull(m_radius - other.m_radius) ||
100 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
101 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
101 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
102 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
102 return true;
103 return true;
103
104
104 return false;
105 return false;
105 }
106 }
106
107
108 void emitChangedSignal(QPieSlice *s)
109 {
110 emit s->changed();
111 }
112
107 qreal m_value;
113 qreal m_value;
108
114
109 Themed<QPen> m_slicePen;
115 Themed<QPen> m_slicePen;
110 Themed<QBrush> m_sliceBrush;
116 Themed<QBrush> m_sliceBrush;
111
117
112 bool m_isExploded;
118 bool m_isExploded;
113 qreal m_explodeDistanceFactor;
119 qreal m_explodeDistanceFactor;
114
120
115 bool m_isLabelVisible;
121 bool m_isLabelVisible;
116 QString m_labelText;
122 QString m_labelText;
117 Themed<QFont> m_labelFont;
123 Themed<QFont> m_labelFont;
118 qreal m_labelArmLengthFactor;
124 qreal m_labelArmLengthFactor;
119 Themed<QPen> m_labelPen;
125 Themed<QPen> m_labelPen;
120
126
121 qreal m_percentage;
127 qreal m_percentage;
122 QPointF m_center;
128 QPointF m_center;
123 qreal m_radius;
129 qreal m_radius;
124 qreal m_startAngle;
130 qreal m_startAngle;
125 qreal m_angleSpan;
131 qreal m_angleSpan;
126 };
132 };
127
133
128 QTCOMMERCIALCHART_END_NAMESPACE
134 QTCOMMERCIALCHART_END_NAMESPACE
129
135
130 #endif // PIESLICEDATA_P_H
136 #endif // PIESLICEDATA_P_H
@@ -1,79 +1,79
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 PIESLICEITEM_H
21 #ifndef PIESLICEITEM_H
22 #define PIESLICEITEM_H
22 #define PIESLICEITEM_H
23
23
24 #include "qchartglobal.h"
24 #include "qchartglobal.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "qpieseries.h"
26 #include "qpieseries.h"
27 #include "qpiesliceprivate_p.h"
27 #include "pieslicedata_p.h"
28 #include <QGraphicsItem>
28 #include <QGraphicsItem>
29 #include <QRectF>
29 #include <QRectF>
30 #include <QColor>
30 #include <QColor>
31 #include <QPen>
31 #include <QPen>
32
32
33 #define PIESLICE_LABEL_GAP 5
33 #define PIESLICE_LABEL_GAP 5
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 class PieChartItem;
36 class PieChartItem;
37 class PieSliceLabel;
37 class PieSliceLabel;
38 class QPieSlice;
38 class QPieSlice;
39
39
40 class PieSliceItem : public QGraphicsObject
40 class PieSliceItem : public QGraphicsObject
41 {
41 {
42 Q_OBJECT
42 Q_OBJECT
43
43
44 public:
44 public:
45 PieSliceItem(QGraphicsItem* parent = 0);
45 PieSliceItem(QGraphicsItem* parent = 0);
46 ~PieSliceItem();
46 ~PieSliceItem();
47
47
48 public: // from QGraphicsItem
48 public: // from QGraphicsItem
49 QRectF boundingRect() const;
49 QRectF boundingRect() const;
50 QPainterPath shape() const;
50 QPainterPath shape() const;
51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
52 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
53 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
53 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
54 void mousePressEvent(QGraphicsSceneMouseEvent *event);
54 void mousePressEvent(QGraphicsSceneMouseEvent *event);
55
55
56 Q_SIGNALS:
56 Q_SIGNALS:
57 void clicked(Qt::MouseButtons buttons);
57 void clicked(Qt::MouseButtons buttons);
58 void hoverEnter();
58 void hoverEnter();
59 void hoverLeave();
59 void hoverLeave();
60
60
61 public:
61 public:
62 void setSliceData(PieSliceData sliceData);
62 void setSliceData(PieSliceData sliceData);
63 void updateGeometry();
63 void updateGeometry();
64 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
64 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
65 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
65 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
66 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
66 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
67 static QRectF labelTextRect(QFont font, QString text);
67 static QRectF labelTextRect(QFont font, QString text);
68
68
69 private:
69 private:
70 PieSliceData m_data;
70 PieSliceData m_data;
71 QRectF m_boundingRect;
71 QRectF m_boundingRect;
72 QPainterPath m_slicePath;
72 QPainterPath m_slicePath;
73 QPainterPath m_labelArmPath;
73 QPainterPath m_labelArmPath;
74 QRectF m_labelTextRect;
74 QRectF m_labelTextRect;
75 };
75 };
76
76
77 QTCOMMERCIALCHART_END_NAMESPACE
77 QTCOMMERCIALCHART_END_NAMESPACE
78
78
79 #endif // PIESLICEITEM_H
79 #endif // PIESLICEITEM_H
@@ -1,693 +1,694
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 "qpiesliceprivate_p.h"
23 #include "qpieseriesprivate_p.h"
22 #include "qpieseriesprivate_p.h"
23 #include "qpieslice.h"
24 #include "pieslicedata_p.h"
24 #include <QDebug>
25 #include <QDebug>
25
26
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
28
28 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
29 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
29 :QObject(parent),
30 :QObject(parent),
30 q_ptr(parent),
31 q_ptr(parent),
31 m_pieRelativeHorPos(0.5),
32 m_pieRelativeHorPos(0.5),
32 m_pieRelativeVerPos(0.5),
33 m_pieRelativeVerPos(0.5),
33 m_pieRelativeSize(0.7),
34 m_pieRelativeSize(0.7),
34 m_pieStartAngle(0),
35 m_pieStartAngle(0),
35 m_pieEndAngle(360),
36 m_pieEndAngle(360),
36 m_total(0),
37 m_total(0),
37 m_mapValues(0),
38 m_mapValues(0),
38 m_mapLabels(0),
39 m_mapLabels(0),
39 m_mapOrientation(Qt::Horizontal)
40 m_mapOrientation(Qt::Horizontal)
40 {
41 {
41
42
42 }
43 }
43
44
44 QPieSeriesPrivate::~QPieSeriesPrivate()
45 QPieSeriesPrivate::~QPieSeriesPrivate()
45 {
46 {
46
47
47 }
48 }
48
49
49 void QPieSeriesPrivate::updateDerivativeData()
50 void QPieSeriesPrivate::updateDerivativeData()
50 {
51 {
51 m_total = 0;
52 m_total = 0;
52
53
53 // nothing to do?
54 // nothing to do?
54 if (m_slices.count() == 0)
55 if (m_slices.count() == 0)
55 return;
56 return;
56
57
57 // calculate total
58 // calculate total
58 foreach (QPieSlice* s, m_slices)
59 foreach (QPieSlice* s, m_slices)
59 m_total += s->value();
60 m_total += s->value();
60
61
61 // nothing to show..
62 // nothing to show..
62 if (qFuzzyIsNull(m_total))
63 if (qFuzzyIsNull(m_total))
63 return;
64 return;
64
65
65 // update slice attributes
66 // update slice attributes
66 qreal sliceAngle = m_pieStartAngle;
67 qreal sliceAngle = m_pieStartAngle;
67 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
68 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
68 QVector<QPieSlice*> changed;
69 QVector<QPieSlice*> changed;
69 foreach (QPieSlice* s, m_slices) {
70 foreach (QPieSlice* s, m_slices) {
70
71
71 PieSliceData data = s->data_ptr()->m_data;
72 PieSliceData data = *s->data_ptr();
72 data.m_percentage = s->value() / m_total;
73 data.m_percentage = s->value() / m_total;
73 data.m_angleSpan = pieSpan * data.m_percentage;
74 data.m_angleSpan = pieSpan * data.m_percentage;
74 data.m_startAngle = sliceAngle;
75 data.m_startAngle = sliceAngle;
75 sliceAngle += data.m_angleSpan;
76 sliceAngle += data.m_angleSpan;
76
77
77 if (s->data_ptr()->m_data != data) {
78 if (*s->data_ptr() != data) {
78 s->data_ptr()->m_data = data;
79 *s->data_ptr() = data;
79 changed << s;
80 changed << s;
80 }
81 }
81 }
82 }
82
83
83 // emit signals
84 // emit signals
84 foreach (QPieSlice* s, changed)
85 foreach (QPieSlice* s, changed)
85 emit s->data_ptr()->changed();
86 s->data_ptr()->emitChangedSignal(s);
86 }
87 }
87
88
88 void QPieSeriesPrivate::sliceChanged()
89 void QPieSeriesPrivate::sliceChanged()
89 {
90 {
90 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
91 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
91 updateDerivativeData();
92 updateDerivativeData();
92 }
93 }
93
94
94 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
95 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
95 {
96 {
96 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
97 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
97 Q_ASSERT(m_slices.contains(slice));
98 Q_ASSERT(m_slices.contains(slice));
98 Q_Q(QPieSeries);
99 Q_Q(QPieSeries);
99 emit q->clicked(slice, buttons);
100 emit q->clicked(slice, buttons);
100 }
101 }
101
102
102 void QPieSeriesPrivate::sliceHoverEnter()
103 void QPieSeriesPrivate::sliceHoverEnter()
103 {
104 {
104 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
105 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
105 Q_ASSERT(m_slices.contains(slice));
106 Q_ASSERT(m_slices.contains(slice));
106 Q_Q(QPieSeries);
107 Q_Q(QPieSeries);
107 emit q->hoverEnter(slice);
108 emit q->hoverEnter(slice);
108 }
109 }
109
110
110 void QPieSeriesPrivate::sliceHoverLeave()
111 void QPieSeriesPrivate::sliceHoverLeave()
111 {
112 {
112 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
113 Q_ASSERT(m_slices.contains(slice));
114 Q_ASSERT(m_slices.contains(slice));
114 Q_Q(QPieSeries);
115 Q_Q(QPieSeries);
115 emit q->hoverLeave(slice);
116 emit q->hoverLeave(slice);
116 }
117 }
117
118
118 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
119 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
119 {
120 {
120 Q_UNUSED(bottomRight)
121 Q_UNUSED(bottomRight)
121 Q_Q(QPieSeries);
122 Q_Q(QPieSeries);
122
123
123 if (m_mapOrientation == Qt::Vertical)
124 if (m_mapOrientation == Qt::Vertical)
124 {
125 {
125 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
126 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
126 if (topLeft.column() == m_mapValues)
127 if (topLeft.column() == m_mapValues)
127 if (m_mapValues == m_mapLabels)
128 if (m_mapValues == m_mapLabels)
128 {
129 {
129 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
130 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
130 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
131 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
131 }
132 }
132 else
133 else
133 {
134 {
134 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
135 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
135 }
136 }
136 else if (topLeft.column() == m_mapLabels)
137 else if (topLeft.column() == m_mapLabels)
137 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
138 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
138 }
139 }
139 else
140 else
140 {
141 {
141 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
142 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
142 if (topLeft.row() == m_mapValues)
143 if (topLeft.row() == m_mapValues)
143 if (m_mapValues == m_mapLabels)
144 if (m_mapValues == m_mapLabels)
144 {
145 {
145 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
146 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
146 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
147 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
147 }
148 }
148 else
149 else
149 {
150 {
150 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
151 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
151 }
152 }
152 else if (topLeft.row() == m_mapLabels)
153 else if (topLeft.row() == m_mapLabels)
153 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
154 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
154 }
155 }
155 }
156 }
156
157
157 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
158 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
158 {
159 {
159 Q_UNUSED(parent)
160 Q_UNUSED(parent)
160 Q_UNUSED(end)
161 Q_UNUSED(end)
161 Q_Q(QPieSeries);
162 Q_Q(QPieSeries);
162
163
163 QPieSlice* newSlice = new QPieSlice;
164 QPieSlice* newSlice = new QPieSlice;
164 newSlice->setLabelVisible(true);
165 newSlice->setLabelVisible(true);
165 if (m_mapOrientation == Qt::Vertical)
166 if (m_mapOrientation == Qt::Vertical)
166 {
167 {
167 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
168 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
168 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
169 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
169 }
170 }
170 else
171 else
171 {
172 {
172 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
173 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
173 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
174 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
174 }
175 }
175
176
176 q->insert(start, newSlice);
177 q->insert(start, newSlice);
177 }
178 }
178
179
179 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
180 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
180 {
181 {
181 Q_UNUSED(parent)
182 Q_UNUSED(parent)
182 Q_UNUSED(end)
183 Q_UNUSED(end)
183 Q_Q(QPieSeries);
184 Q_Q(QPieSeries);
184 q->remove(m_slices.at(start));
185 q->remove(m_slices.at(start));
185 }
186 }
186
187
187
188
188
189
189 /*!
190 /*!
190 \class QPieSeries
191 \class QPieSeries
191 \brief Pie series API for QtCommercial Charts
192 \brief Pie series API for QtCommercial Charts
192
193
193 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
194 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
194 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
195 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
195 The actual slice size is determined by that relative value.
196 The actual slice size is determined by that relative value.
196
197
197 By default the pie is defined as a full pie but it can be a partial pie.
198 By default the pie is defined as a full pie but it can be a partial pie.
198 This can be done by setting a starting angle and angle span to the series.
199 This can be done by setting a starting angle and angle span to the series.
199 */
200 */
200
201
201 /*!
202 /*!
202 Constructs a series object which is a child of \a parent.
203 Constructs a series object which is a child of \a parent.
203 */
204 */
204 QPieSeries::QPieSeries(QObject *parent) :
205 QPieSeries::QPieSeries(QObject *parent) :
205 QSeries(parent),
206 QSeries(parent),
206 d_ptr(new QPieSeriesPrivate(this))
207 d_ptr(new QPieSeriesPrivate(this))
207 {
208 {
208
209
209 }
210 }
210
211
211 /*!
212 /*!
212 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
213 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
213 */
214 */
214 QPieSeries::~QPieSeries()
215 QPieSeries::~QPieSeries()
215 {
216 {
216 // NOTE: d_prt destroyed by QObject
217 // NOTE: d_prt destroyed by QObject
217 }
218 }
218
219
219 /*!
220 /*!
220 Returns QChartSeries::SeriesTypePie.
221 Returns QChartSeries::SeriesTypePie.
221 */
222 */
222 QSeries::QSeriesType QPieSeries::type() const
223 QSeries::QSeriesType QPieSeries::type() const
223 {
224 {
224 return QSeries::SeriesTypePie;
225 return QSeries::SeriesTypePie;
225 }
226 }
226
227
227 /*!
228 /*!
228 Sets an array of \a slices to the series replacing the existing slices.
229 Sets an array of \a slices to the series replacing the existing slices.
229 Slice ownership is passed to the series.
230 Slice ownership is passed to the series.
230 */
231 */
231 void QPieSeries::replace(QList<QPieSlice*> slices)
232 void QPieSeries::replace(QList<QPieSlice*> slices)
232 {
233 {
233 clear();
234 clear();
234 append(slices);
235 append(slices);
235 }
236 }
236
237
237 /*!
238 /*!
238 Adds an array of \a slices to the series.
239 Adds an array of \a slices to the series.
239 Slice ownership is passed to the series.
240 Slice ownership is passed to the series.
240 */
241 */
241 void QPieSeries::append(QList<QPieSlice*> slices)
242 void QPieSeries::append(QList<QPieSlice*> slices)
242 {
243 {
243 Q_D(QPieSeries);
244 Q_D(QPieSeries);
244
245
245 foreach (QPieSlice* s, slices) {
246 foreach (QPieSlice* s, slices) {
246 s->setParent(this);
247 s->setParent(this);
247 d->m_slices << s;
248 d->m_slices << s;
248 }
249 }
249
250
250 d->updateDerivativeData();
251 d->updateDerivativeData();
251
252
252 foreach (QPieSlice* s, slices) {
253 foreach (QPieSlice* s, slices) {
253 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
254 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
254 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
255 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
255 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
256 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
256 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
257 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
257 }
258 }
258
259
259 emit added(slices);
260 emit added(slices);
260 }
261 }
261
262
262 /*!
263 /*!
263 Adds a single \a slice to the series.
264 Adds a single \a slice to the series.
264 Slice ownership is passed to the series.
265 Slice ownership is passed to the series.
265 */
266 */
266 void QPieSeries::append(QPieSlice* slice)
267 void QPieSeries::append(QPieSlice* slice)
267 {
268 {
268 append(QList<QPieSlice*>() << slice);
269 append(QList<QPieSlice*>() << slice);
269 }
270 }
270
271
271 /*!
272 /*!
272 Adds a single \a slice to the series and returns a reference to the series.
273 Adds a single \a slice to the series and returns a reference to the series.
273 Slice ownership is passed to the series.
274 Slice ownership is passed to the series.
274 */
275 */
275 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
276 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
276 {
277 {
277 append(slice);
278 append(slice);
278 return *this;
279 return *this;
279 }
280 }
280
281
281
282
282 /*!
283 /*!
283 Appends a single slice to the series with give \a value and \a name.
284 Appends a single slice to the series with give \a value and \a name.
284 Slice ownership is passed to the series.
285 Slice ownership is passed to the series.
285 */
286 */
286 QPieSlice* QPieSeries::append(qreal value, QString name)
287 QPieSlice* QPieSeries::append(qreal value, QString name)
287 {
288 {
288 QPieSlice* slice = new QPieSlice(value, name);
289 QPieSlice* slice = new QPieSlice(value, name);
289 append(slice);
290 append(slice);
290 return slice;
291 return slice;
291 }
292 }
292
293
293 /*!
294 /*!
294 Inserts a single \a slice to the series before the slice at \a index position.
295 Inserts a single \a slice to the series before the slice at \a index position.
295 Slice ownership is passed to the series.
296 Slice ownership is passed to the series.
296 */
297 */
297 void QPieSeries::insert(int index, QPieSlice* slice)
298 void QPieSeries::insert(int index, QPieSlice* slice)
298 {
299 {
299 Q_D(QPieSeries);
300 Q_D(QPieSeries);
300 Q_ASSERT(index <= d->m_slices.count());
301 Q_ASSERT(index <= d->m_slices.count());
301 slice->setParent(this);
302 slice->setParent(this);
302 d->m_slices.insert(index, slice);
303 d->m_slices.insert(index, slice);
303
304
304 d->updateDerivativeData();
305 d->updateDerivativeData();
305
306
306 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
307 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
307 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
308 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
308 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
309 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
309 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
310 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
310
311
311 emit added(QList<QPieSlice*>() << slice);
312 emit added(QList<QPieSlice*>() << slice);
312 }
313 }
313
314
314 /*!
315 /*!
315 Removes a single \a slice from the series and deletes the slice.
316 Removes a single \a slice from the series and deletes the slice.
316
317
317 Do not reference this pointer after this call.
318 Do not reference this pointer after this call.
318 */
319 */
319 void QPieSeries::remove(QPieSlice* slice)
320 void QPieSeries::remove(QPieSlice* slice)
320 {
321 {
321 Q_D(QPieSeries);
322 Q_D(QPieSeries);
322 if (!d->m_slices.removeOne(slice)) {
323 if (!d->m_slices.removeOne(slice)) {
323 Q_ASSERT(0); // TODO: how should this be reported?
324 Q_ASSERT(0); // TODO: how should this be reported?
324 return;
325 return;
325 }
326 }
326
327
327 d->updateDerivativeData();
328 d->updateDerivativeData();
328
329
329 emit removed(QList<QPieSlice*>() << slice);
330 emit removed(QList<QPieSlice*>() << slice);
330
331
331 delete slice;
332 delete slice;
332 slice = NULL;
333 slice = NULL;
333 }
334 }
334
335
335 /*!
336 /*!
336 Clears all slices from the series.
337 Clears all slices from the series.
337 */
338 */
338 void QPieSeries::clear()
339 void QPieSeries::clear()
339 {
340 {
340 Q_D(QPieSeries);
341 Q_D(QPieSeries);
341 if (d->m_slices.count() == 0)
342 if (d->m_slices.count() == 0)
342 return;
343 return;
343
344
344 QList<QPieSlice*> slices = d->m_slices;
345 QList<QPieSlice*> slices = d->m_slices;
345 foreach (QPieSlice* s, d->m_slices) {
346 foreach (QPieSlice* s, d->m_slices) {
346 d->m_slices.removeOne(s);
347 d->m_slices.removeOne(s);
347 delete s;
348 delete s;
348 }
349 }
349
350
350 d->updateDerivativeData();
351 d->updateDerivativeData();
351
352
352 emit removed(slices);
353 emit removed(slices);
353 }
354 }
354
355
355 /*!
356 /*!
356 Counts the number of the slices in this series.
357 Counts the number of the slices in this series.
357 */
358 */
358 int QPieSeries::count() const
359 int QPieSeries::count() const
359 {
360 {
360 Q_D(const QPieSeries);
361 Q_D(const QPieSeries);
361 return d->m_slices.count();
362 return d->m_slices.count();
362 }
363 }
363
364
364 /*!
365 /*!
365 Returns true is the series is empty.
366 Returns true is the series is empty.
366 */
367 */
367 bool QPieSeries::isEmpty() const
368 bool QPieSeries::isEmpty() const
368 {
369 {
369 Q_D(const QPieSeries);
370 Q_D(const QPieSeries);
370 return d->m_slices.isEmpty();
371 return d->m_slices.isEmpty();
371 }
372 }
372
373
373 /*!
374 /*!
374 Returns a list of slices that belong to this series.
375 Returns a list of slices that belong to this series.
375 */
376 */
376 QList<QPieSlice*> QPieSeries::slices() const
377 QList<QPieSlice*> QPieSeries::slices() const
377 {
378 {
378 Q_D(const QPieSeries);
379 Q_D(const QPieSeries);
379 return d->m_slices;
380 return d->m_slices;
380 }
381 }
381
382
382 /*!
383 /*!
383 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
384 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
384
385
385 The factors are relative to the chart rectangle where:
386 The factors are relative to the chart rectangle where:
386
387
387 \a relativeHorizontalPosition 0.0 means the absolute left.
388 \a relativeHorizontalPosition 0.0 means the absolute left.
388 \a relativeHorizontalPosition 1.0 means the absolute right.
389 \a relativeHorizontalPosition 1.0 means the absolute right.
389 \a relativeVerticalPosition 0.0 means the absolute top.
390 \a relativeVerticalPosition 0.0 means the absolute top.
390 \a relativeVerticalPosition 1.0 means the absolute bottom.
391 \a relativeVerticalPosition 1.0 means the absolute bottom.
391
392
392 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
393 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
393
394
394 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
395 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
395 */
396 */
396 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
397 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
397 {
398 {
398 Q_D(QPieSeries);
399 Q_D(QPieSeries);
399 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
400 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
400 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
401 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
401 return;
402 return;
402
403
403 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativeHorizontalPosition) ||
404 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativeHorizontalPosition) ||
404 !qFuzzyIsNull(d->m_pieRelativeVerPos - relativeVerticalPosition)) {
405 !qFuzzyIsNull(d->m_pieRelativeVerPos - relativeVerticalPosition)) {
405 d->m_pieRelativeHorPos = relativeHorizontalPosition;
406 d->m_pieRelativeHorPos = relativeHorizontalPosition;
406 d->m_pieRelativeVerPos = relativeVerticalPosition;
407 d->m_pieRelativeVerPos = relativeVerticalPosition;
407 emit piePositionChanged();
408 emit piePositionChanged();
408 }
409 }
409 }
410 }
410
411
411 /*!
412 /*!
412 Gets the horizontal position of the pie.
413 Gets the horizontal position of the pie.
413
414
414 The returned value is relative to the chart rectangle where:
415 The returned value is relative to the chart rectangle where:
415
416
416 0.0 means the absolute left.
417 0.0 means the absolute left.
417 1.0 means the absolute right.
418 1.0 means the absolute right.
418
419
419 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
420 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
420
421
421 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
422 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
422 */
423 */
423 qreal QPieSeries::pieHorizontalPosition() const
424 qreal QPieSeries::pieHorizontalPosition() const
424 {
425 {
425 Q_D(const QPieSeries);
426 Q_D(const QPieSeries);
426 return d->m_pieRelativeHorPos;
427 return d->m_pieRelativeHorPos;
427 }
428 }
428
429
429 /*!
430 /*!
430 Gets the vertical position position of the pie.
431 Gets the vertical position position of the pie.
431
432
432 The returned value is relative to the chart rectangle where:
433 The returned value is relative to the chart rectangle where:
433
434
434 0.0 means the absolute top.
435 0.0 means the absolute top.
435 1.0 means the absolute bottom.
436 1.0 means the absolute bottom.
436
437
437 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
438 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
438
439
439 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
440 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
440 */
441 */
441 qreal QPieSeries::pieVerticalPosition() const
442 qreal QPieSeries::pieVerticalPosition() const
442 {
443 {
443 Q_D(const QPieSeries);
444 Q_D(const QPieSeries);
444 return d->m_pieRelativeVerPos;
445 return d->m_pieRelativeVerPos;
445 }
446 }
446
447
447 /*!
448 /*!
448 Sets the relative size of the pie.
449 Sets the relative size of the pie.
449
450
450 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
451 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
451
452
452 Default value is 0.7.
453 Default value is 0.7.
453
454
454 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
455 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
455 */
456 */
456 void QPieSeries::setPieSize(qreal relativeSize)
457 void QPieSeries::setPieSize(qreal relativeSize)
457 {
458 {
458 Q_D(QPieSeries);
459 Q_D(QPieSeries);
459 if (relativeSize < 0.0 || relativeSize > 1.0)
460 if (relativeSize < 0.0 || relativeSize > 1.0)
460 return;
461 return;
461
462
462 if (!qFuzzyIsNull(d->m_pieRelativeSize- relativeSize)) {
463 if (!qFuzzyIsNull(d->m_pieRelativeSize- relativeSize)) {
463 d->m_pieRelativeSize = relativeSize;
464 d->m_pieRelativeSize = relativeSize;
464 emit pieSizeChanged();
465 emit pieSizeChanged();
465 }
466 }
466 }
467 }
467
468
468 /*!
469 /*!
469 Gets the relative size of the pie.
470 Gets the relative size of the pie.
470
471
471 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
472 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
472
473
473 Default value is 0.7.
474 Default value is 0.7.
474
475
475 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
476 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
476 */
477 */
477 qreal QPieSeries::pieSize() const
478 qreal QPieSeries::pieSize() const
478 {
479 {
479 Q_D(const QPieSeries);
480 Q_D(const QPieSeries);
480 return d->m_pieRelativeSize;
481 return d->m_pieRelativeSize;
481 }
482 }
482
483
483
484
484 /*!
485 /*!
485 Sets the end angle of the pie.
486 Sets the end angle of the pie.
486
487
487 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
488 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
488
489
489 \a angle must be less than pie end angle. Default value is 0.
490 \a angle must be less than pie end angle. Default value is 0.
490
491
491 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
492 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
492 */
493 */
493 void QPieSeries::setPieStartAngle(qreal angle)
494 void QPieSeries::setPieStartAngle(qreal angle)
494 {
495 {
495 Q_D(QPieSeries);
496 Q_D(QPieSeries);
496
497
497 if (angle < 0 || angle > 360 || angle > d->m_pieEndAngle)
498 if (angle < 0 || angle > 360 || angle > d->m_pieEndAngle)
498 return;
499 return;
499
500
500 if (!qFuzzyIsNull(angle - d->m_pieStartAngle)) {
501 if (!qFuzzyIsNull(angle - d->m_pieStartAngle)) {
501 d->m_pieStartAngle = angle;
502 d->m_pieStartAngle = angle;
502 d->updateDerivativeData();
503 d->updateDerivativeData();
503 }
504 }
504 }
505 }
505
506
506 /*!
507 /*!
507 Gets the start angle of the pie.
508 Gets the start angle of the pie.
508
509
509 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
510 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
510
511
511 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
512 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
512 */
513 */
513 qreal QPieSeries::pieStartAngle() const
514 qreal QPieSeries::pieStartAngle() const
514 {
515 {
515 Q_D(const QPieSeries);
516 Q_D(const QPieSeries);
516 return d->m_pieStartAngle;
517 return d->m_pieStartAngle;
517 }
518 }
518
519
519 /*!
520 /*!
520 Sets the end angle of the pie.
521 Sets the end angle of the pie.
521
522
522 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
523 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
523
524
524 \a angle must be greater than start angle.
525 \a angle must be greater than start angle.
525
526
526 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
527 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
527 */
528 */
528 void QPieSeries::setPieEndAngle(qreal angle)
529 void QPieSeries::setPieEndAngle(qreal angle)
529 {
530 {
530 Q_D(QPieSeries);
531 Q_D(QPieSeries);
531
532
532 if (angle < 0 || angle > 360 || angle < d->m_pieStartAngle)
533 if (angle < 0 || angle > 360 || angle < d->m_pieStartAngle)
533 return;
534 return;
534
535
535 if (!qFuzzyIsNull(angle - d->m_pieEndAngle)) {
536 if (!qFuzzyIsNull(angle - d->m_pieEndAngle)) {
536 d->m_pieEndAngle = angle;
537 d->m_pieEndAngle = angle;
537 d->updateDerivativeData();
538 d->updateDerivativeData();
538 }
539 }
539 }
540 }
540
541
541 /*!
542 /*!
542 Returns the end angle of the pie.
543 Returns the end angle of the pie.
543
544
544 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
545 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
545
546
546 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
547 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
547 */
548 */
548 qreal QPieSeries::pieEndAngle() const
549 qreal QPieSeries::pieEndAngle() const
549 {
550 {
550 Q_D(const QPieSeries);
551 Q_D(const QPieSeries);
551 return d->m_pieEndAngle;
552 return d->m_pieEndAngle;
552 }
553 }
553
554
554 /*!
555 /*!
555 Sets the all the slice labels \a visible or invisible.
556 Sets the all the slice labels \a visible or invisible.
556
557
557 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
558 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
558 */
559 */
559 void QPieSeries::setLabelsVisible(bool visible)
560 void QPieSeries::setLabelsVisible(bool visible)
560 {
561 {
561 Q_D(QPieSeries);
562 Q_D(QPieSeries);
562 foreach (QPieSlice* s, d->m_slices)
563 foreach (QPieSlice* s, d->m_slices)
563 s->setLabelVisible(visible);
564 s->setLabelVisible(visible);
564 }
565 }
565
566
566 /*!
567 /*!
567 Returns the sum of all slice values in this series.
568 Returns the sum of all slice values in this series.
568
569
569 \sa QPieSlice::value(), QPieSlice::setValue()
570 \sa QPieSlice::value(), QPieSlice::setValue()
570 */
571 */
571 qreal QPieSeries::total() const
572 qreal QPieSeries::total() const
572 {
573 {
573 Q_D(const QPieSeries);
574 Q_D(const QPieSeries);
574 return d->m_total;
575 return d->m_total;
575 }
576 }
576
577
577 /*!
578 /*!
578 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
579 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
579
580
580 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
581 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
581
582
582 \sa QPieSlice::clicked()
583 \sa QPieSlice::clicked()
583 */
584 */
584
585
585 /*!
586 /*!
586 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
587 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
587
588
588 This signal is emitted when user has hovered over a \a slice.
589 This signal is emitted when user has hovered over a \a slice.
589
590
590 \sa QPieSlice::hoverEnter()
591 \sa QPieSlice::hoverEnter()
591 */
592 */
592
593
593 /*!
594 /*!
594 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
595 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
595
596
596 This signal is emitted when user has hovered away from a \a slice.
597 This signal is emitted when user has hovered away from a \a slice.
597
598
598 \sa QPieSlice::hoverLeave()
599 \sa QPieSlice::hoverLeave()
599 */
600 */
600
601
601 /*!
602 /*!
602 \fn void QPieSeries::added(QList<QPieSlice*> slices)
603 \fn void QPieSeries::added(QList<QPieSlice*> slices)
603
604
604 This signal is emitted when \a slices has been added to the series.
605 This signal is emitted when \a slices has been added to the series.
605
606
606 \sa append(), insert()
607 \sa append(), insert()
607 */
608 */
608
609
609 /*!
610 /*!
610 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
611 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
611
612
612 This signal is emitted when \a slices has been removed from the series.
613 This signal is emitted when \a slices has been removed from the series.
613
614
614 \sa remove(), clear()
615 \sa remove(), clear()
615 */
616 */
616
617
617 /*!
618 /*!
618 \fn void QPieSeries::piePositionChanged()
619 \fn void QPieSeries::piePositionChanged()
619
620
620 This signal is emitted when pie position has changed.
621 This signal is emitted when pie position has changed.
621
622
622 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
623 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
623 */
624 */
624
625
625 /*!
626 /*!
626 \fn void QPieSeries::pieSizeChanged()
627 \fn void QPieSeries::pieSizeChanged()
627
628
628 This signal is emitted when pie size has changed.
629 This signal is emitted when pie size has changed.
629
630
630 \sa pieSize(), setPieSize()
631 \sa pieSize(), setPieSize()
631 */
632 */
632
633
633 bool QPieSeries::setModel(QAbstractItemModel* model)
634 bool QPieSeries::setModel(QAbstractItemModel* model)
634 {
635 {
635 Q_D(QPieSeries);
636 Q_D(QPieSeries);
636 // disconnect signals from old model
637 // disconnect signals from old model
637 if(m_model)
638 if(m_model)
638 {
639 {
639 disconnect(m_model, 0, this, 0);
640 disconnect(m_model, 0, this, 0);
640 d->m_mapValues = -1;
641 d->m_mapValues = -1;
641 d->m_mapLabels = -1;
642 d->m_mapLabels = -1;
642 d->m_mapOrientation = Qt::Vertical;
643 d->m_mapOrientation = Qt::Vertical;
643 }
644 }
644
645
645 // set new model
646 // set new model
646 if(model)
647 if(model)
647 {
648 {
648 m_model = model;
649 m_model = model;
649 return true;
650 return true;
650 }
651 }
651 else
652 else
652 {
653 {
653 m_model = NULL;
654 m_model = NULL;
654 return false;
655 return false;
655 }
656 }
656 }
657 }
657
658
658 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
659 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
659 {
660 {
660 Q_D(QPieSeries);
661 Q_D(QPieSeries);
661
662
662 if (m_model == NULL)
663 if (m_model == NULL)
663 return;
664 return;
664
665
665 d->m_mapValues = modelValuesLine;
666 d->m_mapValues = modelValuesLine;
666 d->m_mapLabels = modelLabelsLine;
667 d->m_mapLabels = modelLabelsLine;
667 d->m_mapOrientation = orientation;
668 d->m_mapOrientation = orientation;
668
669
669 // connect the signals
670 // connect the signals
670 if (d->m_mapOrientation == Qt::Vertical) {
671 if (d->m_mapOrientation == Qt::Vertical) {
671 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
672 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
672 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
673 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
673 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
674 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
674 } else {
675 } else {
675 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
676 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
676 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
677 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
677 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
678 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
678 }
679 }
679
680
680 // create the initial slices set
681 // create the initial slices set
681 if (d->m_mapOrientation == Qt::Vertical) {
682 if (d->m_mapOrientation == Qt::Vertical) {
682 for (int i = 0; i < m_model->rowCount(); i++)
683 for (int i = 0; i < m_model->rowCount(); i++)
683 append(m_model->data(m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
684 append(m_model->data(m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
684 } else {
685 } else {
685 for (int i = 0; i < m_model->columnCount(); i++)
686 for (int i = 0; i < m_model->columnCount(); i++)
686 append(m_model->data(m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
687 append(m_model->data(m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
687 }
688 }
688 }
689 }
689
690
690 #include "moc_qpieseries.cpp"
691 #include "moc_qpieseries.cpp"
691 #include "moc_qpieseriesprivate_p.cpp"
692 #include "moc_qpieseriesprivate_p.cpp"
692
693
693 QTCOMMERCIALCHART_END_NAMESPACE
694 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,100 +1,96
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 <qseries.h>
24 #include <qseries.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 class QPieSeriesPrivate;
27 class QPieSeriesPrivate;
28 class QPieSlice;
28 class QPieSlice;
29
29
30 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
30 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
31 {
31 {
32 Q_OBJECT
32 Q_OBJECT
33
33
34 public:
34 public:
35 QPieSeries(QObject *parent = 0);
35 QPieSeries(QObject *parent = 0);
36 virtual ~QPieSeries();
36 virtual ~QPieSeries();
37
37
38 public: // from QChartSeries
38 public: // from QChartSeries
39 QSeriesType type() const;
39 QSeriesType type() const;
40
40
41 public:
41 public:
42
42
43 // slice setters
43 // slice setters
44 void append(QPieSlice* slice);
44 void append(QPieSlice* slice);
45 void append(QList<QPieSlice*> slices);
45 void append(QList<QPieSlice*> slices);
46 void insert(int index, QPieSlice* slice);
46 void insert(int index, QPieSlice* slice);
47 void replace(QList<QPieSlice*> slices);
47 void replace(QList<QPieSlice*> slices);
48 void remove(QPieSlice* slice);
48 void remove(QPieSlice* slice);
49 void clear();
49 void clear();
50
50
51 // slice getters
51 // slice getters
52 QList<QPieSlice*> slices() const;
52 QList<QPieSlice*> slices() const;
53
53
54 // calculated data
54 // calculated data
55 int count() const;
55 int count() const;
56 bool isEmpty() const;
56 bool isEmpty() const;
57 qreal total() const;
57 qreal total() const;
58
58
59 // pie customization
59 // pie customization
60 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
60 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
61 qreal pieHorizontalPosition() const;
61 qreal pieHorizontalPosition() const;
62 qreal pieVerticalPosition() const;
62 qreal pieVerticalPosition() const;
63 void setPieSize(qreal relativeSize);
63 void setPieSize(qreal relativeSize);
64 qreal pieSize() const;
64 qreal pieSize() const;
65 void setPieStartAngle(qreal startAngle);
65 void setPieStartAngle(qreal startAngle);
66 qreal pieStartAngle() const;
66 qreal pieStartAngle() const;
67 void setPieEndAngle(qreal endAngle);
67 void setPieEndAngle(qreal endAngle);
68 qreal pieEndAngle() const;
68 qreal pieEndAngle() const;
69
69
70 // convenience function
70 // convenience function
71 QPieSeries& operator << (QPieSlice* slice);
71 QPieSeries& operator << (QPieSlice* slice);
72 QPieSlice* append(qreal value, QString name);
72 QPieSlice* append(qreal value, QString name);
73 void setLabelsVisible(bool visible = true);
73 void setLabelsVisible(bool visible = true);
74
74
75 // data from model
75 // data from model
76 bool setModel(QAbstractItemModel* model);
76 bool setModel(QAbstractItemModel* model);
77 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
77 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
78
78
79 Q_SIGNALS:
79 Q_SIGNALS:
80 void clicked(QPieSlice* slice, Qt::MouseButtons buttons);
80 void clicked(QPieSlice* slice, Qt::MouseButtons buttons);
81 void hoverEnter(QPieSlice* slice);
81 void hoverEnter(QPieSlice* slice);
82 void hoverLeave(QPieSlice* slice);
82 void hoverLeave(QPieSlice* slice);
83 void added(QList<QPieSlice*> slices);
83 void added(QList<QPieSlice*> slices);
84 void removed(QList<QPieSlice*> slices);
84 void removed(QList<QPieSlice*> slices);
85 void piePositionChanged();
85 void piePositionChanged();
86 void pieSizeChanged();
86 void pieSizeChanged();
87
87
88 private:
88 private:
89 QPieSeriesPrivate * const d_ptr;
89 QPieSeriesPrivate * const d_ptr;
90 Q_DECLARE_PRIVATE(QPieSeries)
90 Q_DECLARE_PRIVATE(QPieSeries)
91 Q_DISABLE_COPY(QPieSeries)
91 Q_DISABLE_COPY(QPieSeries)
92
93 public:
94 typedef QPieSeriesPrivate * const DataPtr;
95 inline DataPtr &data_ptr() { return d_ptr; }
96 };
92 };
97
93
98 QTCOMMERCIALCHART_END_NAMESPACE
94 QTCOMMERCIALCHART_END_NAMESPACE
99
95
100 #endif // PIESERIES_H
96 #endif // PIESERIES_H
@@ -1,433 +1,401
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 "qpieslice.h"
21 #include "qpieslice.h"
22 #include "qpiesliceprivate_p.h"
22 #include "pieslicedata_p.h"
23 #include "qpieseries.h"
24 #include "qpieseriesprivate_p.h"
25
23
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
25
28 /*!
26 /*!
29 \class QPieSlice
27 \class QPieSlice
30 \brief Defines a slice in pie series.
28 \brief Defines a slice in pie series.
31
29
32 Holds all the data of a single slice in a QPieSeries and provides the means
30 Holds all the data of a single slice in a QPieSeries and provides the means
33 to modify slice data and customize the visual appearance of the slice.
31 to modify slice data and customize the visual appearance of the slice.
34
32
35 It also provides the means to customize user interaction with the slice by
33 It also provides the means to customize user interaction with the slice by
36 providing signals for clicking and hover events.
34 providing signals for clicking and hover events.
37 */
35 */
38
36
39 /*!
37 /*!
40 \property QPieSlice::label
38 \property QPieSlice::label
41
39
42 Label of the slice.
40 Label of the slice.
43 */
41 */
44
42
45 /*!
43 /*!
46 \property QPieSlice::value
44 \property QPieSlice::value
47
45
48 Value of the slice.
46 Value of the slice.
49 */
47 */
50
48
51 /*!
49 /*!
52 Constructs an empty slice with a \a parent.
50 Constructs an empty slice with a \a parent.
53
51
54 Note that QPieSeries takes ownership of the slice when it is set/added.
52 Note that QPieSeries takes ownership of the slice when it is set/added.
55
53
56 \sa QPieSeries::replace(), QPieSeries::append()
54 \sa QPieSeries::replace(), QPieSeries::append()
57 */
55 */
58 QPieSlice::QPieSlice(QObject *parent)
56 QPieSlice::QPieSlice(QObject *parent)
59 :QObject(parent),
57 :QObject(parent),
60 d_ptr(new QPieSlicePrivate(this))
58 d(new PieSliceData())
61 {
59 {
62
60
63 }
61 }
64
62
65 /*!
63 /*!
66 Constructs an empty slice with given \a value, \a label and a \a parent.
64 Constructs an empty slice with given \a value, \a label and a \a parent.
67 Note that QPieSeries takes ownership of the slice when it is set/added.
65 Note that QPieSeries takes ownership of the slice when it is set/added.
68 \sa QPieSeries::replace(), QPieSeries::append()
66 \sa QPieSeries::replace(), QPieSeries::append()
69 */
67 */
70 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
68 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
71 :QObject(parent),
69 :QObject(parent),
72 d_ptr(new QPieSlicePrivate(this))
70 d(new PieSliceData())
73 {
71 {
74 Q_D(QPieSlice);
72 d->m_value = value;
75 d->m_data.m_value = value;
73 d->m_labelText = label;
76 d->m_data.m_labelText = label;
77 }
74 }
78
75
79 /*!
76 /*!
80 Destroys the slice.
77 Destroys the slice.
81 User should not delete the slice if it has been added to the series.
78 User should not delete the slice if it has been added to the series.
82 */
79 */
83 QPieSlice::~QPieSlice()
80 QPieSlice::~QPieSlice()
84 {
81 {
85 delete d_ptr;
82 delete d;
86 }
83 }
87
84
88 /*!
85 /*!
89 Gets the value of the slice.
86 Gets the value of the slice.
90 Note that all values in the series
87 Note that all values in the series
91 \sa setValue()
88 \sa setValue()
92 */
89 */
93 qreal QPieSlice::value() const
90 qreal QPieSlice::value() const
94 {
91 {
95 Q_D(const QPieSlice);
92 return d->m_value;
96 return d->m_data.m_value;
97 }
93 }
98
94
99 /*!
95 /*!
100 Gets the label of the slice.
96 Gets the label of the slice.
101 \sa setLabel()
97 \sa setLabel()
102 */
98 */
103 QString QPieSlice::label() const
99 QString QPieSlice::label() const
104 {
100 {
105 Q_D(const QPieSlice);
101 return d->m_labelText;
106 return d->m_data.m_labelText;
107 }
102 }
108
103
109 /*!
104 /*!
110 Returns true if label is set as visible.
105 Returns true if label is set as visible.
111 \sa setLabelVisible()
106 \sa setLabelVisible()
112 */
107 */
113 bool QPieSlice::isLabelVisible() const
108 bool QPieSlice::isLabelVisible() const
114 {
109 {
115 Q_D(const QPieSlice);
110 return d->m_isLabelVisible;
116 return d->m_data.m_isLabelVisible;
117 }
111 }
118
112
119 /*!
113 /*!
120 Returns true if slice is exloded from the pie.
114 Returns true if slice is exloded from the pie.
121 \sa setExploded(), setExplodeDistanceFactor()
115 \sa setExploded(), setExplodeDistanceFactor()
122 */
116 */
123 bool QPieSlice::isExploded() const
117 bool QPieSlice::isExploded() const
124 {
118 {
125 Q_D(const QPieSlice);
119 return d->m_isExploded;
126 return d->m_data.m_isExploded;
127 }
120 }
128
121
129 /*!
122 /*!
130 Returns the explode distance factor.
123 Returns the explode distance factor.
131
124
132 The factor is relative to pie radius. For example:
125 The factor is relative to pie radius. For example:
133 1.0 means the distance is the same as the radius.
126 1.0 means the distance is the same as the radius.
134 0.5 means the distance is half of the radius.
127 0.5 means the distance is half of the radius.
135
128
136 Default value is 0.15.
129 Default value is 0.15.
137
130
138 \sa setExplodeDistanceFactor()
131 \sa setExplodeDistanceFactor()
139 */
132 */
140 qreal QPieSlice::explodeDistanceFactor() const
133 qreal QPieSlice::explodeDistanceFactor() const
141 {
134 {
142 Q_D(const QPieSlice);
135 return d->m_explodeDistanceFactor;
143 return d->m_data.m_explodeDistanceFactor;
144 }
136 }
145
137
146 /*!
138 /*!
147 Returns the percentage of this slice compared to all slices in the same series.
139 Returns the percentage of this slice compared to all slices in the same series.
148 The returned value ranges from 0 to 1.0.
140 The returned value ranges from 0 to 1.0.
149
141
150 Updated internally after the slice is added to the series.
142 Updated internally after the slice is added to the series.
151 */
143 */
152 qreal QPieSlice::percentage() const
144 qreal QPieSlice::percentage() const
153 {
145 {
154 Q_D(const QPieSlice);
146 return d->m_percentage;
155 return d->m_data.m_percentage;
156 }
147 }
157
148
158 /*!
149 /*!
159 Returns the starting angle of this slice in the series it belongs to.
150 Returns the starting angle of this slice in the series it belongs to.
160
151
161 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
152 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
162
153
163 Updated internally after the slice is added to the series.
154 Updated internally after the slice is added to the series.
164 */
155 */
165 qreal QPieSlice::startAngle() const
156 qreal QPieSlice::startAngle() const
166 {
157 {
167 Q_D(const QPieSlice);
158 return d->m_startAngle;
168 return d->m_data.m_startAngle;
169 }
159 }
170
160
171 /*!
161 /*!
172 Returns the end angle of this slice in the series it belongs to.
162 Returns the end angle of this slice in the series it belongs to.
173
163
174 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
164 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
175
165
176 Updated internally after the slice is added to the series.
166 Updated internally after the slice is added to the series.
177 */
167 */
178 qreal QPieSlice::endAngle() const
168 qreal QPieSlice::endAngle() const
179 {
169 {
180 Q_D(const QPieSlice);
170 return d->m_startAngle + d->m_angleSpan;
181 return d->m_data.m_startAngle + d->m_data.m_angleSpan;
182 }
171 }
183
172
184 /*!
173 /*!
185 Returns the pen used to draw this slice.
174 Returns the pen used to draw this slice.
186 \sa setPen()
175 \sa setPen()
187 */
176 */
188 QPen QPieSlice::pen() const
177 QPen QPieSlice::pen() const
189 {
178 {
190 Q_D(const QPieSlice);
179 return d->m_slicePen;
191 return d->m_data.m_slicePen;
192 }
180 }
193
181
194 /*!
182 /*!
195 Returns the brush used to draw this slice.
183 Returns the brush used to draw this slice.
196 \sa setBrush()
184 \sa setBrush()
197 */
185 */
198 QBrush QPieSlice::brush() const
186 QBrush QPieSlice::brush() const
199 {
187 {
200 Q_D(const QPieSlice);
188 return d->m_sliceBrush;
201 return d->m_data.m_sliceBrush;
202 }
189 }
203
190
204 /*!
191 /*!
205 Returns the pen used to draw the label in this slice.
192 Returns the pen used to draw the label in this slice.
206 \sa setLabelPen()
193 \sa setLabelPen()
207 */
194 */
208 QPen QPieSlice::labelPen() const
195 QPen QPieSlice::labelPen() const
209 {
196 {
210 Q_D(const QPieSlice);
197 return d->m_labelPen;
211 return d->m_data.m_labelPen;
212 }
198 }
213
199
214 /*!
200 /*!
215 Returns the font used to draw label in this slice.
201 Returns the font used to draw label in this slice.
216 \sa setLabelFont()
202 \sa setLabelFont()
217 */
203 */
218 QFont QPieSlice::labelFont() const
204 QFont QPieSlice::labelFont() const
219 {
205 {
220 Q_D(const QPieSlice);
206 return d->m_labelFont;
221 return d->m_data.m_labelFont;
222 }
207 }
223
208
224 /*!
209 /*!
225 Gets the label arm length factor.
210 Gets the label arm length factor.
226
211
227 The factor is relative to pie radius. For example:
212 The factor is relative to pie radius. For example:
228 1.0 means the length is the same as the radius.
213 1.0 means the length is the same as the radius.
229 0.5 means the length is half of the radius.
214 0.5 means the length is half of the radius.
230
215
231 Default value is 0.15
216 Default value is 0.15
232
217
233 \sa setLabelArmLengthFactor()
218 \sa setLabelArmLengthFactor()
234 */
219 */
235 qreal QPieSlice::labelArmLengthFactor() const
220 qreal QPieSlice::labelArmLengthFactor() const
236 {
221 {
237 Q_D(const QPieSlice);
222 return d->m_labelArmLengthFactor;
238 return d->m_data.m_labelArmLengthFactor;
239 }
223 }
240
224
241 /*!
225 /*!
242 \fn void QPieSlice::clicked(Qt::MouseButtons buttons)
226 \fn void QPieSlice::clicked(Qt::MouseButtons buttons)
243
227
244 This signal is emitted when user has clicked the slice.
228 This signal is emitted when user has clicked the slice.
245
229
246 \sa QPieSeries::clicked()
230 \sa QPieSeries::clicked()
247 */
231 */
248
232
249 /*!
233 /*!
250 \fn void QPieSlice::hoverEnter()
234 \fn void QPieSlice::hoverEnter()
251
235
252 This signal is emitted when user has hovered over the slice.
236 This signal is emitted when user has hovered over the slice.
253
237
254 \sa QPieSeries::hoverEnter()
238 \sa QPieSeries::hoverEnter()
255 */
239 */
256
240
257 /*!
241 /*!
258 \fn void QPieSlice::hoverLeave()
242 \fn void QPieSlice::hoverLeave()
259
243
260 This signal is emitted when user has hovered away from the slice.
244 This signal is emitted when user has hovered away from the slice.
261
245
262 \sa QPieSeries::hoverLeave()
246 \sa QPieSeries::hoverLeave()
263 */
247 */
264
248
265 /*!
249 /*!
266 \fn void QPieSlice::changed()
250 \fn void QPieSlice::changed()
267
251
268 This signal emitted when something has changed in the slice.
252 This signal emitted when something has changed in the slice.
269
253
270 \sa QPieSeries::changed()
254 \sa QPieSeries::changed()
271 */
255 */
272
256
273 /*!
257 /*!
274 Sets the \a value of this slice.
258 Sets the \a value of this slice.
275 \sa value()
259 \sa value()
276 */
260 */
277 void QPieSlice::setValue(qreal value)
261 void QPieSlice::setValue(qreal value)
278 {
262 {
279 Q_D(QPieSlice);
263 if (!qFuzzyIsNull(d->m_value - value)) {
280 if (!qFuzzyIsNull(d->m_data.m_value - value)) {
264 d->m_value = value;
281 d->m_data.m_value = value;
282
283 QPieSeries *series = qobject_cast<QPieSeries*>(parent());
284 if (series)
285 series->data_ptr()->updateDerivativeData(); // will emit changed()
286 else
287 emit changed();
265 emit changed();
288 }
266 }
289 }
267 }
290
268
291 /*!
269 /*!
292 Sets the \a label of the slice.
270 Sets the \a label of the slice.
293 \sa label()
271 \sa label()
294 */
272 */
295 void QPieSlice::setLabel(QString label)
273 void QPieSlice::setLabel(QString label)
296 {
274 {
297 Q_D(QPieSlice);
275 if (d->m_labelText != label) {
298 if (d->m_data.m_labelText != label) {
276 d->m_labelText = label;
299 d->m_data.m_labelText = label;
300 emit changed();
277 emit changed();
301 }
278 }
302 }
279 }
303
280
304 /*!
281 /*!
305 Sets the label \a visible in this slice.
282 Sets the label \a visible in this slice.
306 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
283 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
307 */
284 */
308 void QPieSlice::setLabelVisible(bool visible)
285 void QPieSlice::setLabelVisible(bool visible)
309 {
286 {
310 Q_D(QPieSlice);
287 if (d->m_isLabelVisible != visible) {
311 if (d->m_data.m_isLabelVisible != visible) {
288 d->m_isLabelVisible = visible;
312 d->m_data.m_isLabelVisible = visible;
313 emit changed();
289 emit changed();
314 }
290 }
315 }
291 }
316
292
317 /*!
293 /*!
318 Sets this slice \a exploded.
294 Sets this slice \a exploded.
319 \sa isExploded(), explodeDistanceFactor()
295 \sa isExploded(), explodeDistanceFactor()
320 */
296 */
321 void QPieSlice::setExploded(bool exploded)
297 void QPieSlice::setExploded(bool exploded)
322 {
298 {
323 Q_D(QPieSlice);
299 if (d->m_isExploded != exploded) {
324 if (d->m_data.m_isExploded != exploded) {
300 d->m_isExploded = exploded;
325 d->m_data.m_isExploded = exploded;
326 emit changed();
301 emit changed();
327 }
302 }
328 }
303 }
329
304
330 /*!
305 /*!
331 Sets the explode distance \a factor.
306 Sets the explode distance \a factor.
332
307
333 The factor is relative to pie radius. For example:
308 The factor is relative to pie radius. For example:
334 1.0 means the distance is the same as the radius.
309 1.0 means the distance is the same as the radius.
335 0.5 means the distance is half of the radius.
310 0.5 means the distance is half of the radius.
336
311
337 Default value is 0.15
312 Default value is 0.15
338
313
339 \sa explodeDistanceFactor()
314 \sa explodeDistanceFactor()
340 */
315 */
341 void QPieSlice::setExplodeDistanceFactor(qreal factor)
316 void QPieSlice::setExplodeDistanceFactor(qreal factor)
342 {
317 {
343 Q_D(QPieSlice);
318 if (!qFuzzyIsNull(d->m_explodeDistanceFactor - factor)) {
344 if (!qFuzzyIsNull(d->m_data.m_explodeDistanceFactor - factor)) {
319 d->m_explodeDistanceFactor = factor;
345 d->m_data.m_explodeDistanceFactor = factor;
346 emit changed();
320 emit changed();
347 }
321 }
348 }
322 }
349
323
350 /*!
324 /*!
351 Sets the \a pen used to draw this slice.
325 Sets the \a pen used to draw this slice.
352 Note that applying a theme will override this.
326 Note that applying a theme will override this.
353 \sa pen()
327 \sa pen()
354 */
328 */
355 void QPieSlice::setPen(const QPen &pen)
329 void QPieSlice::setPen(const QPen &pen)
356 {
330 {
357 Q_D(QPieSlice);
331 if (d->m_slicePen != pen) {
358 if (d->m_data.m_slicePen != pen) {
332 d->m_slicePen = pen;
359 d->m_data.m_slicePen = pen;
333 d->m_slicePen.setThemed(false);
360 d->m_data.m_slicePen.setThemed(false);
361 emit changed();
334 emit changed();
362 }
335 }
363 }
336 }
364
337
365 /*!
338 /*!
366 Sets the \a brush used to draw this slice.
339 Sets the \a brush used to draw this slice.
367 Note that applying a theme will override this.
340 Note that applying a theme will override this.
368 \sa brush()
341 \sa brush()
369 */
342 */
370 void QPieSlice::setBrush(const QBrush &brush)
343 void QPieSlice::setBrush(const QBrush &brush)
371 {
344 {
372 Q_D(QPieSlice);
345 if (d->m_sliceBrush != brush) {
373 if (d->m_data.m_sliceBrush != brush) {
346 d->m_sliceBrush = brush;
374 d->m_data.m_sliceBrush = brush;
347 d->m_sliceBrush.setThemed(false);
375 d->m_data.m_sliceBrush.setThemed(false);
376 emit changed();
348 emit changed();
377 }
349 }
378 }
350 }
379
351
380 /*!
352 /*!
381 Sets the \a pen used to draw the label in this slice.
353 Sets the \a pen used to draw the label in this slice.
382 Note that applying a theme will override this.
354 Note that applying a theme will override this.
383 \sa labelPen()
355 \sa labelPen()
384 */
356 */
385 void QPieSlice::setLabelPen(const QPen &pen)
357 void QPieSlice::setLabelPen(const QPen &pen)
386 {
358 {
387 Q_D(QPieSlice);
359 if (d->m_labelPen != pen) {
388 if (d->m_data.m_labelPen != pen) {
360 d->m_labelPen = pen;
389 d->m_data.m_labelPen = pen;
361 d->m_labelPen.setThemed(false);
390 d->m_data.m_labelPen.setThemed(false);
391 emit changed();
362 emit changed();
392 }
363 }
393 }
364 }
394
365
395 /*!
366 /*!
396 Sets the \a font used to draw the label in this slice.
367 Sets the \a font used to draw the label in this slice.
397 Note that applying a theme will override this.
368 Note that applying a theme will override this.
398 \sa labelFont()
369 \sa labelFont()
399 */
370 */
400 void QPieSlice::setLabelFont(const QFont &font)
371 void QPieSlice::setLabelFont(const QFont &font)
401 {
372 {
402 Q_D(QPieSlice);
373 if (d->m_labelFont != font) {
403 if (d->m_data.m_labelFont != font) {
374 d->m_labelFont = font;
404 d->m_data.m_labelFont = font;
375 d->m_labelFont.setThemed(false);
405 d->m_data.m_labelFont.setThemed(false);
406 emit changed();
376 emit changed();
407 }
377 }
408 }
378 }
409
379
410 /*!
380 /*!
411 Sets the label arm length \a factor.
381 Sets the label arm length \a factor.
412
382
413 The factor is relative to pie radius. For example:
383 The factor is relative to pie radius. For example:
414 1.0 means the length is the same as the radius.
384 1.0 means the length is the same as the radius.
415 0.5 means the length is half of the radius.
385 0.5 means the length is half of the radius.
416
386
417 Default value is 0.15
387 Default value is 0.15
418
388
419 \sa labelArmLengthFactor()
389 \sa labelArmLengthFactor()
420 */
390 */
421 void QPieSlice::setLabelArmLengthFactor(qreal factor)
391 void QPieSlice::setLabelArmLengthFactor(qreal factor)
422 {
392 {
423 Q_D(QPieSlice);
393 if (!qFuzzyIsNull(d->m_labelArmLengthFactor - factor)) {
424 if (!qFuzzyIsNull(d->m_data.m_labelArmLengthFactor - factor)) {
394 d->m_labelArmLengthFactor = factor;
425 d->m_data.m_labelArmLengthFactor = factor;
426 emit changed();
395 emit changed();
427 }
396 }
428 }
397 }
429
398
430 #include "moc_qpieslice.cpp"
399 #include "moc_qpieslice.cpp"
431 #include "moc_qpiesliceprivate_p.cpp"
432
400
433 QTCOMMERCIALCHART_END_NAMESPACE
401 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,91 +1,91
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 QPIESLICE_H
21 #ifndef QPIESLICE_H
22 #define QPIESLICE_H
22 #define QPIESLICE_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <QObject>
25 #include <QObject>
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28 #include <QFont>
28 #include <QFont>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 class QPieSlicePrivate;
31 class PieSliceData;
32
32
33 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
33 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
34 {
34 {
35 Q_OBJECT
35 Q_OBJECT
36 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
36 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
37 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
37 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
38
38
39 public:
39 public:
40 QPieSlice(QObject *parent = 0);
40 QPieSlice(QObject *parent = 0);
41 QPieSlice(qreal value, QString label, QObject *parent = 0);
41 QPieSlice(qreal value, QString label, QObject *parent = 0);
42 virtual ~QPieSlice();
42 virtual ~QPieSlice();
43
43
44 // data
44 // data
45 void setValue(qreal value);
45 void setValue(qreal value);
46 qreal value() const;
46 qreal value() const;
47 void setLabel(QString label);
47 void setLabel(QString label);
48 QString label() const;
48 QString label() const;
49 void setLabelVisible(bool visible = true);
49 void setLabelVisible(bool visible = true);
50 bool isLabelVisible() const;
50 bool isLabelVisible() const;
51 void setExploded(bool exploded = true);
51 void setExploded(bool exploded = true);
52 bool isExploded() const;
52 bool isExploded() const;
53
53
54 // generated data
54 // generated data
55 qreal percentage() const;
55 qreal percentage() const;
56 qreal startAngle() const;
56 qreal startAngle() const;
57 qreal endAngle() const;
57 qreal endAngle() const;
58
58
59 // customization
59 // customization
60 void setPen(const QPen &pen);
60 void setPen(const QPen &pen);
61 QPen pen() const;
61 QPen pen() const;
62 void setBrush(const QBrush &brush);
62 void setBrush(const QBrush &brush);
63 QBrush brush() const;
63 QBrush brush() const;
64 void setLabelPen(const QPen &pen);
64 void setLabelPen(const QPen &pen);
65 QPen labelPen() const;
65 QPen labelPen() const;
66 void setLabelFont(const QFont &font);
66 void setLabelFont(const QFont &font);
67 QFont labelFont() const;
67 QFont labelFont() const;
68 void setLabelArmLengthFactor(qreal factor);
68 void setLabelArmLengthFactor(qreal factor);
69 qreal labelArmLengthFactor() const;
69 qreal labelArmLengthFactor() const;
70 void setExplodeDistanceFactor(qreal factor);
70 void setExplodeDistanceFactor(qreal factor);
71 qreal explodeDistanceFactor() const;
71 qreal explodeDistanceFactor() const;
72
72
73 Q_SIGNALS:
73 Q_SIGNALS:
74 void clicked(Qt::MouseButtons buttons);
74 void clicked(Qt::MouseButtons buttons);
75 void hoverEnter();
75 void hoverEnter();
76 void hoverLeave();
76 void hoverLeave();
77 void changed();
77 void changed();
78
78
79 private:
79 private:
80 QPieSlicePrivate * const d_ptr;
80 friend class PieSliceData;
81 Q_DECLARE_PRIVATE(QPieSlice)
81 PieSliceData * const d;
82 Q_DISABLE_COPY(QPieSlice)
82 Q_DISABLE_COPY(QPieSlice)
83
83
84 public:
84 public:
85 typedef QPieSlicePrivate * const DataPtr;
85 typedef PieSliceData * const DataPtr;
86 inline DataPtr &data_ptr() { return d_ptr; }
86 inline DataPtr &data_ptr() { return d; }
87 };
87 };
88
88
89 QTCOMMERCIALCHART_END_NAMESPACE
89 QTCOMMERCIALCHART_END_NAMESPACE
90
90
91 #endif // QPIESLICE_H
91 #endif // QPIESLICE_H
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now