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