##// END OF EJS Templates
Fix setting custom color to pie. Now the pie knows if the color is set by the user.
Jani Honkonen -
r691:02b456949de5
parent child
Show More
@@ -1,365 +1,375
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartview.h"
3 #include "qchartview.h"
4 #include "qlegend.h"
4 #include "qlegend.h"
5 #include "qchartaxis.h"
5 #include "qchartaxis.h"
6 #include <QTime>
6 #include <QTime>
7
7
8 //series
8 //series
9 #include "qbarset.h"
9 #include "qbarset.h"
10 #include "qbarseries.h"
10 #include "qbarseries.h"
11 #include "qstackedbarseries.h"
11 #include "qstackedbarseries.h"
12 #include "qpercentbarseries.h"
12 #include "qpercentbarseries.h"
13 #include "qlineseries.h"
13 #include "qlineseries.h"
14 #include "qareaseries.h"
14 #include "qareaseries.h"
15 #include "qscatterseries.h"
15 #include "qscatterseries.h"
16 #include "qpieseries.h"
16 #include "qpieseries.h"
17 #include "qpieslice.h"
17 #include "qpieslice.h"
18 #include "qsplineseries.h"
18 #include "qsplineseries.h"
19
19
20 //items
20 //items
21 #include "axisitem_p.h"
21 #include "axisitem_p.h"
22 #include "barchartitem_p.h"
22 #include "barchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
23 #include "stackedbarchartitem_p.h"
24 #include "percentbarchartitem_p.h"
24 #include "percentbarchartitem_p.h"
25 #include "linechartitem_p.h"
25 #include "linechartitem_p.h"
26 #include "areachartitem_p.h"
26 #include "areachartitem_p.h"
27 #include "scatterchartitem_p.h"
27 #include "scatterchartitem_p.h"
28 #include "piechartitem_p.h"
28 #include "piechartitem_p.h"
29 #include "splinechartitem_p.h"
29 #include "splinechartitem_p.h"
30
30
31 //themes
31 //themes
32 #include "chartthemedefault_p.h"
32 #include "chartthemedefault_p.h"
33 #include "chartthemelight_p.h"
33 #include "chartthemelight_p.h"
34 #include "chartthemebluecerulean_p.h"
34 #include "chartthemebluecerulean_p.h"
35 #include "chartthemedark_p.h"
35 #include "chartthemedark_p.h"
36 #include "chartthemebrownsand_p.h"
36 #include "chartthemebrownsand_p.h"
37 #include "chartthemebluencs_p.h"
37 #include "chartthemebluencs_p.h"
38 #include "chartthemevanilla_p.h"
38 #include "chartthemevanilla_p.h"
39 #include "chartthemeicy_p.h"
39 #include "chartthemeicy_p.h"
40 #include "chartthemegrayscale_p.h"
40 #include "chartthemegrayscale_p.h"
41 #include "chartthemescientific_p.h"
41 #include "chartthemescientific_p.h"
42
42
43 QTCOMMERCIALCHART_BEGIN_NAMESPACE
43 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44
44
45 ChartTheme::ChartTheme(QChart::ChartTheme id) :
45 ChartTheme::ChartTheme(QChart::ChartTheme id) :
46 m_masterFont(QFont()),
46 m_masterFont(QFont()),
47 m_titleBrush(QColor(QRgb(0x000000))),
47 m_titleBrush(QColor(QRgb(0x000000))),
48 m_axisLinePen(QPen(QRgb(0x000000))),
48 m_axisLinePen(QPen(QRgb(0x000000))),
49 m_axisLabelBrush(QColor(QRgb(0x000000))),
49 m_axisLabelBrush(QColor(QRgb(0x000000))),
50 m_backgroundShadesPen(Qt::NoPen),
50 m_backgroundShadesPen(Qt::NoPen),
51 m_backgroundShadesBrush(Qt::NoBrush),
51 m_backgroundShadesBrush(Qt::NoBrush),
52 m_backgroundShades(BackgroundShadesNone),
52 m_backgroundShades(BackgroundShadesNone),
53 m_gridLinePen(QPen(QRgb(0x000000)))
53 m_gridLinePen(QPen(QRgb(0x000000)))
54 {
54 {
55 m_id = id;
55 m_id = id;
56 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
56 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
57 }
57 }
58
58
59
59
60 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
60 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
61 {
61 {
62 switch(theme) {
62 switch(theme) {
63 case QChart::ChartThemeLight:
63 case QChart::ChartThemeLight:
64 return new ChartThemeLight();
64 return new ChartThemeLight();
65 case QChart::ChartThemeBlueCerulean:
65 case QChart::ChartThemeBlueCerulean:
66 return new ChartThemeBlueCerulean();
66 return new ChartThemeBlueCerulean();
67 case QChart::ChartThemeDark:
67 case QChart::ChartThemeDark:
68 return new ChartThemeDark();
68 return new ChartThemeDark();
69 case QChart::ChartThemeBrownSand:
69 case QChart::ChartThemeBrownSand:
70 return new ChartThemeBrownSand();
70 return new ChartThemeBrownSand();
71 case QChart::ChartThemeBlueNcs:
71 case QChart::ChartThemeBlueNcs:
72 return new ChartThemeBlueNcs();
72 return new ChartThemeBlueNcs();
73 case QChart::ChartThemeVanilla:
73 case QChart::ChartThemeVanilla:
74 return new ChartThemeVanilla();
74 return new ChartThemeVanilla();
75 case QChart::ChartThemeIcy:
75 case QChart::ChartThemeIcy:
76 return new ChartThemeIcy();
76 return new ChartThemeIcy();
77 case QChart::ChartThemeGrayscale:
77 case QChart::ChartThemeGrayscale:
78 return new ChartThemeGrayscale();
78 return new ChartThemeGrayscale();
79 case QChart::ChartThemeScientific:
79 case QChart::ChartThemeScientific:
80 return new ChartThemeScientific();
80 return new ChartThemeScientific();
81 default:
81 default:
82 return new ChartThemeDefault();
82 return new ChartThemeDefault();
83 }
83 }
84 }
84 }
85
85
86 void ChartTheme::decorate(QChart* chart,bool force)
86 void ChartTheme::decorate(QChart* chart,bool force)
87 {
87 {
88 QPen pen;
88 QPen pen;
89 QBrush brush;
89 QBrush brush;
90
90
91 if(brush == chart->backgroundBrush() || force)
91 if(brush == chart->backgroundBrush() || force)
92 {
92 {
93 if (m_backgroundShades == BackgroundShadesNone) {
93 if (m_backgroundShades == BackgroundShadesNone) {
94 chart->setBackgroundBrush(m_chartBackgroundGradient);
94 chart->setBackgroundBrush(m_chartBackgroundGradient);
95 }
95 }
96 else {
96 else {
97 chart->setBackgroundBrush(Qt::NoBrush);
97 chart->setBackgroundBrush(Qt::NoBrush);
98 }
98 }
99 }
99 }
100 chart->setTitleFont(m_masterFont);
100 chart->setTitleFont(m_masterFont);
101 chart->setTitleBrush(m_titleBrush);
101 chart->setTitleBrush(m_titleBrush);
102 }
102 }
103
103
104 void ChartTheme::decorate(QLegend* legend,bool force)
104 void ChartTheme::decorate(QLegend* legend,bool force)
105 {
105 {
106 QPen pen;
106 QPen pen;
107 QBrush brush;
107 QBrush brush;
108
108
109 if (pen == legend->pen() || force){
109 if (pen == legend->pen() || force){
110 //TODO:: legend->setPen();
110 //TODO:: legend->setPen();
111 }
111 }
112
112
113
113
114 if (brush == legend->brush() || force) {
114 if (brush == legend->brush() || force) {
115 legend->setBrush(m_chartBackgroundGradient);
115 legend->setBrush(m_chartBackgroundGradient);
116 }
116 }
117 }
117 }
118
118
119 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
119 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
120 {
120 {
121 QPen pen;
121 QPen pen;
122 QBrush brush;
122 QBrush brush;
123
123
124 if (pen == series->pen() || force){
124 if (pen == series->pen() || force){
125 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
125 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
126 pen.setWidthF(2);
126 pen.setWidthF(2);
127 series->setPen(pen);
127 series->setPen(pen);
128 }
128 }
129
129
130 if (brush == series->brush() || force) {
130 if (brush == series->brush() || force) {
131 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
131 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
132 series->setBrush(brush);
132 series->setBrush(brush);
133 }
133 }
134 }
134 }
135
135
136
136
137 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
137 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
138 {
138 {
139 QPen pen;
139 QPen pen;
140 if(pen == series->pen() || force ){
140 if(pen == series->pen() || force ){
141 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
141 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
142 pen.setWidthF(2);
142 pen.setWidthF(2);
143 series->setPen(pen);
143 series->setPen(pen);
144 }
144 }
145 }
145 }
146
146
147 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
147 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
148 {
148 {
149 QBrush brush;
149 QBrush brush;
150 QPen pen;
150 QPen pen;
151 QList<QBarSet*> sets = series->barSets();
151 QList<QBarSet*> sets = series->barSets();
152
152
153 qreal takeAtPos = 0.5;
153 qreal takeAtPos = 0.5;
154 qreal step = 0.2;
154 qreal step = 0.2;
155 if (sets.count() > 1 ) {
155 if (sets.count() > 1 ) {
156 step = 1.0 / (qreal) sets.count();
156 step = 1.0 / (qreal) sets.count();
157 if (sets.count() % m_seriesGradients.count())
157 if (sets.count() % m_seriesGradients.count())
158 step *= m_seriesGradients.count();
158 step *= m_seriesGradients.count();
159 else
159 else
160 step *= (m_seriesGradients.count() - 1);
160 step *= (m_seriesGradients.count() - 1);
161 }
161 }
162
162
163 for (int i(0); i < sets.count(); i++) {
163 for (int i(0); i < sets.count(); i++) {
164 int colorIndex = (index + i) % m_seriesGradients.count();
164 int colorIndex = (index + i) % m_seriesGradients.count();
165 if (i > 0 && i % m_seriesGradients.count() == 0) {
165 if (i > 0 && i % m_seriesGradients.count() == 0) {
166 // There is no dedicated base color for each sets, generate more colors
166 // There is no dedicated base color for each sets, generate more colors
167 takeAtPos += step;
167 takeAtPos += step;
168 if (takeAtPos == 1.0)
168 if (takeAtPos == 1.0)
169 takeAtPos += step;
169 takeAtPos += step;
170 takeAtPos -= (int) takeAtPos;
170 takeAtPos -= (int) takeAtPos;
171 }
171 }
172 qDebug() << "pos:" << takeAtPos;
172 qDebug() << "pos:" << takeAtPos;
173 if (brush == sets.at(i)->brush() || force )
173 if (brush == sets.at(i)->brush() || force )
174 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
174 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
175
175
176 // Pick label color from the opposite end of the gradient.
176 // Pick label color from the opposite end of the gradient.
177 // 0.3 as a boundary seems to work well.
177 // 0.3 as a boundary seems to work well.
178 if (takeAtPos < 0.3)
178 if (takeAtPos < 0.3)
179 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
179 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
180 else
180 else
181 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
181 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
182
182
183 if (pen == sets.at(i)->pen() || force) {
183 if (pen == sets.at(i)->pen() || force) {
184 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
184 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
185 sets.at(i)->setPen(c);
185 sets.at(i)->setPen(c);
186 }
186 }
187 }
187 }
188 }
188 }
189
189
190 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
190 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
191 {
191 {
192 QPen pen;
192 QPen pen;
193 QBrush brush;
193 QBrush brush;
194
194
195 if (pen == series->pen() || force) {
195 if (pen == series->pen() || force) {
196 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
196 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
197 pen.setWidthF(2);
197 pen.setWidthF(2);
198 series->setPen(pen);
198 series->setPen(pen);
199 }
199 }
200
200
201 if (brush == series->brush() || force) {
201 if (brush == series->brush() || force) {
202 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
202 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
203 series->setBrush(brush);
203 series->setBrush(brush);
204 }
204 }
205 }
205 }
206
206
207 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
207 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
208 {
208 {
209 QPen pen;
210 QBrush brush;
211
212 for (int i(0); i < series->slices().count(); i++) {
209 for (int i(0); i < series->slices().count(); i++) {
213 if (pen == series->slices().at(i)->slicePen() || force) {
210
214 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
211 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
215 series->slices().at(i)->setSlicePen(penColor);
216 }
217
212
218 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
213 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
219 qreal pos = (qreal) (i + 1) / (qreal) series->count();
214 qreal pos = (qreal) (i + 1) / (qreal) series->count();
220 if (brush == series->slices().at(i)->sliceBrush() || force) {
215 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
221 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
216
222 series->slices().at(i)->setSliceBrush(brushColor);
217 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
218 PieSliceData data = s->m_data;
219
220 if (data.m_slicePen.isThemed() || force) {
221 data.m_slicePen = penColor;
222 data.m_slicePen.setThemed(true);
223 }
224
225 if (data.m_sliceBrush.isThemed() || force) {
226 data.m_sliceBrush = brushColor;
227 data.m_sliceBrush.setThemed(true);
228 }
229
230 if (s->m_data != data) {
231 s->m_data = data;
232 emit s->changed();
223 }
233 }
224 }
234 }
225 }
235 }
226
236
227 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
237 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
228 {
238 {
229 QPen pen;
239 QPen pen;
230 if(pen == series->pen() || force){
240 if(pen == series->pen() || force){
231 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
241 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
232 pen.setWidthF(2);
242 pen.setWidthF(2);
233 series->setPen(pen);
243 series->setPen(pen);
234 }
244 }
235 }
245 }
236
246
237 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
247 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
238 {
248 {
239 QPen pen;
249 QPen pen;
240 QBrush brush;
250 QBrush brush;
241 QFont font;
251 QFont font;
242
252
243 if (axis->isAxisVisible()) {
253 if (axis->isAxisVisible()) {
244
254
245 if(brush == axis->labelsBrush() || force){
255 if(brush == axis->labelsBrush() || force){
246 axis->setLabelsBrush(m_axisLabelBrush);
256 axis->setLabelsBrush(m_axisLabelBrush);
247 }
257 }
248 if(pen == axis->labelsPen() || force){
258 if(pen == axis->labelsPen() || force){
249 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
259 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
250 }
260 }
251
261
252
262
253 if (axis->shadesVisible() || force) {
263 if (axis->shadesVisible() || force) {
254
264
255 if(brush == axis->shadesBrush() || force){
265 if(brush == axis->shadesBrush() || force){
256 axis->setShadesBrush(m_backgroundShadesBrush);
266 axis->setShadesBrush(m_backgroundShadesBrush);
257 }
267 }
258
268
259 if(pen == axis->shadesPen() || force){
269 if(pen == axis->shadesPen() || force){
260 axis->setShadesPen(m_backgroundShadesPen);
270 axis->setShadesPen(m_backgroundShadesPen);
261 }
271 }
262
272
263 if(force && (m_backgroundShades == BackgroundShadesBoth
273 if(force && (m_backgroundShades == BackgroundShadesBoth
264 || (m_backgroundShades == BackgroundShadesVertical && axisX)
274 || (m_backgroundShades == BackgroundShadesVertical && axisX)
265 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
275 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
266 axis->setShadesVisible(true);
276 axis->setShadesVisible(true);
267
277
268 }
278 }
269 }
279 }
270
280
271 if(pen == axis->axisPen() || force){
281 if(pen == axis->axisPen() || force){
272 axis->setAxisPen(m_axisLinePen);
282 axis->setAxisPen(m_axisLinePen);
273 }
283 }
274
284
275 if(pen == axis->gridLinePen() || force){
285 if(pen == axis->gridLinePen() || force){
276 axis->setGridLinePen(m_gridLinePen);
286 axis->setGridLinePen(m_gridLinePen);
277 }
287 }
278
288
279 if(font == axis->labelsFont() || force){
289 if(font == axis->labelsFont() || force){
280 axis->setLabelsFont(m_masterFont);
290 axis->setLabelsFont(m_masterFont);
281 }
291 }
282 }
292 }
283 }
293 }
284
294
285 void ChartTheme::generateSeriesGradients()
295 void ChartTheme::generateSeriesGradients()
286 {
296 {
287 // Generate gradients in HSV color space
297 // Generate gradients in HSV color space
288 foreach (QColor color, m_seriesColors) {
298 foreach (QColor color, m_seriesColors) {
289 QLinearGradient g;
299 QLinearGradient g;
290 qreal h = color.hsvHueF();
300 qreal h = color.hsvHueF();
291 qreal s = color.hsvSaturationF();
301 qreal s = color.hsvSaturationF();
292
302
293 // TODO: tune the algorithm to give nice results with most base colors defined in
303 // TODO: tune the algorithm to give nice results with most base colors defined in
294 // most themes. The rest of the gradients we can define manually in theme specific
304 // most themes. The rest of the gradients we can define manually in theme specific
295 // implementation.
305 // implementation.
296 QColor start = color;
306 QColor start = color;
297 start.setHsvF(h, 0.0, 1.0);
307 start.setHsvF(h, 0.0, 1.0);
298 g.setColorAt(0.0, start);
308 g.setColorAt(0.0, start);
299
309
300 g.setColorAt(0.5, color);
310 g.setColorAt(0.5, color);
301
311
302 QColor end = color;
312 QColor end = color;
303 end.setHsvF(h, s, 0.25);
313 end.setHsvF(h, s, 0.25);
304 g.setColorAt(1.0, end);
314 g.setColorAt(1.0, end);
305
315
306 m_seriesGradients << g;
316 m_seriesGradients << g;
307 }
317 }
308 }
318 }
309
319
310
320
311 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
321 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
312 {
322 {
313 Q_ASSERT(pos >=0.0 && pos <= 1.0);
323 Q_ASSERT(pos >=0.0 && pos <= 1.0);
314 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
324 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
315 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
325 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
316 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
326 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
317 QColor c;
327 QColor c;
318 c.setRgbF(r, g, b);
328 c.setRgbF(r, g, b);
319 return c;
329 return c;
320 }
330 }
321
331
322 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
332 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
323 {
333 {
324 Q_ASSERT(pos >=0 && pos <= 1.0);
334 Q_ASSERT(pos >=0 && pos <= 1.0);
325
335
326 // another possibility:
336 // another possibility:
327 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
337 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
328
338
329 QGradientStops stops = gradient.stops();
339 QGradientStops stops = gradient.stops();
330 int count = stops.count();
340 int count = stops.count();
331
341
332 // find previous stop relative to position
342 // find previous stop relative to position
333 QGradientStop prev = stops.first();
343 QGradientStop prev = stops.first();
334 for (int i=0; i<count; i++) {
344 for (int i=0; i<count; i++) {
335 QGradientStop stop = stops.at(i);
345 QGradientStop stop = stops.at(i);
336 if (pos > stop.first)
346 if (pos > stop.first)
337 prev = stop;
347 prev = stop;
338
348
339 // given position is actually a stop position?
349 // given position is actually a stop position?
340 if (pos == stop.first) {
350 if (pos == stop.first) {
341 //qDebug() << "stop color" << pos;
351 //qDebug() << "stop color" << pos;
342 return stop.second;
352 return stop.second;
343 }
353 }
344 }
354 }
345
355
346 // find next stop relative to position
356 // find next stop relative to position
347 QGradientStop next = stops.last();
357 QGradientStop next = stops.last();
348 for (int i=count-1; i>=0; i--) {
358 for (int i=count-1; i>=0; i--) {
349 QGradientStop stop = stops.at(i);
359 QGradientStop stop = stops.at(i);
350 if (pos < stop.first)
360 if (pos < stop.first)
351 next = stop;
361 next = stop;
352 }
362 }
353
363
354 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
364 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
355
365
356 qreal range = next.first - prev.first;
366 qreal range = next.first - prev.first;
357 qreal posDelta = pos - prev.first;
367 qreal posDelta = pos - prev.first;
358 qreal relativePos = posDelta / range;
368 qreal relativePos = posDelta / range;
359
369
360 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
370 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
361
371
362 return colorAt(prev.second, next.second, relativePos);
372 return colorAt(prev.second, next.second, relativePos);
363 }
373 }
364
374
365 QTCOMMERCIALCHART_END_NAMESPACE
375 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,192 +1,191
1 #include "piechartitem_p.h"
1 #include "piechartitem_p.h"
2 #include "piesliceitem_p.h"
2 #include "piesliceitem_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpiesliceprivate_p.h"
4 #include "qpiesliceprivate_p.h"
5 #include "qpieseries.h"
5 #include "qpieseries.h"
6 #include "chartpresenter_p.h"
6 #include "chartpresenter_p.h"
7 #include "chartdataset_p.h"
7 #include "chartdataset_p.h"
8 #include "chartanimator_p.h"
8 #include "chartanimator_p.h"
9 #include <QDebug>
9 #include <QDebug>
10 #include <QPainter>
10 #include <QPainter>
11 #include <QTimer>
11 #include <QTimer>
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
16 :ChartItem(presenter),
16 :ChartItem(presenter),
17 m_series(series)
17 m_series(series)
18 {
18 {
19 Q_ASSERT(series);
19 Q_ASSERT(series);
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
24
24
25 QTimer::singleShot(0, this, SLOT(initialize()));
25 QTimer::singleShot(0, this, SLOT(initialize()));
26
26
27 // Note: the following does not affect as long as the item does not have anything to paint
27 // Note: the following does not affect as long as the item does not have anything to paint
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieChartItem::~PieChartItem()
31 PieChartItem::~PieChartItem()
32 {
32 {
33 // slices deleted automatically through QGraphicsItem
33 // slices deleted automatically through QGraphicsItem
34 }
34 }
35
35
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
37 {
37 {
38 Q_UNUSED(painter)
38 Q_UNUSED(painter)
39 // TODO: paint shadows for all components
39 // TODO: paint shadows for all components
40 // - get paths from items & merge & offset and draw with shadow color?
40 // - get paths from items & merge & offset and draw with shadow color?
41 //painter->setBrush(QBrush(Qt::red));
41 //painter->setBrush(QBrush(Qt::red));
42 //painter->drawRect(m_debugRect);
42 //painter->drawRect(m_debugRect);
43 }
43 }
44
44
45 void PieChartItem::initialize()
45 void PieChartItem::initialize()
46 {
46 {
47 handleSlicesAdded(m_series->slices());
47 handleSlicesAdded(m_series->slices());
48 }
48 }
49
49
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
51 {
51 {
52 bool isEmpty = m_slices.isEmpty();
52 bool isEmpty = m_slices.isEmpty();
53
53
54 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
54 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
55
55
56 foreach (QPieSlice *s, slices) {
56 foreach (QPieSlice *s, slices) {
57 PieSliceItem* item = new PieSliceItem(this);
57 PieSliceItem* item = new PieSliceItem(this);
58 m_slices.insert(s, item);
58 m_slices.insert(s, item);
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
60 connect(item, SIGNAL(clicked()), s, SIGNAL(clicked()));
60 connect(item, SIGNAL(clicked()), s, SIGNAL(clicked()));
61 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
61 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
62 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
62 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
63
63
64 PieSliceData data = sliceData(s);
64 PieSliceData data = sliceData(s);
65
65
66 if (animator())
66 if (animator())
67 animator()->addAnimation(this, s, data, isEmpty);
67 animator()->addAnimation(this, s, data, isEmpty);
68 else
68 else
69 setLayout(s, data);
69 setLayout(s, data);
70 }
70 }
71 }
71 }
72
72
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
74 {
74 {
75 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
75 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false);
76
76
77 foreach (QPieSlice *s, slices) {
77 foreach (QPieSlice *s, slices) {
78 if (animator())
78 if (animator())
79 animator()->removeAnimation(this, s);
79 animator()->removeAnimation(this, s);
80 else
80 else
81 destroySlice(s);
81 destroySlice(s);
82 }
82 }
83 }
83 }
84
84
85 void PieChartItem::handlePieLayoutChanged()
85 void PieChartItem::handlePieLayoutChanged()
86 {
86 {
87 PieLayout layout = calculateLayout();
87 PieLayout layout = calculateLayout();
88 applyLayout(layout);
88 applyLayout(layout);
89 update();
89 update();
90 }
90 }
91
91
92 void PieChartItem::handleSliceChanged()
92 void PieChartItem::handleSliceChanged()
93 {
93 {
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
95 Q_ASSERT(m_slices.contains(slice));
95 Q_ASSERT(m_slices.contains(slice));
96 PieSliceData data = sliceData(slice);
96 PieSliceData data = sliceData(slice);
97 updateLayout(slice, data);
97 updateLayout(slice, data);
98 update();
98 update();
99 }
99 }
100
100
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
102 {
102 {
103 // TODO
103 // TODO
104 }
104 }
105
105
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
107 {
107 {
108 prepareGeometryChange();
108 prepareGeometryChange();
109 m_rect = rect;
109 m_rect = rect;
110 handlePieLayoutChanged();
110 handlePieLayoutChanged();
111 }
111 }
112
112
113 void PieChartItem::calculatePieLayout()
113 void PieChartItem::calculatePieLayout()
114 {
114 {
115 // find pie center coordinates
115 // find pie center coordinates
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
118
118
119 // find maximum radius for pie
119 // find maximum radius for pie
120 m_pieRadius = m_rect.height() / 2;
120 m_pieRadius = m_rect.height() / 2;
121 if (m_rect.width() < m_rect.height())
121 if (m_rect.width() < m_rect.height())
122 m_pieRadius = m_rect.width() / 2;
122 m_pieRadius = m_rect.width() / 2;
123
123
124 // apply size factor
124 // apply size factor
125 m_pieRadius *= m_series->pieSize();
125 m_pieRadius *= m_series->pieSize();
126 }
126 }
127
127
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
129 {
129 {
130 PieSliceData sliceData = slice->data_ptr()->m_data;
130 PieSliceData sliceData = slice->data_ptr()->m_data;
131 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
131 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
132 sliceData.m_radius = m_pieRadius;
132 sliceData.m_radius = m_pieRadius;
133 sliceData.m_angleSpan = slice->endAngle() - slice->startAngle();
134 return sliceData;
133 return sliceData;
135 }
134 }
136
135
137 PieLayout PieChartItem::calculateLayout()
136 PieLayout PieChartItem::calculateLayout()
138 {
137 {
139 calculatePieLayout();
138 calculatePieLayout();
140 PieLayout layout;
139 PieLayout layout;
141 foreach (QPieSlice* s, m_series->slices()) {
140 foreach (QPieSlice* s, m_series->slices()) {
142 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
141 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
143 layout.insert(s, sliceData(s));
142 layout.insert(s, sliceData(s));
144 }
143 }
145 return layout;
144 return layout;
146 }
145 }
147
146
148 void PieChartItem::applyLayout(const PieLayout &layout)
147 void PieChartItem::applyLayout(const PieLayout &layout)
149 {
148 {
150 if (animator())
149 if (animator())
151 animator()->updateLayout(this, layout);
150 animator()->updateLayout(this, layout);
152 else
151 else
153 setLayout(layout);
152 setLayout(layout);
154 }
153 }
155
154
156 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
155 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
157 {
156 {
158 if (animator())
157 if (animator())
159 animator()->updateLayout(this, slice, sliceData);
158 animator()->updateLayout(this, slice, sliceData);
160 else
159 else
161 setLayout(slice, sliceData);
160 setLayout(slice, sliceData);
162 }
161 }
163
162
164 void PieChartItem::setLayout(const PieLayout &layout)
163 void PieChartItem::setLayout(const PieLayout &layout)
165 {
164 {
166 foreach (QPieSlice *slice, layout.keys()) {
165 foreach (QPieSlice *slice, layout.keys()) {
167 PieSliceItem *item = m_slices.value(slice);
166 PieSliceItem *item = m_slices.value(slice);
168 Q_ASSERT(item);
167 Q_ASSERT(item);
169 item->setSliceData(layout.value(slice));
168 item->setSliceData(layout.value(slice));
170 item->updateGeometry();
169 item->updateGeometry();
171 item->update();
170 item->update();
172 }
171 }
173 }
172 }
174
173
175 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
174 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
176 {
175 {
177 // find slice
176 // find slice
178 PieSliceItem *item = m_slices.value(slice);
177 PieSliceItem *item = m_slices.value(slice);
179 Q_ASSERT(item);
178 Q_ASSERT(item);
180 item->setSliceData(sliceData);
179 item->setSliceData(sliceData);
181 item->updateGeometry();
180 item->updateGeometry();
182 item->update();
181 item->update();
183 }
182 }
184
183
185 void PieChartItem::destroySlice(QPieSlice *slice)
184 void PieChartItem::destroySlice(QPieSlice *slice)
186 {
185 {
187 delete m_slices.take(slice);
186 delete m_slices.take(slice);
188 }
187 }
189
188
190 #include "moc_piechartitem_p.cpp"
189 #include "moc_piechartitem_p.cpp"
191
190
192 QTCOMMERCIALCHART_END_NAMESPACE
191 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,48 +1,110
1 #ifndef PIESLICEDATA_P_H
1 #ifndef PIESLICEDATA_P_H
2 #define PIESLICEDATA_P_H
2 #define PIESLICEDATA_P_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QPen>
5 #include <QPen>
6 #include <QBrush>
6 #include <QBrush>
7 #include <QDebug>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
11 template <class T>
12 class Themed : public T
13 {
14 public:
15 Themed():m_isThemed(true) {}
16
17 inline T &operator=(const T &other) { return T::operator =(other); }
18
19 inline bool operator!=(const T &other) { return T::operator !=(other); }
20 inline bool operator!=(const Themed &other)
21 {
22 if (T::operator !=(other))
23 return true;
24
25 if (m_isThemed != other.m_isThemed)
26 return true;
27
28 return false;
29 }
30
31 inline void setThemed(bool state) { m_isThemed = state; }
32 inline bool isThemed() const { return m_isThemed; }
33
34 private:
35 bool m_isThemed;
36 };
37
10 class PieSliceData
38 class PieSliceData
11 {
39 {
12 public:
40 public:
13 PieSliceData()
41 PieSliceData()
14 {
42 {
15 m_value = 0;
43 m_value = 0;
16 m_percentage = 0;
44
17 m_startAngle = 0;
18 m_angleSpan = 0;
19 m_isExploded = false;
45 m_isExploded = false;
20 m_explodeDistanceFactor = 0.15;
46 m_explodeDistanceFactor = 0.15;
21 m_labelVisible = false;
47
48 m_isLabelVisible = false;
22 m_labelArmLengthFactor = 0.15;
49 m_labelArmLengthFactor = 0.15;
50
51 m_percentage = 0;
52 m_radius = 0;
53 m_startAngle = 0;
54 m_angleSpan = 0;
55 }
56
57 bool operator!=(const PieSliceData &other)
58 {
59 if (m_value != other.m_value)
60 return true;
61
62 if (m_slicePen != other.m_slicePen ||
63 m_sliceBrush != other.m_sliceBrush)
64 return true;
65
66 if (m_isExploded != other.m_isExploded ||
67 m_explodeDistanceFactor != other.m_explodeDistanceFactor)
68 return true;
69
70 if (m_isLabelVisible != other.m_isLabelVisible ||
71 m_labelText != other.m_labelText ||
72 m_labelFont != other.m_labelFont ||
73 m_labelArmLengthFactor != other.m_labelArmLengthFactor ||
74 m_labelArmPen != other.m_labelArmPen)
75 return true;
76
77 if (m_percentage != other.m_percentage ||
78 m_center != other.m_center ||
79 m_radius != other.m_radius ||
80 m_startAngle != other.m_startAngle ||
81 m_angleSpan != other.m_angleSpan)
82 return true;
83
84 return false;
23 }
85 }
24
86
25 qreal m_value;
87 qreal m_value;
26
88
27 QPen m_slicePen;
89 Themed<QPen> m_slicePen;
28 QBrush m_sliceBrush;
90 Themed<QBrush> m_sliceBrush;
29
91
30 bool m_isExploded;
92 bool m_isExploded;
31 qreal m_explodeDistanceFactor;
93 qreal m_explodeDistanceFactor;
32
94
33 bool m_labelVisible;
95 bool m_isLabelVisible;
34 QString m_labelText;
96 QString m_labelText;
35 QFont m_labelFont;
97 Themed<QFont> m_labelFont;
36 qreal m_labelArmLengthFactor;
98 qreal m_labelArmLengthFactor;
37 QPen m_labelArmPen;
99 Themed<QPen> m_labelArmPen;
38
100
39 qreal m_percentage;
101 qreal m_percentage;
40 QPointF m_center;
102 QPointF m_center;
41 qreal m_radius;
103 qreal m_radius;
42 qreal m_startAngle;
104 qreal m_startAngle;
43 qreal m_angleSpan;
105 qreal m_angleSpan;
44 };
106 };
45
107
46 QTCOMMERCIALCHART_END_NAMESPACE
108 QTCOMMERCIALCHART_END_NAMESPACE
47
109
48 #endif // PIESLICEDATA_P_H
110 #endif // PIESLICEDATA_P_H
@@ -1,184 +1,184
1 #include "piesliceitem_p.h"
1 #include "piesliceitem_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
24 :QGraphicsObject(parent)
24 :QGraphicsObject(parent)
25 {
25 {
26 setAcceptHoverEvents(true);
26 setAcceptHoverEvents(true);
27 setAcceptedMouseButtons(Qt::LeftButton);
27 setAcceptedMouseButtons(Qt::LeftButton);
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieSliceItem::~PieSliceItem()
31 PieSliceItem::~PieSliceItem()
32 {
32 {
33
33
34 }
34 }
35
35
36 QRectF PieSliceItem::boundingRect() const
36 QRectF PieSliceItem::boundingRect() const
37 {
37 {
38 return m_boundingRect;
38 return m_boundingRect;
39 }
39 }
40
40
41 QPainterPath PieSliceItem::shape() const
41 QPainterPath PieSliceItem::shape() const
42 {
42 {
43 // Don't include the label and label arm.
43 // Don't include the label and label arm.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
45 return m_slicePath;
45 return m_slicePath;
46 }
46 }
47
47
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setClipRect(parentItem()->boundingRect());
50 painter->setClipRect(parentItem()->boundingRect());
51
51
52 painter->save();
52 painter->save();
53 painter->setPen(m_data.m_slicePen);
53 painter->setPen(m_data.m_slicePen);
54 painter->setBrush(m_data.m_sliceBrush);
54 painter->setBrush(m_data.m_sliceBrush);
55 painter->drawPath(m_slicePath);
55 painter->drawPath(m_slicePath);
56 painter->restore();
56 painter->restore();
57
57
58 if (m_data.m_labelVisible) {
58 if (m_data.m_isLabelVisible) {
59 painter->save();
59 painter->save();
60 painter->setPen(m_data.m_labelArmPen);
60 painter->setPen(m_data.m_labelArmPen);
61 painter->drawPath(m_labelArmPath);
61 painter->drawPath(m_labelArmPath);
62 painter->restore();
62 painter->restore();
63
63
64 painter->setFont(m_data.m_labelFont);
64 painter->setFont(m_data.m_labelFont);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
66 }
66 }
67 }
67 }
68
68
69 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
69 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
70 {
70 {
71 emit hoverEnter();
71 emit hoverEnter();
72 }
72 }
73
73
74 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
74 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
75 {
75 {
76 emit hoverLeave();
76 emit hoverLeave();
77 }
77 }
78
78
79 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
79 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
80 {
80 {
81 emit clicked();
81 emit clicked();
82 }
82 }
83
83
84 void PieSliceItem::setSliceData(PieSliceData sliceData)
84 void PieSliceItem::setSliceData(PieSliceData sliceData)
85 {
85 {
86 m_data = sliceData;
86 m_data = sliceData;
87 }
87 }
88
88
89 void PieSliceItem::updateGeometry()
89 void PieSliceItem::updateGeometry()
90 {
90 {
91 if (m_data.m_radius <= 0)
91 if (m_data.m_radius <= 0)
92 return;
92 return;
93
93
94 prepareGeometryChange();
94 prepareGeometryChange();
95
95
96 // update slice path
96 // update slice path
97 qreal centerAngle;
97 qreal centerAngle;
98 QPointF armStart;
98 QPointF armStart;
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
100
100
101 // update text rect
101 // update text rect
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
103
103
104 // update label arm path
104 // update label arm path
105 QPointF labelTextStart;
105 QPointF labelTextStart;
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
107
107
108 // update text position
108 // update text position
109 m_labelTextRect.moveBottomLeft(labelTextStart);
109 m_labelTextRect.moveBottomLeft(labelTextStart);
110
110
111 // update bounding rect
111 // update bounding rect
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
113 }
113 }
114
114
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
116 {
116 {
117 if (slice->isExploded()) {
117 if (slice->isExploded()) {
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
119 qreal len = radius * slice->explodeDistanceFactor();
119 qreal len = radius * slice->explodeDistanceFactor();
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
122 point += QPointF(dx, dy);
122 point += QPointF(dx, dy);
123 }
123 }
124 return point;
124 return point;
125 }
125 }
126
126
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
128 {
128 {
129 // calculate center angle
129 // calculate center angle
130 *centerAngle = startAngle + (angleSpan/2);
130 *centerAngle = startAngle + (angleSpan/2);
131
131
132 // calculate slice rectangle
132 // calculate slice rectangle
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
134
134
135 // slice path
135 // slice path
136 // TODO: draw the shape so that it might have a hole in the center
136 // TODO: draw the shape so that it might have a hole in the center
137 QPainterPath path;
137 QPainterPath path;
138 path.moveTo(rect.center());
138 path.moveTo(rect.center());
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
140 path.closeSubpath();
140 path.closeSubpath();
141
141
142 // calculate label arm start point
142 // calculate label arm start point
143 *armStart = center;
143 *armStart = center;
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
145
145
146 return path;
146 return path;
147 }
147 }
148
148
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
150 {
150 {
151 qreal dx = qSin(angle*(PI/180)) * length;
151 qreal dx = qSin(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
153 QPointF parm1 = start + QPointF(dx, dy);
153 QPointF parm1 = start + QPointF(dx, dy);
154
154
155 QPointF parm2 = parm1;
155 QPointF parm2 = parm1;
156 if (angle < 180) { // arm swings the other way on the left side
156 if (angle < 180) { // arm swings the other way on the left side
157 parm2 += QPointF(textWidth, 0);
157 parm2 += QPointF(textWidth, 0);
158 *textStart = parm1;
158 *textStart = parm1;
159 }
159 }
160 else {
160 else {
161 parm2 += QPointF(-textWidth,0);
161 parm2 += QPointF(-textWidth,0);
162 *textStart = parm2;
162 *textStart = parm2;
163 }
163 }
164
164
165 // elevate the text position a bit so that it does not hit the line
165 // elevate the text position a bit so that it does not hit the line
166 *textStart += QPointF(0, -5);
166 *textStart += QPointF(0, -5);
167
167
168 QPainterPath path;
168 QPainterPath path;
169 path.moveTo(start);
169 path.moveTo(start);
170 path.lineTo(parm1);
170 path.lineTo(parm1);
171 path.lineTo(parm2);
171 path.lineTo(parm2);
172
172
173 return path;
173 return path;
174 }
174 }
175
175
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
177 {
177 {
178 QFontMetricsF fm(font);
178 QFontMetricsF fm(font);
179 return fm.boundingRect(text);
179 return fm.boundingRect(text);
180 }
180 }
181
181
182 #include "moc_piesliceitem_p.cpp"
182 #include "moc_piesliceitem_p.cpp"
183
183
184 QTCOMMERCIALCHART_END_NAMESPACE
184 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,409 +1,413
1 #include "qpieslice.h"
1 #include "qpieslice.h"
2 #include "qpiesliceprivate_p.h"
2 #include "qpiesliceprivate_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieseriesprivate_p.h"
4 #include "qpieseriesprivate_p.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 /*!
8 /*!
9 \class QPieSlice
9 \class QPieSlice
10 \brief Defines a slice in pie series.
10 \brief Defines a slice in pie series.
11
11
12 Holds all the data of a single slice in a QPieSeries and provides the means
12 Holds all the data of a single slice in a QPieSeries and provides the means
13 to modify slice data and customize the visual appearance of the slice.
13 to modify slice data and customize the visual appearance of the slice.
14
14
15 It also provides the means to customize user interaction with the slice by
15 It also provides the means to customize user interaction with the slice by
16 providing signals for clicking and hover events.
16 providing signals for clicking and hover events.
17 */
17 */
18
18
19 /*!
19 /*!
20 \property QPieSlice::label
20 \property QPieSlice::label
21
21
22 Label of the slice.
22 Label of the slice.
23 */
23 */
24
24
25 /*!
25 /*!
26 \property QPieSlice::value
26 \property QPieSlice::value
27
27
28 Value of the slice.
28 Value of the slice.
29 */
29 */
30
30
31 /*!
31 /*!
32 Constructs an empty slice with a \a parent.
32 Constructs an empty slice with a \a parent.
33
33
34 Note that QPieSeries takes ownership of the slice when it is set/added.
34 Note that QPieSeries takes ownership of the slice when it is set/added.
35
35
36 \sa QPieSeries::replace(), QPieSeries::add()
36 \sa QPieSeries::replace(), QPieSeries::add()
37 */
37 */
38 QPieSlice::QPieSlice(QObject *parent)
38 QPieSlice::QPieSlice(QObject *parent)
39 :QObject(parent),
39 :QObject(parent),
40 d_ptr(new QPieSlicePrivate(this))
40 d_ptr(new QPieSlicePrivate(this))
41 {
41 {
42
42
43 }
43 }
44
44
45 /*!
45 /*!
46 Constructs an empty slice with given \a value, \a label and a \a parent.
46 Constructs an empty slice with given \a value, \a label and a \a parent.
47 Note that QPieSeries takes ownership of the slice when it is set/added.
47 Note that QPieSeries takes ownership of the slice when it is set/added.
48 \sa QPieSeries::replace(), QPieSeries::add()
48 \sa QPieSeries::replace(), QPieSeries::add()
49 */
49 */
50 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
50 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
51 :QObject(parent),
51 :QObject(parent),
52 d_ptr(new QPieSlicePrivate(this))
52 d_ptr(new QPieSlicePrivate(this))
53 {
53 {
54 Q_D(QPieSlice);
54 Q_D(QPieSlice);
55 d->m_data.m_value = value;
55 d->m_data.m_value = value;
56 d->m_data.m_labelText = label;
56 d->m_data.m_labelText = label;
57 }
57 }
58
58
59 /*!
59 /*!
60 Destroys the slice.
60 Destroys the slice.
61 User should not delete the slice if it has been added to the series.
61 User should not delete the slice if it has been added to the series.
62 */
62 */
63 QPieSlice::~QPieSlice()
63 QPieSlice::~QPieSlice()
64 {
64 {
65 delete d_ptr;
65 delete d_ptr;
66 }
66 }
67
67
68 /*!
68 /*!
69 Gets the value of the slice.
69 Gets the value of the slice.
70 Note that all values in the series
70 Note that all values in the series
71 \sa setValue()
71 \sa setValue()
72 */
72 */
73 qreal QPieSlice::value() const
73 qreal QPieSlice::value() const
74 {
74 {
75 Q_D(const QPieSlice);
75 Q_D(const QPieSlice);
76 return d->m_data.m_value;
76 return d->m_data.m_value;
77 }
77 }
78
78
79 /*!
79 /*!
80 Gets the label of the slice.
80 Gets the label of the slice.
81 \sa setLabel()
81 \sa setLabel()
82 */
82 */
83 QString QPieSlice::label() const
83 QString QPieSlice::label() const
84 {
84 {
85 Q_D(const QPieSlice);
85 Q_D(const QPieSlice);
86 return d->m_data.m_labelText;
86 return d->m_data.m_labelText;
87 }
87 }
88
88
89 /*!
89 /*!
90 Returns true if label is set as visible.
90 Returns true if label is set as visible.
91 \sa setLabelVisible()
91 \sa setLabelVisible()
92 */
92 */
93 bool QPieSlice::isLabelVisible() const
93 bool QPieSlice::isLabelVisible() const
94 {
94 {
95 Q_D(const QPieSlice);
95 Q_D(const QPieSlice);
96 return d->m_data.m_labelVisible;
96 return d->m_data.m_isLabelVisible;
97 }
97 }
98
98
99 /*!
99 /*!
100 Returns true if slice is exloded from the pie.
100 Returns true if slice is exloded from the pie.
101 \sa setExploded(), setExplodeDistanceFactor()
101 \sa setExploded(), setExplodeDistanceFactor()
102 */
102 */
103 bool QPieSlice::isExploded() const
103 bool QPieSlice::isExploded() const
104 {
104 {
105 Q_D(const QPieSlice);
105 Q_D(const QPieSlice);
106 return d->m_data.m_isExploded;
106 return d->m_data.m_isExploded;
107 }
107 }
108
108
109 /*!
109 /*!
110 Returns the explode distance factor.
110 Returns the explode distance factor.
111
111
112 The factor is relative to pie radius. For example:
112 The factor is relative to pie radius. For example:
113 1.0 means the distance is the same as the radius.
113 1.0 means the distance is the same as the radius.
114 0.5 means the distance is half of the radius.
114 0.5 means the distance is half of the radius.
115
115
116 Default value is 0.15.
116 Default value is 0.15.
117
117
118 \sa setExplodeDistanceFactor()
118 \sa setExplodeDistanceFactor()
119 */
119 */
120 qreal QPieSlice::explodeDistanceFactor() const
120 qreal QPieSlice::explodeDistanceFactor() const
121 {
121 {
122 Q_D(const QPieSlice);
122 Q_D(const QPieSlice);
123 return d->m_data.m_explodeDistanceFactor;
123 return d->m_data.m_explodeDistanceFactor;
124 }
124 }
125
125
126 /*!
126 /*!
127 Returns the percentage of this slice compared to all slices in the same series.
127 Returns the percentage of this slice compared to all slices in the same series.
128 The returned value ranges from 0 to 1.0.
128 The returned value ranges from 0 to 1.0.
129
129
130 Updated internally after the slice is added to the series.
130 Updated internally after the slice is added to the series.
131 */
131 */
132 qreal QPieSlice::percentage() const
132 qreal QPieSlice::percentage() const
133 {
133 {
134 Q_D(const QPieSlice);
134 Q_D(const QPieSlice);
135 return d->m_data.m_percentage;
135 return d->m_data.m_percentage;
136 }
136 }
137
137
138 /*!
138 /*!
139 Returns the starting angle of this slice in the series it belongs to.
139 Returns the starting angle of this slice in the series it belongs to.
140
140
141 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
141 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
142
142
143 Updated internally after the slice is added to the series.
143 Updated internally after the slice is added to the series.
144 */
144 */
145 qreal QPieSlice::startAngle() const
145 qreal QPieSlice::startAngle() const
146 {
146 {
147 Q_D(const QPieSlice);
147 Q_D(const QPieSlice);
148 return d->m_data.m_startAngle;
148 return d->m_data.m_startAngle;
149 }
149 }
150
150
151 /*!
151 /*!
152 Returns the end angle of this slice in the series it belongs to.
152 Returns the end angle of this slice in the series it belongs to.
153
153
154 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
154 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
155
155
156 Updated internally after the slice is added to the series.
156 Updated internally after the slice is added to the series.
157 */
157 */
158 qreal QPieSlice::endAngle() const
158 qreal QPieSlice::endAngle() const
159 {
159 {
160 Q_D(const QPieSlice);
160 Q_D(const QPieSlice);
161 return d->m_data.m_startAngle + d->m_data.m_angleSpan;
161 return d->m_data.m_startAngle + d->m_data.m_angleSpan;
162 }
162 }
163
163
164 /*!
164 /*!
165 Returns the pen used to draw this slice.
165 Returns the pen used to draw this slice.
166 \sa setSlicePen()
166 \sa setSlicePen()
167 */
167 */
168 QPen QPieSlice::slicePen() const
168 QPen QPieSlice::slicePen() const
169 {
169 {
170 Q_D(const QPieSlice);
170 Q_D(const QPieSlice);
171 return d->m_data.m_slicePen;
171 return d->m_data.m_slicePen;
172 }
172 }
173
173
174 /*!
174 /*!
175 Returns the brush used to draw this slice.
175 Returns the brush used to draw this slice.
176 \sa setSliceBrush()
176 \sa setSliceBrush()
177 */
177 */
178 QBrush QPieSlice::sliceBrush() const
178 QBrush QPieSlice::sliceBrush() const
179 {
179 {
180 Q_D(const QPieSlice);
180 Q_D(const QPieSlice);
181 return d->m_data.m_sliceBrush;
181 return d->m_data.m_sliceBrush;
182 }
182 }
183
183
184 /*!
184 /*!
185 Returns the pen used to draw label arm in this slice.
185 Returns the pen used to draw label arm in this slice.
186 \sa setLabelArmPen()
186 \sa setLabelArmPen()
187 */
187 */
188 QPen QPieSlice::labelArmPen() const
188 QPen QPieSlice::labelArmPen() const
189 {
189 {
190 Q_D(const QPieSlice);
190 Q_D(const QPieSlice);
191 return d->m_data.m_labelArmPen;
191 return d->m_data.m_labelArmPen;
192 }
192 }
193
193
194 /*!
194 /*!
195 Returns the font used to draw label in this slice.
195 Returns the font used to draw label in this slice.
196 \sa setLabelFont()
196 \sa setLabelFont()
197 */
197 */
198 QFont QPieSlice::labelFont() const
198 QFont QPieSlice::labelFont() const
199 {
199 {
200 Q_D(const QPieSlice);
200 Q_D(const QPieSlice);
201 return d->m_data.m_labelFont;
201 return d->m_data.m_labelFont;
202 }
202 }
203
203
204 /*!
204 /*!
205 Gets the label arm lenght factor.
205 Gets the label arm length factor.
206
206
207 The factor is relative to pie radius. For example:
207 The factor is relative to pie radius. For example:
208 1.0 means the length is the same as the radius.
208 1.0 means the length is the same as the radius.
209 0.5 means the length is half of the radius.
209 0.5 means the length is half of the radius.
210
210
211 Default value is 0.15
211 Default value is 0.15
212
212
213 \sa setLabelArmLengthFactor()
213 \sa setLabelArmLengthFactor()
214 */
214 */
215 qreal QPieSlice::labelArmLengthFactor() const
215 qreal QPieSlice::labelArmLengthFactor() const
216 {
216 {
217 Q_D(const QPieSlice);
217 Q_D(const QPieSlice);
218 return d->m_data.m_labelArmLengthFactor;
218 return d->m_data.m_labelArmLengthFactor;
219 }
219 }
220
220
221 /*!
221 /*!
222 \fn void QPieSlice::clicked()
222 \fn void QPieSlice::clicked()
223
223
224 This signal is emitted when user has clicked the slice.
224 This signal is emitted when user has clicked the slice.
225
225
226 \sa QPieSeries::clicked()
226 \sa QPieSeries::clicked()
227 */
227 */
228
228
229 /*!
229 /*!
230 \fn void QPieSlice::hoverEnter()
230 \fn void QPieSlice::hoverEnter()
231
231
232 This signal is emitted when user has hovered over the slice.
232 This signal is emitted when user has hovered over the slice.
233
233
234 \sa QPieSeries::hoverEnter()
234 \sa QPieSeries::hoverEnter()
235 */
235 */
236
236
237 /*!
237 /*!
238 \fn void QPieSlice::hoverLeave()
238 \fn void QPieSlice::hoverLeave()
239
239
240 This signal is emitted when user has hovered away from the slice.
240 This signal is emitted when user has hovered away from the slice.
241
241
242 \sa QPieSeries::hoverLeave()
242 \sa QPieSeries::hoverLeave()
243 */
243 */
244
244
245 /*!
245 /*!
246 \fn void QPieSlice::changed()
246 \fn void QPieSlice::changed()
247
247
248 This signal emitted when something has changed in the slice.
248 This signal emitted when something has changed in the slice.
249
249
250 \sa QPieSeries::changed()
250 \sa QPieSeries::changed()
251 */
251 */
252
252
253 /*!
253 /*!
254 Sets the \a value of this slice.
254 Sets the \a value of this slice.
255 \sa value()
255 \sa value()
256 */
256 */
257 void QPieSlice::setValue(qreal value)
257 void QPieSlice::setValue(qreal value)
258 {
258 {
259 Q_D(QPieSlice);
259 Q_D(QPieSlice);
260 if (d->m_data.m_value != value) {
260 if (d->m_data.m_value != value) {
261 d->m_data.m_value = value;
261 d->m_data.m_value = value;
262
262
263 QPieSeries *series = qobject_cast<QPieSeries*>(parent());
263 QPieSeries *series = qobject_cast<QPieSeries*>(parent());
264 if (series)
264 if (series)
265 series->data_ptr()->updateDerivativeData(); // will emit changed()
265 series->data_ptr()->updateDerivativeData(); // will emit changed()
266 else
266 else
267 emit changed();
267 emit changed();
268 }
268 }
269 }
269 }
270
270
271 /*!
271 /*!
272 Sets the \a label of the slice.
272 Sets the \a label of the slice.
273 \sa label()
273 \sa label()
274 */
274 */
275 void QPieSlice::setLabel(QString label)
275 void QPieSlice::setLabel(QString label)
276 {
276 {
277 Q_D(QPieSlice);
277 Q_D(QPieSlice);
278 if (d->m_data.m_labelText != label) {
278 if (d->m_data.m_labelText != label) {
279 d->m_data.m_labelText = label;
279 d->m_data.m_labelText = label;
280 emit changed();
280 emit changed();
281 }
281 }
282 }
282 }
283
283
284 /*!
284 /*!
285 Sets the label \a visible in this slice.
285 Sets the label \a visible in this slice.
286 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
286 \sa isLabelVisible(), QPieSeries::setLabelsVisible()
287 */
287 */
288 void QPieSlice::setLabelVisible(bool visible)
288 void QPieSlice::setLabelVisible(bool visible)
289 {
289 {
290 Q_D(QPieSlice);
290 Q_D(QPieSlice);
291 if (d->m_data.m_labelVisible != visible) {
291 if (d->m_data.m_isLabelVisible != visible) {
292 d->m_data.m_labelVisible = visible;
292 d->m_data.m_isLabelVisible = visible;
293 emit changed();
293 emit changed();
294 }
294 }
295 }
295 }
296
296
297 /*!
297 /*!
298 Sets this slice \a exploded.
298 Sets this slice \a exploded.
299 \sa isExploded(), explodeDistanceFactor()
299 \sa isExploded(), explodeDistanceFactor()
300 */
300 */
301 void QPieSlice::setExploded(bool exploded)
301 void QPieSlice::setExploded(bool exploded)
302 {
302 {
303 Q_D(QPieSlice);
303 Q_D(QPieSlice);
304 if (d->m_data.m_isExploded != exploded) {
304 if (d->m_data.m_isExploded != exploded) {
305 d->m_data.m_isExploded = exploded;
305 d->m_data.m_isExploded = exploded;
306 emit changed();
306 emit changed();
307 }
307 }
308 }
308 }
309
309
310 /*!
310 /*!
311 Sets the explode distance \a factor.
311 Sets the explode distance \a factor.
312
312
313 The factor is relative to pie radius. For example:
313 The factor is relative to pie radius. For example:
314 1.0 means the distance is the same as the radius.
314 1.0 means the distance is the same as the radius.
315 0.5 means the distance is half of the radius.
315 0.5 means the distance is half of the radius.
316
316
317 Default value is 0.15
317 Default value is 0.15
318
318
319 \sa explodeDistanceFactor()
319 \sa explodeDistanceFactor()
320 */
320 */
321 void QPieSlice::setExplodeDistanceFactor(qreal factor)
321 void QPieSlice::setExplodeDistanceFactor(qreal factor)
322 {
322 {
323 Q_D(QPieSlice);
323 Q_D(QPieSlice);
324 if (d->m_data.m_explodeDistanceFactor != factor) {
324 if (d->m_data.m_explodeDistanceFactor != factor) {
325 d->m_data.m_explodeDistanceFactor = factor;
325 d->m_data.m_explodeDistanceFactor = factor;
326 emit changed();
326 emit changed();
327 }
327 }
328 }
328 }
329
329
330 /*!
330 /*!
331 Sets the \a pen used to draw this slice.
331 Sets the \a pen used to draw this slice.
332 Note that applying a theme will override this.
332 Note that applying a theme will override this.
333 \sa slicePen()
333 \sa slicePen()
334 */
334 */
335 void QPieSlice::setSlicePen(const QPen &pen)
335 void QPieSlice::setSlicePen(const QPen &pen)
336 {
336 {
337 Q_D(QPieSlice);
337 Q_D(QPieSlice);
338 if (d->m_data.m_slicePen != pen) {
338 if (d->m_data.m_slicePen != pen) {
339 d->m_data.m_slicePen = pen;
339 d->m_data.m_slicePen = pen;
340 d->m_data.m_slicePen.setThemed(false);
340 emit changed();
341 emit changed();
341 }
342 }
342 }
343 }
343
344
344 /*!
345 /*!
345 Sets the \a brush used to draw this slice.
346 Sets the \a brush used to draw this slice.
346 Note that applying a theme will override this.
347 Note that applying a theme will override this.
347 \sa sliceBrush()
348 \sa sliceBrush()
348 */
349 */
349 void QPieSlice::setSliceBrush(const QBrush &brush)
350 void QPieSlice::setSliceBrush(const QBrush &brush)
350 {
351 {
351 Q_D(QPieSlice);
352 Q_D(QPieSlice);
352 if (d->m_data.m_sliceBrush != brush) {
353 if (d->m_data.m_sliceBrush != brush) {
353 d->m_data.m_sliceBrush = brush;
354 d->m_data.m_sliceBrush = brush;
355 d->m_data.m_sliceBrush.setThemed(false);
354 emit changed();
356 emit changed();
355 }
357 }
356 }
358 }
357
359
358 /*!
360 /*!
359 Sets the \a pen used to draw the label arm in this slice.
361 Sets the \a pen used to draw the label arm in this slice.
360 Note that applying a theme will override this.
362 Note that applying a theme will override this.
361 \sa labelArmPen()
363 \sa labelArmPen()
362 */
364 */
363 void QPieSlice::setLabelArmPen(const QPen &pen)
365 void QPieSlice::setLabelArmPen(const QPen &pen)
364 {
366 {
365 Q_D(QPieSlice);
367 Q_D(QPieSlice);
366 if (d->m_data.m_labelArmPen != pen) {
368 if (d->m_data.m_labelArmPen != pen) {
367 d->m_data.m_labelArmPen = pen;
369 d->m_data.m_labelArmPen = pen;
370 d->m_data.m_labelArmPen.setThemed(false);
368 emit changed();
371 emit changed();
369 }
372 }
370 }
373 }
371
374
372 /*!
375 /*!
373 Sets the \a font used to draw the label in this slice.
376 Sets the \a font used to draw the label in this slice.
374 Note that applying a theme will override this.
377 Note that applying a theme will override this.
375 \sa labelFont()
378 \sa labelFont()
376 */
379 */
377 void QPieSlice::setLabelFont(const QFont &font)
380 void QPieSlice::setLabelFont(const QFont &font)
378 {
381 {
379 Q_D(QPieSlice);
382 Q_D(QPieSlice);
380 if (d->m_data.m_labelFont != font) {
383 if (d->m_data.m_labelFont != font) {
381 d->m_data.m_labelFont = font;
384 d->m_data.m_labelFont = font;
385 d->m_data.m_labelFont.setThemed(false);
382 emit changed();
386 emit changed();
383 }
387 }
384 }
388 }
385
389
386 /*!
390 /*!
387 Sets the label arm lenght \a factor.
391 Sets the label arm length \a factor.
388
392
389 The factor is relative to pie radius. For example:
393 The factor is relative to pie radius. For example:
390 1.0 means the length is the same as the radius.
394 1.0 means the length is the same as the radius.
391 0.5 means the length is half of the radius.
395 0.5 means the length is half of the radius.
392
396
393 Default value is 0.15
397 Default value is 0.15
394
398
395 \sa labelArmLengthFactor()
399 \sa labelArmLengthFactor()
396 */
400 */
397 void QPieSlice::setLabelArmLengthFactor(qreal factor)
401 void QPieSlice::setLabelArmLengthFactor(qreal factor)
398 {
402 {
399 Q_D(QPieSlice);
403 Q_D(QPieSlice);
400 if (d->m_data.m_labelArmLengthFactor != factor) {
404 if (d->m_data.m_labelArmLengthFactor != factor) {
401 d->m_data.m_labelArmLengthFactor = factor;
405 d->m_data.m_labelArmLengthFactor = factor;
402 emit changed();
406 emit changed();
403 }
407 }
404 }
408 }
405
409
406 #include "moc_qpieslice.cpp"
410 #include "moc_qpieslice.cpp"
407 #include "moc_qpiesliceprivate_p.cpp"
411 #include "moc_qpiesliceprivate_p.cpp"
408
412
409 QTCOMMERCIALCHART_END_NAMESPACE
413 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,35 +1,36
1 #ifndef QPIESLICEPRIVATE_P_H
1 #ifndef QPIESLICEPRIVATE_P_H
2 #define QPIESLICEPRIVATE_P_H
2 #define QPIESLICEPRIVATE_P_H
3
3
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "pieslicedata_p.h"
5 #include "pieslicedata_p.h"
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 class QPieSlicePrivate : public QObject
9 class QPieSlicePrivate : public QObject
10 {
10 {
11 Q_OBJECT
11 Q_OBJECT
12 Q_DECLARE_PUBLIC(QPieSlice)
12 Q_DECLARE_PUBLIC(QPieSlice)
13
13
14 public:
14 public:
15 QPieSlicePrivate(QPieSlice *parent)
15 QPieSlicePrivate(QPieSlice *parent)
16 :QObject(parent),
16 :QObject(parent),
17 q_ptr(parent)
17 q_ptr(parent)
18 {
18 {
19 connect(this, SIGNAL(changed()), q_ptr, SIGNAL(changed()));
19 connect(this, SIGNAL(changed()), q_ptr, SIGNAL(changed()));
20 }
20 }
21
21
22 ~QPieSlicePrivate() {}
22 ~QPieSlicePrivate() {}
23
23
24 Q_SIGNALS:
24 Q_SIGNALS:
25 void changed();
25 void changed();
26
26
27 public:
27 public:
28 friend class QPieSeriesPrivate;
28 friend class QPieSeriesPrivate;
29 friend class ChartTheme;
29 QPieSlice * const q_ptr;
30 QPieSlice * const q_ptr;
30 PieSliceData m_data;
31 PieSliceData m_data;
31 };
32 };
32
33
33 QTCOMMERCIALCHART_END_NAMESPACE
34 QTCOMMERCIALCHART_END_NAMESPACE
34
35
35 #endif // QPIESLICEPRIVATE_P_H
36 #endif // QPIESLICEPRIVATE_P_H
General Comments 0
You need to be logged in to leave comments. Login now