##// END OF EJS Templates
Polish QPieSlice API by removing the DataPtr stuff
Jani Honkonen -
r822:924499b21823
parent child
Show More
@@ -1,393 +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)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
186 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
187 else
187 else
188 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
188 sets.at(i)->setLabelBrush(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
217 for (int i(0); i < series->slices().count(); i++) {
217 for (int i(0); i < series->slices().count(); i++) {
218
218
219 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);
220
220
221 // 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
222 qreal pos = (qreal) (i + 1) / (qreal) series->count();
222 qreal pos = (qreal) (i + 1) / (qreal) series->count();
223 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
223 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
224
224
225 QPieSlice *s = series->slices().at(i);
225 QPieSlice *s = series->slices().at(i);
226 PieSliceData data = *s->data_ptr();
226 PieSliceData data = PieSliceData::data(s);
227
227
228 if (data.m_slicePen.isThemed() || force) {
228 if (data.m_slicePen.isThemed() || force) {
229 data.m_slicePen = penColor;
229 data.m_slicePen = penColor;
230 data.m_slicePen.setThemed(true);
230 data.m_slicePen.setThemed(true);
231 }
231 }
232
232
233 if (data.m_sliceBrush.isThemed() || force) {
233 if (data.m_sliceBrush.isThemed() || force) {
234 data.m_sliceBrush = brushColor;
234 data.m_sliceBrush = brushColor;
235 data.m_sliceBrush.setThemed(true);
235 data.m_sliceBrush.setThemed(true);
236 }
236 }
237
237
238 if (data.m_labelPen.isThemed() || force) {
238 if (data.m_labelPen.isThemed() || force) {
239 data.m_labelPen = QPen(m_titleBrush.color());
239 data.m_labelPen = QPen(m_titleBrush.color());
240 data.m_labelPen.setThemed(true);
240 data.m_labelPen.setThemed(true);
241 }
241 }
242
242
243 if (data.m_labelFont.isThemed() || force) {
243 if (data.m_labelFont.isThemed() || force) {
244 data.m_labelFont = m_labelFont;
244 data.m_labelFont = m_labelFont;
245 data.m_labelFont.setThemed(true);
245 data.m_labelFont.setThemed(true);
246 }
246 }
247
247
248 if (*s->data_ptr() != data) {
248 if (PieSliceData::data(s) != data) {
249 *s->data_ptr() = data;
249 PieSliceData::data(s) = data;
250 emit s->data_ptr()->emitChangedSignal(s);
250 emit PieSliceData::data(s).emitChangedSignal(s);
251 }
251 }
252 }
252 }
253 }
253 }
254
254
255 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
255 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
256 {
256 {
257 QPen pen;
257 QPen pen;
258 if(pen == series->pen() || force){
258 if(pen == series->pen() || force){
259 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
259 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
260 pen.setWidthF(2);
260 pen.setWidthF(2);
261 series->setPen(pen);
261 series->setPen(pen);
262 }
262 }
263 }
263 }
264
264
265 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
265 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
266 {
266 {
267 QPen pen;
267 QPen pen;
268 QBrush brush;
268 QBrush brush;
269 QFont font;
269 QFont font;
270
270
271 if (axis->isAxisVisible()) {
271 if (axis->isAxisVisible()) {
272
272
273 if(brush == axis->labelsBrush() || force){
273 if(brush == axis->labelsBrush() || force){
274 axis->setLabelsBrush(m_axisLabelBrush);
274 axis->setLabelsBrush(m_axisLabelBrush);
275 }
275 }
276 if(pen == axis->labelsPen() || force){
276 if(pen == axis->labelsPen() || force){
277 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
277 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
278 }
278 }
279
279
280
280
281 if (axis->shadesVisible() || force) {
281 if (axis->shadesVisible() || force) {
282
282
283 if(brush == axis->shadesBrush() || force){
283 if(brush == axis->shadesBrush() || force){
284 axis->setShadesBrush(m_backgroundShadesBrush);
284 axis->setShadesBrush(m_backgroundShadesBrush);
285 }
285 }
286
286
287 if(pen == axis->shadesPen() || force){
287 if(pen == axis->shadesPen() || force){
288 axis->setShadesPen(m_backgroundShadesPen);
288 axis->setShadesPen(m_backgroundShadesPen);
289 }
289 }
290
290
291 if(force && (m_backgroundShades == BackgroundShadesBoth
291 if(force && (m_backgroundShades == BackgroundShadesBoth
292 || (m_backgroundShades == BackgroundShadesVertical && axisX)
292 || (m_backgroundShades == BackgroundShadesVertical && axisX)
293 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
293 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
294 axis->setShadesVisible(true);
294 axis->setShadesVisible(true);
295
295
296 }
296 }
297 }
297 }
298
298
299 if(pen == axis->axisPen() || force){
299 if(pen == axis->axisPen() || force){
300 axis->setAxisPen(m_axisLinePen);
300 axis->setAxisPen(m_axisLinePen);
301 }
301 }
302
302
303 if(pen == axis->gridLinePen() || force){
303 if(pen == axis->gridLinePen() || force){
304 axis->setGridLinePen(m_gridLinePen);
304 axis->setGridLinePen(m_gridLinePen);
305 }
305 }
306
306
307 if(font == axis->labelsFont() || force){
307 if(font == axis->labelsFont() || force){
308 axis->setLabelsFont(m_labelFont);
308 axis->setLabelsFont(m_labelFont);
309 }
309 }
310 }
310 }
311 }
311 }
312
312
313 void ChartTheme::generateSeriesGradients()
313 void ChartTheme::generateSeriesGradients()
314 {
314 {
315 // Generate gradients in HSV color space
315 // Generate gradients in HSV color space
316 foreach (QColor color, m_seriesColors) {
316 foreach (QColor color, m_seriesColors) {
317 QLinearGradient g;
317 QLinearGradient g;
318 qreal h = color.hsvHueF();
318 qreal h = color.hsvHueF();
319 qreal s = color.hsvSaturationF();
319 qreal s = color.hsvSaturationF();
320
320
321 // 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
322 // 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
323 // implementation.
323 // implementation.
324 QColor start = color;
324 QColor start = color;
325 start.setHsvF(h, 0.0, 1.0);
325 start.setHsvF(h, 0.0, 1.0);
326 g.setColorAt(0.0, start);
326 g.setColorAt(0.0, start);
327
327
328 g.setColorAt(0.5, color);
328 g.setColorAt(0.5, color);
329
329
330 QColor end = color;
330 QColor end = color;
331 end.setHsvF(h, s, 0.25);
331 end.setHsvF(h, s, 0.25);
332 g.setColorAt(1.0, end);
332 g.setColorAt(1.0, end);
333
333
334 m_seriesGradients << g;
334 m_seriesGradients << g;
335 }
335 }
336 }
336 }
337
337
338
338
339 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
339 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
340 {
340 {
341 Q_ASSERT(pos >=0.0 && pos <= 1.0);
341 Q_ASSERT(pos >=0.0 && pos <= 1.0);
342 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
342 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
343 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
343 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
344 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
344 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
345 QColor c;
345 QColor c;
346 c.setRgbF(r, g, b);
346 c.setRgbF(r, g, b);
347 return c;
347 return c;
348 }
348 }
349
349
350 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
350 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
351 {
351 {
352 Q_ASSERT(pos >=0 && pos <= 1.0);
352 Q_ASSERT(pos >=0 && pos <= 1.0);
353
353
354 // another possibility:
354 // another possibility:
355 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
355 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
356
356
357 QGradientStops stops = gradient.stops();
357 QGradientStops stops = gradient.stops();
358 int count = stops.count();
358 int count = stops.count();
359
359
360 // find previous stop relative to position
360 // find previous stop relative to position
361 QGradientStop prev = stops.first();
361 QGradientStop prev = stops.first();
362 for (int i=0; i<count; i++) {
362 for (int i=0; i<count; i++) {
363 QGradientStop stop = stops.at(i);
363 QGradientStop stop = stops.at(i);
364 if (pos > stop.first)
364 if (pos > stop.first)
365 prev = stop;
365 prev = stop;
366
366
367 // given position is actually a stop position?
367 // given position is actually a stop position?
368 if (pos == stop.first) {
368 if (pos == stop.first) {
369 //qDebug() << "stop color" << pos;
369 //qDebug() << "stop color" << pos;
370 return stop.second;
370 return stop.second;
371 }
371 }
372 }
372 }
373
373
374 // find next stop relative to position
374 // find next stop relative to position
375 QGradientStop next = stops.last();
375 QGradientStop next = stops.last();
376 for (int i=count-1; i>=0; i--) {
376 for (int i=count-1; i>=0; i--) {
377 QGradientStop stop = stops.at(i);
377 QGradientStop stop = stops.at(i);
378 if (pos < stop.first)
378 if (pos < stop.first)
379 next = stop;
379 next = stop;
380 }
380 }
381
381
382 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
382 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
383
383
384 qreal range = next.first - prev.first;
384 qreal range = next.first - prev.first;
385 qreal posDelta = pos - prev.first;
385 qreal posDelta = pos - prev.first;
386 qreal relativePos = posDelta / range;
386 qreal relativePos = posDelta / range;
387
387
388 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
388 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
389
389
390 return colorAt(prev.second, next.second, relativePos);
390 return colorAt(prev.second, next.second, relativePos);
391 }
391 }
392
392
393 QTCOMMERCIALCHART_END_NAMESPACE
393 QTCOMMERCIALCHART_END_NAMESPACE
@@ -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 "qpieseries.h"
24 #include "qpieseries.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
28 #include <QDebug>
28 #include <QDebug>
29 #include <QPainter>
29 #include <QPainter>
30 #include <QTimer>
30 #include <QTimer>
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
34 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
35 :ChartItem(presenter),
35 :ChartItem(presenter),
36 m_series(series)
36 m_series(series)
37 {
37 {
38 Q_ASSERT(series);
38 Q_ASSERT(series);
39 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
39 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
40 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
40 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
41 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
41 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
42 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
42 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
43
43
44 QTimer::singleShot(0, this, SLOT(initialize()));
44 QTimer::singleShot(0, this, SLOT(initialize()));
45
45
46 // 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
47 setZValue(ChartPresenter::PieSeriesZValue);
47 setZValue(ChartPresenter::PieSeriesZValue);
48 }
48 }
49
49
50 PieChartItem::~PieChartItem()
50 PieChartItem::~PieChartItem()
51 {
51 {
52 // slices deleted automatically through QGraphicsItem
52 // slices deleted automatically through QGraphicsItem
53 }
53 }
54
54
55 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
55 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
56 {
56 {
57 Q_UNUSED(painter)
57 Q_UNUSED(painter)
58 // TODO: paint shadows for all components
58 // TODO: paint shadows for all components
59 // - get paths from items & merge & offset and draw with shadow color?
59 // - get paths from items & merge & offset and draw with shadow color?
60 //painter->setBrush(QBrush(Qt::red));
60 //painter->setBrush(QBrush(Qt::red));
61 //painter->drawRect(m_debugRect);
61 //painter->drawRect(m_debugRect);
62 }
62 }
63
63
64 void PieChartItem::initialize()
64 void PieChartItem::initialize()
65 {
65 {
66 handleSlicesAdded(m_series->slices());
66 handleSlicesAdded(m_series->slices());
67 }
67 }
68
68
69 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
69 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
70 {
70 {
71 bool isEmpty = m_slices.isEmpty();
71 bool isEmpty = m_slices.isEmpty();
72
72
73 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
73 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
74
74
75 foreach (QPieSlice *s, slices) {
75 foreach (QPieSlice *s, slices) {
76 PieSliceItem* item = new PieSliceItem(this);
76 PieSliceItem* item = new PieSliceItem(this);
77 m_slices.insert(s, item);
77 m_slices.insert(s, item);
78 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
78 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
79 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons)));
79 connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons)));
80 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
80 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
81 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
81 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
82
82
83 PieSliceData data = sliceData(s);
83 PieSliceData data = sliceData(s);
84
84
85 if (animator())
85 if (animator())
86 animator()->addAnimation(this, s, data, isEmpty);
86 animator()->addAnimation(this, s, data, isEmpty);
87 else
87 else
88 setLayout(s, data);
88 setLayout(s, data);
89 }
89 }
90 }
90 }
91
91
92 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
92 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
93 {
93 {
94 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
94 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
95
95
96 foreach (QPieSlice *s, slices) {
96 foreach (QPieSlice *s, slices) {
97 if (animator())
97 if (animator())
98 animator()->removeAnimation(this, s);
98 animator()->removeAnimation(this, s);
99 else
99 else
100 destroySlice(s);
100 destroySlice(s);
101 }
101 }
102 }
102 }
103
103
104 void PieChartItem::handlePieLayoutChanged()
104 void PieChartItem::handlePieLayoutChanged()
105 {
105 {
106 PieLayout layout = calculateLayout();
106 PieLayout layout = calculateLayout();
107 applyLayout(layout);
107 applyLayout(layout);
108 update();
108 update();
109 }
109 }
110
110
111 void PieChartItem::handleSliceChanged()
111 void PieChartItem::handleSliceChanged()
112 {
112 {
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
114 Q_ASSERT(m_slices.contains(slice));
114 Q_ASSERT(m_slices.contains(slice));
115 PieSliceData data = sliceData(slice);
115 PieSliceData data = sliceData(slice);
116 updateLayout(slice, data);
116 updateLayout(slice, data);
117 update();
117 update();
118 }
118 }
119
119
120 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
120 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
121 {
121 {
122 // TODO
122 // TODO
123 }
123 }
124
124
125 void PieChartItem::handleGeometryChanged(const QRectF& rect)
125 void PieChartItem::handleGeometryChanged(const QRectF& rect)
126 {
126 {
127 prepareGeometryChange();
127 prepareGeometryChange();
128 m_rect = rect;
128 m_rect = rect;
129 handlePieLayoutChanged();
129 handlePieLayoutChanged();
130 }
130 }
131
131
132 void PieChartItem::calculatePieLayout()
132 void PieChartItem::calculatePieLayout()
133 {
133 {
134 // find pie center coordinates
134 // find pie center coordinates
135 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()));
136 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()));
137
137
138 // find maximum radius for pie
138 // find maximum radius for pie
139 m_pieRadius = m_rect.height() / 2;
139 m_pieRadius = m_rect.height() / 2;
140 if (m_rect.width() < m_rect.height())
140 if (m_rect.width() < m_rect.height())
141 m_pieRadius = m_rect.width() / 2;
141 m_pieRadius = m_rect.width() / 2;
142
142
143 // apply size factor
143 // apply size factor
144 m_pieRadius *= m_series->pieSize();
144 m_pieRadius *= m_series->pieSize();
145 }
145 }
146
146
147 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
147 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
148 {
148 {
149 // TODO: This function is kid of useless now. Refactor.
149 // TODO: This function is kid of useless now. Refactor.
150 PieSliceData sliceData = *slice->data_ptr();
150 PieSliceData sliceData = PieSliceData::data(slice);
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,136 +1,142
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 "qpieslice.h"
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28 #include <QDebug>
28 #include <QDebug>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 template <class T>
32 template <class T>
33 class Themed : public T
33 class Themed : public T
34 {
34 {
35 public:
35 public:
36 Themed():m_isThemed(true) {}
36 Themed():m_isThemed(true) {}
37
37
38 inline T &operator=(const T &other) { return T::operator =(other); }
38 inline T &operator=(const T &other) { return T::operator =(other); }
39
39
40 inline bool operator!=(const T &other) const { return T::operator !=(other); }
40 inline bool operator!=(const T &other) const { return T::operator !=(other); }
41 inline bool operator!=(const Themed &other) const
41 inline bool operator!=(const Themed &other) const
42 {
42 {
43 if (T::operator !=(other))
43 if (T::operator !=(other))
44 return true;
44 return true;
45
45
46 if (m_isThemed != other.m_isThemed)
46 if (m_isThemed != other.m_isThemed)
47 return true;
47 return true;
48
48
49 return false;
49 return false;
50 }
50 }
51
51
52 inline void setThemed(bool state) { m_isThemed = state; }
52 inline void setThemed(bool state) { m_isThemed = state; }
53 inline bool isThemed() const { return m_isThemed; }
53 inline bool isThemed() const { return m_isThemed; }
54
54
55 private:
55 private:
56 bool m_isThemed;
56 bool m_isThemed;
57 };
57 };
58
58
59 class PieSliceData
59 class PieSliceData
60 {
60 {
61 public:
61 public:
62 PieSliceData()
62 PieSliceData()
63 {
63 {
64 m_value = 0;
64 m_value = 0;
65
65
66 m_isExploded = false;
66 m_isExploded = false;
67 m_explodeDistanceFactor = 0.15;
67 m_explodeDistanceFactor = 0.15;
68
68
69 m_isLabelVisible = false;
69 m_isLabelVisible = false;
70 m_labelArmLengthFactor = 0.15;
70 m_labelArmLengthFactor = 0.15;
71
71
72 m_percentage = 0;
72 m_percentage = 0;
73 m_radius = 0;
73 m_radius = 0;
74 m_startAngle = 0;
74 m_startAngle = 0;
75 m_angleSpan = 0;
75 m_angleSpan = 0;
76 }
76 }
77
77
78 bool operator!=(const PieSliceData &other) const
78 bool operator!=(const PieSliceData &other) const
79 {
79 {
80 if (!qFuzzyIsNull(m_value - other.m_value))
80 if (!qFuzzyIsNull(m_value - other.m_value))
81 return true;
81 return true;
82
82
83 if (m_slicePen != other.m_slicePen ||
83 if (m_slicePen != other.m_slicePen ||
84 m_sliceBrush != other.m_sliceBrush)
84 m_sliceBrush != other.m_sliceBrush)
85 return true;
85 return true;
86
86
87 if (m_isExploded != other.m_isExploded ||
87 if (m_isExploded != other.m_isExploded ||
88 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
88 !qFuzzyIsNull(m_explodeDistanceFactor - other.m_explodeDistanceFactor))
89 return true;
89 return true;
90
90
91 if (m_isLabelVisible != other.m_isLabelVisible ||
91 if (m_isLabelVisible != other.m_isLabelVisible ||
92 m_labelText != other.m_labelText ||
92 m_labelText != other.m_labelText ||
93 m_labelFont != other.m_labelFont ||
93 m_labelFont != other.m_labelFont ||
94 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
94 !qFuzzyIsNull(m_labelArmLengthFactor - other.m_labelArmLengthFactor) ||
95 m_labelPen != other.m_labelPen)
95 m_labelPen != other.m_labelPen)
96 return true;
96 return true;
97
97
98 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
98 if (!qFuzzyIsNull(m_percentage - other.m_percentage) ||
99 m_center != other.m_center ||
99 m_center != other.m_center ||
100 !qFuzzyIsNull(m_radius - other.m_radius) ||
100 !qFuzzyIsNull(m_radius - other.m_radius) ||
101 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
101 !qFuzzyIsNull(m_startAngle - other.m_startAngle) ||
102 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
102 !qFuzzyIsNull(m_angleSpan - other.m_angleSpan))
103 return true;
103 return true;
104
104
105 return false;
105 return false;
106 }
106 }
107
107
108 void emitChangedSignal(QPieSlice *s)
108 void emitChangedSignal(QPieSlice *s)
109 {
109 {
110 emit s->changed();
110 emit s->changed();
111 }
111 }
112
112
113 static PieSliceData &data(QPieSlice *slice)
114 {
115 Q_ASSERT(slice);
116 return *slice->d;
117 }
118
113 qreal m_value;
119 qreal m_value;
114
120
115 Themed<QPen> m_slicePen;
121 Themed<QPen> m_slicePen;
116 Themed<QBrush> m_sliceBrush;
122 Themed<QBrush> m_sliceBrush;
117
123
118 bool m_isExploded;
124 bool m_isExploded;
119 qreal m_explodeDistanceFactor;
125 qreal m_explodeDistanceFactor;
120
126
121 bool m_isLabelVisible;
127 bool m_isLabelVisible;
122 QString m_labelText;
128 QString m_labelText;
123 Themed<QFont> m_labelFont;
129 Themed<QFont> m_labelFont;
124 qreal m_labelArmLengthFactor;
130 qreal m_labelArmLengthFactor;
125 Themed<QPen> m_labelPen;
131 Themed<QPen> m_labelPen;
126
132
127 qreal m_percentage;
133 qreal m_percentage;
128 QPointF m_center;
134 QPointF m_center;
129 qreal m_radius;
135 qreal m_radius;
130 qreal m_startAngle;
136 qreal m_startAngle;
131 qreal m_angleSpan;
137 qreal m_angleSpan;
132 };
138 };
133
139
134 QTCOMMERCIALCHART_END_NAMESPACE
140 QTCOMMERCIALCHART_END_NAMESPACE
135
141
136 #endif // PIESLICEDATA_P_H
142 #endif // PIESLICEDATA_P_H
@@ -1,694 +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 "qpieseriesprivate_p.h"
22 #include "qpieseriesprivate_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "pieslicedata_p.h"
24 #include "pieslicedata_p.h"
25 #include <QDebug>
25 #include <QDebug>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
29 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
30 :QObject(parent),
30 :QObject(parent),
31 q_ptr(parent),
31 q_ptr(parent),
32 m_pieRelativeHorPos(0.5),
32 m_pieRelativeHorPos(0.5),
33 m_pieRelativeVerPos(0.5),
33 m_pieRelativeVerPos(0.5),
34 m_pieRelativeSize(0.7),
34 m_pieRelativeSize(0.7),
35 m_pieStartAngle(0),
35 m_pieStartAngle(0),
36 m_pieEndAngle(360),
36 m_pieEndAngle(360),
37 m_total(0),
37 m_total(0),
38 m_mapValues(0),
38 m_mapValues(0),
39 m_mapLabels(0),
39 m_mapLabels(0),
40 m_mapOrientation(Qt::Horizontal)
40 m_mapOrientation(Qt::Horizontal)
41 {
41 {
42
42
43 }
43 }
44
44
45 QPieSeriesPrivate::~QPieSeriesPrivate()
45 QPieSeriesPrivate::~QPieSeriesPrivate()
46 {
46 {
47
47
48 }
48 }
49
49
50 void QPieSeriesPrivate::updateDerivativeData()
50 void QPieSeriesPrivate::updateDerivativeData()
51 {
51 {
52 m_total = 0;
52 m_total = 0;
53
53
54 // nothing to do?
54 // nothing to do?
55 if (m_slices.count() == 0)
55 if (m_slices.count() == 0)
56 return;
56 return;
57
57
58 // calculate total
58 // calculate total
59 foreach (QPieSlice* s, m_slices)
59 foreach (QPieSlice* s, m_slices)
60 m_total += s->value();
60 m_total += s->value();
61
61
62 // nothing to show..
62 // nothing to show..
63 if (qFuzzyIsNull(m_total))
63 if (qFuzzyIsNull(m_total))
64 return;
64 return;
65
65
66 // update slice attributes
66 // update slice attributes
67 qreal sliceAngle = m_pieStartAngle;
67 qreal sliceAngle = m_pieStartAngle;
68 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
68 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
69 QVector<QPieSlice*> changed;
69 QVector<QPieSlice*> changed;
70 foreach (QPieSlice* s, m_slices) {
70 foreach (QPieSlice* s, m_slices) {
71
71
72 PieSliceData data = *s->data_ptr();
72 PieSliceData data = PieSliceData::data(s);
73 data.m_percentage = s->value() / m_total;
73 data.m_percentage = s->value() / m_total;
74 data.m_angleSpan = pieSpan * data.m_percentage;
74 data.m_angleSpan = pieSpan * data.m_percentage;
75 data.m_startAngle = sliceAngle;
75 data.m_startAngle = sliceAngle;
76 sliceAngle += data.m_angleSpan;
76 sliceAngle += data.m_angleSpan;
77
77
78 if (*s->data_ptr() != data) {
78 if (PieSliceData::data(s) != data) {
79 *s->data_ptr() = data;
79 PieSliceData::data(s) = data;
80 changed << s;
80 changed << s;
81 }
81 }
82 }
82 }
83
83
84 // emit signals
84 // emit signals
85 foreach (QPieSlice* s, changed)
85 foreach (QPieSlice* s, changed)
86 s->data_ptr()->emitChangedSignal(s);
86 PieSliceData::data(s).emitChangedSignal(s);
87 }
87 }
88
88
89 void QPieSeriesPrivate::sliceChanged()
89 void QPieSeriesPrivate::sliceChanged()
90 {
90 {
91 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
91 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
92 updateDerivativeData();
92 updateDerivativeData();
93 }
93 }
94
94
95 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
95 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
96 {
96 {
97 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
97 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
98 Q_ASSERT(m_slices.contains(slice));
98 Q_ASSERT(m_slices.contains(slice));
99 Q_Q(QPieSeries);
99 Q_Q(QPieSeries);
100 emit q->clicked(slice, buttons);
100 emit q->clicked(slice, buttons);
101 }
101 }
102
102
103 void QPieSeriesPrivate::sliceHoverEnter()
103 void QPieSeriesPrivate::sliceHoverEnter()
104 {
104 {
105 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
105 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
106 Q_ASSERT(m_slices.contains(slice));
106 Q_ASSERT(m_slices.contains(slice));
107 Q_Q(QPieSeries);
107 Q_Q(QPieSeries);
108 emit q->hoverEnter(slice);
108 emit q->hoverEnter(slice);
109 }
109 }
110
110
111 void QPieSeriesPrivate::sliceHoverLeave()
111 void QPieSeriesPrivate::sliceHoverLeave()
112 {
112 {
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
114 Q_ASSERT(m_slices.contains(slice));
114 Q_ASSERT(m_slices.contains(slice));
115 Q_Q(QPieSeries);
115 Q_Q(QPieSeries);
116 emit q->hoverLeave(slice);
116 emit q->hoverLeave(slice);
117 }
117 }
118
118
119 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
119 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
120 {
120 {
121 Q_UNUSED(bottomRight)
121 Q_UNUSED(bottomRight)
122 Q_Q(QPieSeries);
122 Q_Q(QPieSeries);
123
123
124 if (m_mapOrientation == Qt::Vertical)
124 if (m_mapOrientation == Qt::Vertical)
125 {
125 {
126 // 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());
127 if (topLeft.column() == m_mapValues)
127 if (topLeft.column() == m_mapValues)
128 if (m_mapValues == m_mapLabels)
128 if (m_mapValues == m_mapLabels)
129 {
129 {
130 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());
131 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());
132 }
132 }
133 else
133 else
134 {
134 {
135 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());
136 }
136 }
137 else if (topLeft.column() == m_mapLabels)
137 else if (topLeft.column() == m_mapLabels)
138 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());
139 }
139 }
140 else
140 else
141 {
141 {
142 // 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());
143 if (topLeft.row() == m_mapValues)
143 if (topLeft.row() == m_mapValues)
144 if (m_mapValues == m_mapLabels)
144 if (m_mapValues == m_mapLabels)
145 {
145 {
146 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());
147 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());
148 }
148 }
149 else
149 else
150 {
150 {
151 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());
152 }
152 }
153 else if (topLeft.row() == m_mapLabels)
153 else if (topLeft.row() == m_mapLabels)
154 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());
155 }
155 }
156 }
156 }
157
157
158 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
158 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
159 {
159 {
160 Q_UNUSED(parent)
160 Q_UNUSED(parent)
161 Q_UNUSED(end)
161 Q_UNUSED(end)
162 Q_Q(QPieSeries);
162 Q_Q(QPieSeries);
163
163
164 QPieSlice* newSlice = new QPieSlice;
164 QPieSlice* newSlice = new QPieSlice;
165 newSlice->setLabelVisible(true);
165 newSlice->setLabelVisible(true);
166 if (m_mapOrientation == Qt::Vertical)
166 if (m_mapOrientation == Qt::Vertical)
167 {
167 {
168 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());
169 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());
170 }
170 }
171 else
171 else
172 {
172 {
173 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());
174 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());
175 }
175 }
176
176
177 q->insert(start, newSlice);
177 q->insert(start, newSlice);
178 }
178 }
179
179
180 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
180 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
181 {
181 {
182 Q_UNUSED(parent)
182 Q_UNUSED(parent)
183 Q_UNUSED(end)
183 Q_UNUSED(end)
184 Q_Q(QPieSeries);
184 Q_Q(QPieSeries);
185 q->remove(m_slices.at(start));
185 q->remove(m_slices.at(start));
186 }
186 }
187
187
188
188
189
189
190 /*!
190 /*!
191 \class QPieSeries
191 \class QPieSeries
192 \brief Pie series API for QtCommercial Charts
192 \brief Pie series API for QtCommercial Charts
193
193
194 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.
195 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.
196 The actual slice size is determined by that relative value.
196 The actual slice size is determined by that relative value.
197
197
198 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.
199 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.
200 */
200 */
201
201
202 /*!
202 /*!
203 Constructs a series object which is a child of \a parent.
203 Constructs a series object which is a child of \a parent.
204 */
204 */
205 QPieSeries::QPieSeries(QObject *parent) :
205 QPieSeries::QPieSeries(QObject *parent) :
206 QSeries(parent),
206 QSeries(parent),
207 d_ptr(new QPieSeriesPrivate(this))
207 d_ptr(new QPieSeriesPrivate(this))
208 {
208 {
209
209
210 }
210 }
211
211
212 /*!
212 /*!
213 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.
214 */
214 */
215 QPieSeries::~QPieSeries()
215 QPieSeries::~QPieSeries()
216 {
216 {
217 // NOTE: d_prt destroyed by QObject
217 // NOTE: d_prt destroyed by QObject
218 }
218 }
219
219
220 /*!
220 /*!
221 Returns QChartSeries::SeriesTypePie.
221 Returns QChartSeries::SeriesTypePie.
222 */
222 */
223 QSeries::QSeriesType QPieSeries::type() const
223 QSeries::QSeriesType QPieSeries::type() const
224 {
224 {
225 return QSeries::SeriesTypePie;
225 return QSeries::SeriesTypePie;
226 }
226 }
227
227
228 /*!
228 /*!
229 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.
230 Slice ownership is passed to the series.
230 Slice ownership is passed to the series.
231 */
231 */
232 void QPieSeries::replace(QList<QPieSlice*> slices)
232 void QPieSeries::replace(QList<QPieSlice*> slices)
233 {
233 {
234 clear();
234 clear();
235 append(slices);
235 append(slices);
236 }
236 }
237
237
238 /*!
238 /*!
239 Adds an array of \a slices to the series.
239 Adds an array of \a slices to the series.
240 Slice ownership is passed to the series.
240 Slice ownership is passed to the series.
241 */
241 */
242 void QPieSeries::append(QList<QPieSlice*> slices)
242 void QPieSeries::append(QList<QPieSlice*> slices)
243 {
243 {
244 Q_D(QPieSeries);
244 Q_D(QPieSeries);
245
245
246 foreach (QPieSlice* s, slices) {
246 foreach (QPieSlice* s, slices) {
247 s->setParent(this);
247 s->setParent(this);
248 d->m_slices << s;
248 d->m_slices << s;
249 }
249 }
250
250
251 d->updateDerivativeData();
251 d->updateDerivativeData();
252
252
253 foreach (QPieSlice* s, slices) {
253 foreach (QPieSlice* s, slices) {
254 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
254 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
255 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
255 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
256 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
256 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
257 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
257 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
258 }
258 }
259
259
260 emit added(slices);
260 emit added(slices);
261 }
261 }
262
262
263 /*!
263 /*!
264 Adds a single \a slice to the series.
264 Adds a single \a slice to the series.
265 Slice ownership is passed to the series.
265 Slice ownership is passed to the series.
266 */
266 */
267 void QPieSeries::append(QPieSlice* slice)
267 void QPieSeries::append(QPieSlice* slice)
268 {
268 {
269 append(QList<QPieSlice*>() << slice);
269 append(QList<QPieSlice*>() << slice);
270 }
270 }
271
271
272 /*!
272 /*!
273 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.
274 Slice ownership is passed to the series.
274 Slice ownership is passed to the series.
275 */
275 */
276 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
276 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
277 {
277 {
278 append(slice);
278 append(slice);
279 return *this;
279 return *this;
280 }
280 }
281
281
282
282
283 /*!
283 /*!
284 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.
285 Slice ownership is passed to the series.
285 Slice ownership is passed to the series.
286 */
286 */
287 QPieSlice* QPieSeries::append(qreal value, QString name)
287 QPieSlice* QPieSeries::append(qreal value, QString name)
288 {
288 {
289 QPieSlice* slice = new QPieSlice(value, name);
289 QPieSlice* slice = new QPieSlice(value, name);
290 append(slice);
290 append(slice);
291 return slice;
291 return slice;
292 }
292 }
293
293
294 /*!
294 /*!
295 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.
296 Slice ownership is passed to the series.
296 Slice ownership is passed to the series.
297 */
297 */
298 void QPieSeries::insert(int index, QPieSlice* slice)
298 void QPieSeries::insert(int index, QPieSlice* slice)
299 {
299 {
300 Q_D(QPieSeries);
300 Q_D(QPieSeries);
301 Q_ASSERT(index <= d->m_slices.count());
301 Q_ASSERT(index <= d->m_slices.count());
302 slice->setParent(this);
302 slice->setParent(this);
303 d->m_slices.insert(index, slice);
303 d->m_slices.insert(index, slice);
304
304
305 d->updateDerivativeData();
305 d->updateDerivativeData();
306
306
307 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
307 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
308 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
308 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
309 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
309 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
310 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
310 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
311
311
312 emit added(QList<QPieSlice*>() << slice);
312 emit added(QList<QPieSlice*>() << slice);
313 }
313 }
314
314
315 /*!
315 /*!
316 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.
317
317
318 Do not reference this pointer after this call.
318 Do not reference this pointer after this call.
319 */
319 */
320 void QPieSeries::remove(QPieSlice* slice)
320 void QPieSeries::remove(QPieSlice* slice)
321 {
321 {
322 Q_D(QPieSeries);
322 Q_D(QPieSeries);
323 if (!d->m_slices.removeOne(slice)) {
323 if (!d->m_slices.removeOne(slice)) {
324 Q_ASSERT(0); // TODO: how should this be reported?
324 Q_ASSERT(0); // TODO: how should this be reported?
325 return;
325 return;
326 }
326 }
327
327
328 d->updateDerivativeData();
328 d->updateDerivativeData();
329
329
330 emit removed(QList<QPieSlice*>() << slice);
330 emit removed(QList<QPieSlice*>() << slice);
331
331
332 delete slice;
332 delete slice;
333 slice = NULL;
333 slice = NULL;
334 }
334 }
335
335
336 /*!
336 /*!
337 Clears all slices from the series.
337 Clears all slices from the series.
338 */
338 */
339 void QPieSeries::clear()
339 void QPieSeries::clear()
340 {
340 {
341 Q_D(QPieSeries);
341 Q_D(QPieSeries);
342 if (d->m_slices.count() == 0)
342 if (d->m_slices.count() == 0)
343 return;
343 return;
344
344
345 QList<QPieSlice*> slices = d->m_slices;
345 QList<QPieSlice*> slices = d->m_slices;
346 foreach (QPieSlice* s, d->m_slices) {
346 foreach (QPieSlice* s, d->m_slices) {
347 d->m_slices.removeOne(s);
347 d->m_slices.removeOne(s);
348 delete s;
348 delete s;
349 }
349 }
350
350
351 d->updateDerivativeData();
351 d->updateDerivativeData();
352
352
353 emit removed(slices);
353 emit removed(slices);
354 }
354 }
355
355
356 /*!
356 /*!
357 Counts the number of the slices in this series.
357 Counts the number of the slices in this series.
358 */
358 */
359 int QPieSeries::count() const
359 int QPieSeries::count() const
360 {
360 {
361 Q_D(const QPieSeries);
361 Q_D(const QPieSeries);
362 return d->m_slices.count();
362 return d->m_slices.count();
363 }
363 }
364
364
365 /*!
365 /*!
366 Returns true is the series is empty.
366 Returns true is the series is empty.
367 */
367 */
368 bool QPieSeries::isEmpty() const
368 bool QPieSeries::isEmpty() const
369 {
369 {
370 Q_D(const QPieSeries);
370 Q_D(const QPieSeries);
371 return d->m_slices.isEmpty();
371 return d->m_slices.isEmpty();
372 }
372 }
373
373
374 /*!
374 /*!
375 Returns a list of slices that belong to this series.
375 Returns a list of slices that belong to this series.
376 */
376 */
377 QList<QPieSlice*> QPieSeries::slices() const
377 QList<QPieSlice*> QPieSeries::slices() const
378 {
378 {
379 Q_D(const QPieSeries);
379 Q_D(const QPieSeries);
380 return d->m_slices;
380 return d->m_slices;
381 }
381 }
382
382
383 /*!
383 /*!
384 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.
385
385
386 The factors are relative to the chart rectangle where:
386 The factors are relative to the chart rectangle where:
387
387
388 \a relativeHorizontalPosition 0.0 means the absolute left.
388 \a relativeHorizontalPosition 0.0 means the absolute left.
389 \a relativeHorizontalPosition 1.0 means the absolute right.
389 \a relativeHorizontalPosition 1.0 means the absolute right.
390 \a relativeVerticalPosition 0.0 means the absolute top.
390 \a relativeVerticalPosition 0.0 means the absolute top.
391 \a relativeVerticalPosition 1.0 means the absolute bottom.
391 \a relativeVerticalPosition 1.0 means the absolute bottom.
392
392
393 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.
394
394
395 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
395 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
396 */
396 */
397 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
397 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
398 {
398 {
399 Q_D(QPieSeries);
399 Q_D(QPieSeries);
400 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
400 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
401 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
401 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
402 return;
402 return;
403
403
404 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativeHorizontalPosition) ||
404 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativeHorizontalPosition) ||
405 !qFuzzyIsNull(d->m_pieRelativeVerPos - relativeVerticalPosition)) {
405 !qFuzzyIsNull(d->m_pieRelativeVerPos - relativeVerticalPosition)) {
406 d->m_pieRelativeHorPos = relativeHorizontalPosition;
406 d->m_pieRelativeHorPos = relativeHorizontalPosition;
407 d->m_pieRelativeVerPos = relativeVerticalPosition;
407 d->m_pieRelativeVerPos = relativeVerticalPosition;
408 emit piePositionChanged();
408 emit piePositionChanged();
409 }
409 }
410 }
410 }
411
411
412 /*!
412 /*!
413 Gets the horizontal position of the pie.
413 Gets the horizontal position of the pie.
414
414
415 The returned value is relative to the chart rectangle where:
415 The returned value is relative to the chart rectangle where:
416
416
417 0.0 means the absolute left.
417 0.0 means the absolute left.
418 1.0 means the absolute right.
418 1.0 means the absolute right.
419
419
420 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.
421
421
422 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
422 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
423 */
423 */
424 qreal QPieSeries::pieHorizontalPosition() const
424 qreal QPieSeries::pieHorizontalPosition() const
425 {
425 {
426 Q_D(const QPieSeries);
426 Q_D(const QPieSeries);
427 return d->m_pieRelativeHorPos;
427 return d->m_pieRelativeHorPos;
428 }
428 }
429
429
430 /*!
430 /*!
431 Gets the vertical position position of the pie.
431 Gets the vertical position position of the pie.
432
432
433 The returned value is relative to the chart rectangle where:
433 The returned value is relative to the chart rectangle where:
434
434
435 0.0 means the absolute top.
435 0.0 means the absolute top.
436 1.0 means the absolute bottom.
436 1.0 means the absolute bottom.
437
437
438 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.
439
439
440 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
440 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
441 */
441 */
442 qreal QPieSeries::pieVerticalPosition() const
442 qreal QPieSeries::pieVerticalPosition() const
443 {
443 {
444 Q_D(const QPieSeries);
444 Q_D(const QPieSeries);
445 return d->m_pieRelativeVerPos;
445 return d->m_pieRelativeVerPos;
446 }
446 }
447
447
448 /*!
448 /*!
449 Sets the relative size of the pie.
449 Sets the relative size of the pie.
450
450
451 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.
452
452
453 Default value is 0.7.
453 Default value is 0.7.
454
454
455 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
455 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
456 */
456 */
457 void QPieSeries::setPieSize(qreal relativeSize)
457 void QPieSeries::setPieSize(qreal relativeSize)
458 {
458 {
459 Q_D(QPieSeries);
459 Q_D(QPieSeries);
460 if (relativeSize < 0.0 || relativeSize > 1.0)
460 if (relativeSize < 0.0 || relativeSize > 1.0)
461 return;
461 return;
462
462
463 if (!qFuzzyIsNull(d->m_pieRelativeSize- relativeSize)) {
463 if (!qFuzzyIsNull(d->m_pieRelativeSize- relativeSize)) {
464 d->m_pieRelativeSize = relativeSize;
464 d->m_pieRelativeSize = relativeSize;
465 emit pieSizeChanged();
465 emit pieSizeChanged();
466 }
466 }
467 }
467 }
468
468
469 /*!
469 /*!
470 Gets the relative size of the pie.
470 Gets the relative size of the pie.
471
471
472 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.
473
473
474 Default value is 0.7.
474 Default value is 0.7.
475
475
476 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
476 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
477 */
477 */
478 qreal QPieSeries::pieSize() const
478 qreal QPieSeries::pieSize() const
479 {
479 {
480 Q_D(const QPieSeries);
480 Q_D(const QPieSeries);
481 return d->m_pieRelativeSize;
481 return d->m_pieRelativeSize;
482 }
482 }
483
483
484
484
485 /*!
485 /*!
486 Sets the end angle of the pie.
486 Sets the end angle of the pie.
487
487
488 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.
489
489
490 \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.
491
491
492 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
492 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
493 */
493 */
494 void QPieSeries::setPieStartAngle(qreal angle)
494 void QPieSeries::setPieStartAngle(qreal angle)
495 {
495 {
496 Q_D(QPieSeries);
496 Q_D(QPieSeries);
497
497
498 if (angle < 0 || angle > 360 || angle > d->m_pieEndAngle)
498 if (angle < 0 || angle > 360 || angle > d->m_pieEndAngle)
499 return;
499 return;
500
500
501 if (!qFuzzyIsNull(angle - d->m_pieStartAngle)) {
501 if (!qFuzzyIsNull(angle - d->m_pieStartAngle)) {
502 d->m_pieStartAngle = angle;
502 d->m_pieStartAngle = angle;
503 d->updateDerivativeData();
503 d->updateDerivativeData();
504 }
504 }
505 }
505 }
506
506
507 /*!
507 /*!
508 Gets the start angle of the pie.
508 Gets the start angle of the pie.
509
509
510 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.
511
511
512 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
512 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
513 */
513 */
514 qreal QPieSeries::pieStartAngle() const
514 qreal QPieSeries::pieStartAngle() const
515 {
515 {
516 Q_D(const QPieSeries);
516 Q_D(const QPieSeries);
517 return d->m_pieStartAngle;
517 return d->m_pieStartAngle;
518 }
518 }
519
519
520 /*!
520 /*!
521 Sets the end angle of the pie.
521 Sets the end angle of the pie.
522
522
523 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.
524
524
525 \a angle must be greater than start angle.
525 \a angle must be greater than start angle.
526
526
527 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
527 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
528 */
528 */
529 void QPieSeries::setPieEndAngle(qreal angle)
529 void QPieSeries::setPieEndAngle(qreal angle)
530 {
530 {
531 Q_D(QPieSeries);
531 Q_D(QPieSeries);
532
532
533 if (angle < 0 || angle > 360 || angle < d->m_pieStartAngle)
533 if (angle < 0 || angle > 360 || angle < d->m_pieStartAngle)
534 return;
534 return;
535
535
536 if (!qFuzzyIsNull(angle - d->m_pieEndAngle)) {
536 if (!qFuzzyIsNull(angle - d->m_pieEndAngle)) {
537 d->m_pieEndAngle = angle;
537 d->m_pieEndAngle = angle;
538 d->updateDerivativeData();
538 d->updateDerivativeData();
539 }
539 }
540 }
540 }
541
541
542 /*!
542 /*!
543 Returns the end angle of the pie.
543 Returns the end angle of the pie.
544
544
545 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.
546
546
547 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
547 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
548 */
548 */
549 qreal QPieSeries::pieEndAngle() const
549 qreal QPieSeries::pieEndAngle() const
550 {
550 {
551 Q_D(const QPieSeries);
551 Q_D(const QPieSeries);
552 return d->m_pieEndAngle;
552 return d->m_pieEndAngle;
553 }
553 }
554
554
555 /*!
555 /*!
556 Sets the all the slice labels \a visible or invisible.
556 Sets the all the slice labels \a visible or invisible.
557
557
558 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
558 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
559 */
559 */
560 void QPieSeries::setLabelsVisible(bool visible)
560 void QPieSeries::setLabelsVisible(bool visible)
561 {
561 {
562 Q_D(QPieSeries);
562 Q_D(QPieSeries);
563 foreach (QPieSlice* s, d->m_slices)
563 foreach (QPieSlice* s, d->m_slices)
564 s->setLabelVisible(visible);
564 s->setLabelVisible(visible);
565 }
565 }
566
566
567 /*!
567 /*!
568 Returns the sum of all slice values in this series.
568 Returns the sum of all slice values in this series.
569
569
570 \sa QPieSlice::value(), QPieSlice::setValue()
570 \sa QPieSlice::value(), QPieSlice::setValue()
571 */
571 */
572 qreal QPieSeries::total() const
572 qreal QPieSeries::total() const
573 {
573 {
574 Q_D(const QPieSeries);
574 Q_D(const QPieSeries);
575 return d->m_total;
575 return d->m_total;
576 }
576 }
577
577
578 /*!
578 /*!
579 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
579 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
580
580
581 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.
582
582
583 \sa QPieSlice::clicked()
583 \sa QPieSlice::clicked()
584 */
584 */
585
585
586 /*!
586 /*!
587 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
587 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
588
588
589 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.
590
590
591 \sa QPieSlice::hoverEnter()
591 \sa QPieSlice::hoverEnter()
592 */
592 */
593
593
594 /*!
594 /*!
595 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
595 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
596
596
597 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.
598
598
599 \sa QPieSlice::hoverLeave()
599 \sa QPieSlice::hoverLeave()
600 */
600 */
601
601
602 /*!
602 /*!
603 \fn void QPieSeries::added(QList<QPieSlice*> slices)
603 \fn void QPieSeries::added(QList<QPieSlice*> slices)
604
604
605 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.
606
606
607 \sa append(), insert()
607 \sa append(), insert()
608 */
608 */
609
609
610 /*!
610 /*!
611 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
611 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
612
612
613 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.
614
614
615 \sa remove(), clear()
615 \sa remove(), clear()
616 */
616 */
617
617
618 /*!
618 /*!
619 \fn void QPieSeries::piePositionChanged()
619 \fn void QPieSeries::piePositionChanged()
620
620
621 This signal is emitted when pie position has changed.
621 This signal is emitted when pie position has changed.
622
622
623 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
623 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
624 */
624 */
625
625
626 /*!
626 /*!
627 \fn void QPieSeries::pieSizeChanged()
627 \fn void QPieSeries::pieSizeChanged()
628
628
629 This signal is emitted when pie size has changed.
629 This signal is emitted when pie size has changed.
630
630
631 \sa pieSize(), setPieSize()
631 \sa pieSize(), setPieSize()
632 */
632 */
633
633
634 bool QPieSeries::setModel(QAbstractItemModel* model)
634 bool QPieSeries::setModel(QAbstractItemModel* model)
635 {
635 {
636 Q_D(QPieSeries);
636 Q_D(QPieSeries);
637 // disconnect signals from old model
637 // disconnect signals from old model
638 if(m_model)
638 if(m_model)
639 {
639 {
640 disconnect(m_model, 0, this, 0);
640 disconnect(m_model, 0, this, 0);
641 d->m_mapValues = -1;
641 d->m_mapValues = -1;
642 d->m_mapLabels = -1;
642 d->m_mapLabels = -1;
643 d->m_mapOrientation = Qt::Vertical;
643 d->m_mapOrientation = Qt::Vertical;
644 }
644 }
645
645
646 // set new model
646 // set new model
647 if(model)
647 if(model)
648 {
648 {
649 m_model = model;
649 m_model = model;
650 return true;
650 return true;
651 }
651 }
652 else
652 else
653 {
653 {
654 m_model = NULL;
654 m_model = NULL;
655 return false;
655 return false;
656 }
656 }
657 }
657 }
658
658
659 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
659 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
660 {
660 {
661 Q_D(QPieSeries);
661 Q_D(QPieSeries);
662
662
663 if (m_model == NULL)
663 if (m_model == NULL)
664 return;
664 return;
665
665
666 d->m_mapValues = modelValuesLine;
666 d->m_mapValues = modelValuesLine;
667 d->m_mapLabels = modelLabelsLine;
667 d->m_mapLabels = modelLabelsLine;
668 d->m_mapOrientation = orientation;
668 d->m_mapOrientation = orientation;
669
669
670 // connect the signals
670 // connect the signals
671 if (d->m_mapOrientation == Qt::Vertical) {
671 if (d->m_mapOrientation == Qt::Vertical) {
672 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)));
673 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)));
674 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)));
675 } else {
675 } else {
676 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)));
677 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)));
678 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)));
679 }
679 }
680
680
681 // create the initial slices set
681 // create the initial slices set
682 if (d->m_mapOrientation == Qt::Vertical) {
682 if (d->m_mapOrientation == Qt::Vertical) {
683 for (int i = 0; i < m_model->rowCount(); i++)
683 for (int i = 0; i < m_model->rowCount(); i++)
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 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());
685 } else {
685 } else {
686 for (int i = 0; i < m_model->columnCount(); i++)
686 for (int i = 0; i < m_model->columnCount(); i++)
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 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());
688 }
688 }
689 }
689 }
690
690
691 #include "moc_qpieseries.cpp"
691 #include "moc_qpieseries.cpp"
692 #include "moc_qpieseriesprivate_p.cpp"
692 #include "moc_qpieseriesprivate_p.cpp"
693
693
694 QTCOMMERCIALCHART_END_NAMESPACE
694 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,91 +1,87
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 PieSliceData;
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 friend class PieSliceData;
80 friend class PieSliceData;
81 PieSliceData * const d;
81 PieSliceData * const d;
82 Q_DISABLE_COPY(QPieSlice)
82 Q_DISABLE_COPY(QPieSlice)
83
84 public:
85 typedef PieSliceData * const DataPtr;
86 inline DataPtr &data_ptr() { return d; }
87 };
83 };
88
84
89 QTCOMMERCIALCHART_END_NAMESPACE
85 QTCOMMERCIALCHART_END_NAMESPACE
90
86
91 #endif // QPIESLICE_H
87 #endif // QPIESLICE_H
General Comments 0
You need to be logged in to leave comments. Login now