##// END OF EJS Templates
Add drilldown example for piechart
Jani Honkonen -
r406:d88edf82390f
parent child
Show More
@@ -0,0 +1,126
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
5 #include <qpieseries.h>
6 #include <qpieslice.h>
7 #include <QTime>
8
9 QTCOMMERCIALCHART_USE_NAMESPACE
10
11 class DrilldownSlice : public QPieSlice
12 {
13 Q_OBJECT
14
15 public:
16 DrilldownSlice(qreal value, QString prefix, QSeries* drilldownSeries)
17 :m_drilldownSeries(drilldownSeries),
18 m_prefix(prefix)
19 {
20 setValue(value);
21 setLabelVisible(true);
22 updateLabel();
23 connect(this, SIGNAL(changed()), this, SLOT(updateLabel()));
24 }
25
26 QSeries* drilldownSeries() const { return m_drilldownSeries; }
27
28 public Q_SLOTS:
29 void updateLabel()
30 {
31 QString label = m_prefix;
32 label += " - " + QString::number(this->value())+ "e (";
33 label += QString::number(this->percentage()*100, 'f', 1) + "%)";
34 qDebug() << "updateLabel" << label;
35 setLabel(label);
36 }
37
38 private:
39 QSeries* m_drilldownSeries;
40 QString m_prefix;
41 };
42
43 class DrilldownChart : public QChartView
44 {
45 Q_OBJECT
46 public:
47 explicit DrilldownChart(QWidget *parent = 0):QChartView(parent), m_currentSeries(0) {}
48
49 void changeSeries(QSeries* series)
50 {
51 if (m_currentSeries)
52 removeSeries(m_currentSeries);
53 m_currentSeries = series;
54 addSeries(series);
55 setChartTitle(series->title());
56 }
57
58 public Q_SLOTS:
59 void handleSliceClicked(QPieSlice* slice)
60 {
61 DrilldownSlice* drilldownSlice = static_cast<DrilldownSlice*>(slice);
62 changeSeries(drilldownSlice->drilldownSeries());
63 }
64
65 private:
66 QSeries* m_currentSeries;
67 };
68
69 int main(int argc, char *argv[])
70 {
71 QApplication a(argc, argv);
72
73 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
74
75 QMainWindow window;
76
77 DrilldownChart* drilldownChart = new DrilldownChart(&window);
78 drilldownChart->setRenderHint(QPainter::Antialiasing);
79 drilldownChart->setChartTheme(QChart::ChartThemeVanilla);
80
81 QPieSeries* yearSeries = new QPieSeries(drilldownChart);
82 yearSeries->setTitle("Sales by year - All");
83 yearSeries->setHoverHighlighting();
84
85 QList<QString> months;
86 months << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
87
88 int max = 1000;
89
90 QPieSeries* monthSeriesJane = new QPieSeries(drilldownChart);
91 monthSeriesJane->setTitle("Sales by month - Jane");
92 monthSeriesJane->setHoverHighlighting();
93 foreach (QString month, months)
94 *monthSeriesJane << new DrilldownSlice(qrand() % max, month, yearSeries);
95
96 QPieSeries* monthSeriesJohn = new QPieSeries(drilldownChart);
97 monthSeriesJohn->setTitle("Sales by month - John");
98 monthSeriesJohn->setHoverHighlighting();
99 foreach (QString month, months)
100 *monthSeriesJohn << new DrilldownSlice(qrand() % max, month, yearSeries);
101
102 QPieSeries* monthSeriesAxel = new QPieSeries(drilldownChart);
103 monthSeriesAxel->setTitle("Sales by month - Axel");
104 monthSeriesAxel->setHoverHighlighting();
105 foreach (QString month, months)
106 *monthSeriesAxel << new DrilldownSlice(qrand() % max, month, yearSeries);
107
108 *yearSeries << new DrilldownSlice(monthSeriesJane->total(), "Jane", monthSeriesJane);
109 *yearSeries << new DrilldownSlice(monthSeriesJohn->total(), "John", monthSeriesJohn);
110 *yearSeries << new DrilldownSlice(monthSeriesAxel->total(), "Axel", monthSeriesAxel);
111
112 QObject::connect(monthSeriesJane, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
113 QObject::connect(monthSeriesJohn, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
114 QObject::connect(monthSeriesAxel, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
115 QObject::connect(yearSeries, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
116
117 drilldownChart->changeSeries(yearSeries);
118
119 window.setCentralWidget(drilldownChart);
120 window.resize(600, 600);
121 window.show();
122
123 return a.exec();
124 }
125
126 #include "main.moc"
@@ -0,0 +1,9
1 !include( ../example.pri ) {
2 error( "Couldn't find the example.pri file!" )
3 }
4 TARGET = piechartdrilldown
5 SOURCES += main.cpp
6 HEADERS +=
7
8
9 MOC_DIR = $$PWD/moc
@@ -1,16 +1,17
1 TEMPLATE = subdirs
1 TEMPLATE = subdirs
2 SUBDIRS += linechart \
2 SUBDIRS += linechart \
3 zoomlinechart \
3 zoomlinechart \
4 colorlinechart \
4 colorlinechart \
5 barchart \
5 barchart \
6 stackedbarchart \
6 stackedbarchart \
7 percentbarchart \
7 percentbarchart \
8 scatter \
8 scatter \
9 piechart \
9 piechart \
10 piechartdrilldown \
10 dynamiclinechart \
11 dynamiclinechart \
11 axischart \
12 axischart \
12 multichart \
13 multichart \
13 gdpbarchart \
14 gdpbarchart \
14 presenterchart \
15 presenterchart \
15 chartview \
16 chartview \
16 scatterinteractions
17 scatterinteractions
@@ -1,516 +1,530
1 #include "qpieseries.h"
1 #include "qpieseries.h"
2 #include "qpieslice.h"
2 #include "qpieslice.h"
3 #include <QDebug>
3 #include <QDebug>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7
7
8 /*!
8 /*!
9 \class QPieSeries::ChangeSet
9 \class QPieSeries::ChangeSet
10 \brief Defines the changes in the series.
10 \brief Defines the changes in the series.
11
11
12 Contains the changes that have occurred in the series. Lists of added, changed and removed slices.
12 Contains the changes that have occurred in the series. Lists of added, changed and removed slices.
13
13
14 \sa QPieSeries::changed()
14 \sa QPieSeries::changed()
15 */
15 */
16
16
17 /*!
17 /*!
18 \internal
18 \internal
19 */
19 */
20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
21 {
21 {
22 if (!m_added.contains(slice))
22 if (!m_added.contains(slice))
23 m_added << slice;
23 m_added << slice;
24 }
24 }
25
25
26 /*!
26 /*!
27 \internal
27 \internal
28 */
28 */
29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
30 {
30 {
31 foreach (QPieSlice* s, slices)
31 foreach (QPieSlice* s, slices)
32 appendAdded(s);
32 appendAdded(s);
33 }
33 }
34
34
35 /*!
35 /*!
36 \internal
36 \internal
37 */
37 */
38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
39 {
39 {
40 if (!m_changed.contains(slice))
40 if (!m_changed.contains(slice))
41 m_changed << slice;
41 m_changed << slice;
42 }
42 }
43
43
44 /*!
44 /*!
45 \internal
45 \internal
46 */
46 */
47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
48 {
48 {
49 if (!m_removed.contains(slice))
49 if (!m_removed.contains(slice))
50 m_removed << slice;
50 m_removed << slice;
51 }
51 }
52
52
53 /*!
53 /*!
54 Returns a list of slices that have been added to the series.
54 Returns a list of slices that have been added to the series.
55 \sa QPieSeries::changed()
55 \sa QPieSeries::changed()
56 */
56 */
57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
58 {
58 {
59 return m_added;
59 return m_added;
60 }
60 }
61
61
62 /*!
62 /*!
63 Returns a list of slices that have been changed in the series.
63 Returns a list of slices that have been changed in the series.
64 \sa QPieSeries::changed()
64 \sa QPieSeries::changed()
65 */
65 */
66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
67 {
67 {
68 return m_changed;
68 return m_changed;
69 }
69 }
70
70
71 /*!
71 /*!
72 Returns a list of slices that have been removed from the series.
72 Returns a list of slices that have been removed from the series.
73 \sa QPieSeries::changed()
73 \sa QPieSeries::changed()
74 */
74 */
75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
76 {
76 {
77 return m_removed;
77 return m_removed;
78 }
78 }
79
79
80
80
81 /*!
81 /*!
82 Returns true if there are no added/changed or removed slices in the change set.
82 Returns true if there are no added/changed or removed slices in the change set.
83 */
83 */
84 bool QPieSeries::ChangeSet::isEmpty() const
84 bool QPieSeries::ChangeSet::isEmpty() const
85 {
85 {
86 if (m_added.count() || m_changed.count() || m_removed.count())
86 if (m_added.count() || m_changed.count() || m_removed.count())
87 return false;
87 return false;
88 return true;
88 return true;
89 }
89 }
90
90
91 /*!
91 /*!
92 \enum QPieSeries::PiePosition
92 \enum QPieSeries::PiePosition
93
93
94 This enum describes pie position within its bounding rectangle
94 This enum describes pie position within its bounding rectangle
95
95
96 \value PiePositionMaximized
96 \value PiePositionMaximized
97 \value PiePositionTopLeft
97 \value PiePositionTopLeft
98 \value PiePositionTopRight
98 \value PiePositionTopRight
99 \value PiePositionBottomLeft
99 \value PiePositionBottomLeft
100 \value PiePositionBottomRight
100 \value PiePositionBottomRight
101 */
101 */
102
102
103 /*!
103 /*!
104 \class QPieSeries
104 \class QPieSeries
105 \brief Pie series API for QtCommercial Charts
105 \brief Pie series API for QtCommercial Charts
106
106
107 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
107 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
108 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
108 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
109 The actual slice size is determined by that relative value.
109 The actual slice size is determined by that relative value.
110
110
111 By default the pie is defined as a full pie but it can be a partial pie.
111 By default the pie is defined as a full pie but it can be a partial pie.
112 This can be done by setting a starting angle and angle span to the series.
112 This can be done by setting a starting angle and angle span to the series.
113
113
114 To help with the most common user interaction scenarions there some convenience functions.
114 To help with the most common user interaction scenarions there some convenience functions.
115 Like exploding a slice when clicked and higlighting when user hovers over a slice.
115 Like exploding a slice when clicked and higlighting when user hovers over a slice.
116 */
116 */
117
117
118 /*!
118 /*!
119 Constructs a series object which is a child of \a parent.
119 Constructs a series object which is a child of \a parent.
120 */
120 */
121 QPieSeries::QPieSeries(QObject *parent) :
121 QPieSeries::QPieSeries(QObject *parent) :
122 QSeries(parent),
122 QSeries(parent),
123 m_sizeFactor(1.0),
123 m_sizeFactor(1.0),
124 m_position(PiePositionMaximized),
124 m_position(PiePositionMaximized),
125 m_pieStartAngle(0),
125 m_pieStartAngle(0),
126 m_pieAngleSpan(360)
126 m_pieAngleSpan(360)
127 {
127 {
128
128
129 }
129 }
130
130
131 /*!
131 /*!
132 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
132 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
133 */
133 */
134 QPieSeries::~QPieSeries()
134 QPieSeries::~QPieSeries()
135 {
135 {
136
136
137 }
137 }
138
138
139 /*!
139 /*!
140 Returns QChartSeries::SeriesTypePie.
140 Returns QChartSeries::SeriesTypePie.
141 */
141 */
142 QSeries::QSeriesType QPieSeries::type() const
142 QSeries::QSeriesType QPieSeries::type() const
143 {
143 {
144 return QSeries::SeriesTypePie;
144 return QSeries::SeriesTypePie;
145 }
145 }
146
146
147 /*!
147 /*!
148 Sets an array of \a slices to the series replacing the existing slices.
148 Sets an array of \a slices to the series replacing the existing slices.
149 Slice ownership is passed to the series.
149 Slice ownership is passed to the series.
150 */
150 */
151 void QPieSeries::replace(QList<QPieSlice*> slices)
151 void QPieSeries::replace(QList<QPieSlice*> slices)
152 {
152 {
153 clear();
153 clear();
154 add(slices);
154 add(slices);
155 }
155 }
156
156
157 /*!
157 /*!
158 Adds an array of \a slices to the series.
158 Adds an array of \a slices to the series.
159 Slice ownership is passed to the series.
159 Slice ownership is passed to the series.
160 */
160 */
161 void QPieSeries::add(QList<QPieSlice*> slices)
161 void QPieSeries::add(QList<QPieSlice*> slices)
162 {
162 {
163 ChangeSet changeSet;
163 ChangeSet changeSet;
164 foreach (QPieSlice* s, slices) {
164 foreach (QPieSlice* s, slices) {
165 s->setParent(this);
165 s->setParent(this);
166 m_slices << s;
166 m_slices << s;
167 changeSet.appendAdded(s);
167 changeSet.appendAdded(s);
168 }
168 }
169
169
170 updateDerivativeData();
170 updateDerivativeData();
171
171
172 foreach (QPieSlice* s, slices) {
172 foreach (QPieSlice* s, slices) {
173 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
173 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
174 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
174 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
175 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
175 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
176 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
176 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
177 }
177 }
178
178
179 emit changed(changeSet);
179 emit changed(changeSet);
180 }
180 }
181
181
182 /*!
182 /*!
183 Adds a single \a slice to the series.
183 Adds a single \a slice to the series.
184 Slice ownership is passed to the series.
184 Slice ownership is passed to the series.
185 */
185 */
186 void QPieSeries::add(QPieSlice* slice)
186 void QPieSeries::add(QPieSlice* slice)
187 {
187 {
188 add(QList<QPieSlice*>() << slice);
188 add(QList<QPieSlice*>() << slice);
189 }
189 }
190
190
191 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
192 {
193 add(slice);
194 return *this;
195 }
196
191
197
192 /*!
198 /*!
193 Adds a single slice to the series with give \a value and \a name.
199 Adds a single slice to the series with give \a value and \a name.
194 Slice ownership is passed to the series.
200 Slice ownership is passed to the series.
195 */
201 */
196 QPieSlice* QPieSeries::add(qreal value, QString name)
202 QPieSlice* QPieSeries::add(qreal value, QString name)
197 {
203 {
198 QPieSlice* slice = new QPieSlice(value, name);
204 QPieSlice* slice = new QPieSlice(value, name);
199 add(slice);
205 add(slice);
200 return slice;
206 return slice;
201 }
207 }
202
208
203 /*!
209 /*!
204 Removes a single \a slice from the series and deletes the slice.
210 Removes a single \a slice from the series and deletes the slice.
205
211
206 Do not reference this pointer after this call.
212 Do not reference this pointer after this call.
207 */
213 */
208 void QPieSeries::remove(QPieSlice* slice)
214 void QPieSeries::remove(QPieSlice* slice)
209 {
215 {
210 if (!m_slices.removeOne(slice)) {
216 if (!m_slices.removeOne(slice)) {
211 Q_ASSERT(0); // TODO: how should this be reported?
217 Q_ASSERT(0); // TODO: how should this be reported?
212 return;
218 return;
213 }
219 }
214
220
215 ChangeSet changeSet;
221 ChangeSet changeSet;
216 changeSet.appendRemoved(slice);
222 changeSet.appendRemoved(slice);
217 emit changed(changeSet);
223 emit changed(changeSet);
218
224
219 delete slice;
225 delete slice;
220 slice = NULL;
226 slice = NULL;
221
227
222 updateDerivativeData();
228 updateDerivativeData();
223 }
229 }
224
230
225 /*!
231 /*!
226 Clears all slices from the series.
232 Clears all slices from the series.
227 */
233 */
228 void QPieSeries::clear()
234 void QPieSeries::clear()
229 {
235 {
230 if (m_slices.count() == 0)
236 if (m_slices.count() == 0)
231 return;
237 return;
232
238
233 ChangeSet changeSet;
239 ChangeSet changeSet;
234 foreach (QPieSlice* s, m_slices) {
240 foreach (QPieSlice* s, m_slices) {
235 changeSet.appendRemoved(s);
241 changeSet.appendRemoved(s);
236 m_slices.removeOne(s);
242 m_slices.removeOne(s);
237 delete s;
243 delete s;
238 }
244 }
239 emit changed(changeSet);
245 emit changed(changeSet);
240 updateDerivativeData();
246 updateDerivativeData();
241 }
247 }
242
248
243 /*!
249 /*!
244 Counts the number of the slices in this series.
250 Counts the number of the slices in this series.
245 */
251 */
246 int QPieSeries::count() const
252 int QPieSeries::count() const
247 {
253 {
248 return m_slices.count();
254 return m_slices.count();
249 }
255 }
250
256
251 /*!
257 /*!
252 Returns a list of slices that belong to this series.
258 Returns a list of slices that belong to this series.
253 */
259 */
254 QList<QPieSlice*> QPieSeries::slices() const
260 QList<QPieSlice*> QPieSeries::slices() const
255 {
261 {
256 return m_slices;
262 return m_slices;
257 }
263 }
258
264
259 /*!
265 /*!
260 Sets the size \a factor of the pie. 1.0 is the default value.
266 Sets the size \a factor of the pie. 1.0 is the default value.
261 Note that the pie will not grow beyond its absolute maximum size.
267 Note that the pie will not grow beyond its absolute maximum size.
262 In practice its use is to make the pie appear smaller.
268 In practice its use is to make the pie appear smaller.
263 \sa sizeFactor()
269 \sa sizeFactor()
264 */
270 */
265 void QPieSeries::setSizeFactor(qreal factor)
271 void QPieSeries::setSizeFactor(qreal factor)
266 {
272 {
267 if (factor < 0.0)
273 if (factor < 0.0)
268 return;
274 return;
269
275
270 if (m_sizeFactor != factor) {
276 if (m_sizeFactor != factor) {
271 m_sizeFactor = factor;
277 m_sizeFactor = factor;
272 emit sizeFactorChanged();
278 emit sizeFactorChanged();
273 }
279 }
274 }
280 }
275
281
276 /*!
282 /*!
277 Gets the size factor of the pie.
283 Gets the size factor of the pie.
278 \sa setSizeFactor()
284 \sa setSizeFactor()
279 */
285 */
280 qreal QPieSeries::sizeFactor() const
286 qreal QPieSeries::sizeFactor() const
281 {
287 {
282 return m_sizeFactor;
288 return m_sizeFactor;
283 }
289 }
284
290
285 /*!
291 /*!
286 Sets the \a position of the pie within its bounding rectangle.
292 Sets the \a position of the pie within its bounding rectangle.
287 \sa PiePosition, position()
293 \sa PiePosition, position()
288 */
294 */
289 void QPieSeries::setPosition(PiePosition position)
295 void QPieSeries::setPosition(PiePosition position)
290 {
296 {
291 if (m_position != position) {
297 if (m_position != position) {
292 m_position = position;
298 m_position = position;
293 emit positionChanged();
299 emit positionChanged();
294 }
300 }
295 }
301 }
296
302
297 /*!
303 /*!
298 Gets the position of the pie within its bounding rectangle.
304 Gets the position of the pie within its bounding rectangle.
299 \sa PiePosition, setPosition()
305 \sa PiePosition, setPosition()
300 */
306 */
301 QPieSeries::PiePosition QPieSeries::position() const
307 QPieSeries::PiePosition QPieSeries::position() const
302 {
308 {
303 return m_position;
309 return m_position;
304 }
310 }
305
311
306
312
307 /*!
313 /*!
308 Sets the \a startAngle and \a angleSpan of this series.
314 Sets the \a startAngle and \a angleSpan of this series.
309
315
310 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
316 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
311 */
317 */
312 void QPieSeries::setSpan(qreal startAngle, qreal angleSpan)
318 void QPieSeries::setSpan(qreal startAngle, qreal angleSpan)
313 {
319 {
314 if (startAngle >= 0 && startAngle < 360 &&
320 if (startAngle >= 0 && startAngle < 360 &&
315 angleSpan > 0 && angleSpan <= 360) {
321 angleSpan > 0 && angleSpan <= 360) {
316 m_pieStartAngle = startAngle;
322 m_pieStartAngle = startAngle;
317 m_pieAngleSpan = angleSpan;
323 m_pieAngleSpan = angleSpan;
318 updateDerivativeData();
324 updateDerivativeData();
319 }
325 }
320 }
326 }
321
327
322 /*!
328 /*!
323 Sets the all the slice labels \a visible or invisible.
329 Sets the all the slice labels \a visible or invisible.
324
330
325 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
331 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
326 */
332 */
327 void QPieSeries::setLabelsVisible(bool visible)
333 void QPieSeries::setLabelsVisible(bool visible)
328 {
334 {
329 foreach (QPieSlice* s, m_slices)
335 foreach (QPieSlice* s, m_slices)
330 s->setLabelVisible(visible);
336 s->setLabelVisible(visible);
331 }
337 }
332
338
333 /*!
339 /*!
334 Convenience method for exploding a slice when user clicks the pie. Set \a enable to true to
340 Convenience method for exploding a slice when user clicks the pie. Set \a enable to true to
335 explode slices by clicking.
341 explode slices by clicking.
336
342
337 \sa QPieSlice::isExploded(), QPieSlice::setExploded(), QPieSlice::setExplodeDistance()
343 \sa QPieSlice::isExploded(), QPieSlice::setExploded(), QPieSlice::setExplodeDistance()
338 */
344 */
339 void QPieSeries::setClickExplodes(bool enable)
345 void QPieSeries::setClickExplodes(bool enable)
340 {
346 {
341 if (enable)
347 if (enable)
342 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
348 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
343 else
349 else
344 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
350 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
345 }
351 }
346
352
347 /*!
353 /*!
348 Convenience method for highlighting a slice when user hovers over the slice.
354 Convenience method for highlighting a slice when user hovers over the slice.
349 It changes the slice color to be lighter and shows the label of the slice.
355 It changes the slice color to be lighter and shows the label of the slice.
350 Set \a enable to true to highlight a slice when user hovers on top of it.
356 Set \a enable to true to highlight a slice when user hovers on top of it.
351
352 \sa QPieSlice::isExploded(), QPieSlice::setExploded()
353 */
357 */
354
355 void QPieSeries::setHoverHighlighting(bool enable)
358 void QPieSeries::setHoverHighlighting(bool enable)
356 {
359 {
357 if (enable) {
360 if (enable) {
358 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
361 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
359 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
362 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
360 } else {
363 } else {
361 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
364 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
362 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
365 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
363 }
366 }
364 }
367 }
365
368
366 /*!
369 /*!
370 Returns the sum of all slice values in this series.
371
372 \sa QPieSlice::value(), QPieSlice::setValue()
373 */
374 qreal QPieSeries::total() const
375 {
376 return m_total;
377 }
378
379 /*!
367 \fn void QPieSeries::changed(const QPieSeries::ChangeSet& changeSet)
380 \fn void QPieSeries::changed(const QPieSeries::ChangeSet& changeSet)
368
381
369 This signal emitted when something has changed in the series.
382 This signal emitted when something has changed in the series.
370 The \a changeSet contains the details of which slices have been added, changed or removed.
383 The \a changeSet contains the details of which slices have been added, changed or removed.
371
384
372 \sa QPieSeries::ChangeSet, QPieSlice::changed()
385 \sa QPieSeries::ChangeSet, QPieSlice::changed()
373 */
386 */
374
387
375 /*!
388 /*!
376 \fn void QPieSeries::clicked(QPieSlice* slice)
389 \fn void QPieSeries::clicked(QPieSlice* slice)
377
390
378 This signal is emitted when a \a slice has been clicked.
391 This signal is emitted when a \a slice has been clicked.
379
392
380 \sa QPieSlice::clicked()
393 \sa QPieSlice::clicked()
381 */
394 */
382
395
383 /*!
396 /*!
384 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
397 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
385
398
386 This signal is emitted when user has hovered over a \a slice.
399 This signal is emitted when user has hovered over a \a slice.
387
400
388 \sa QPieSlice::hoverEnter()
401 \sa QPieSlice::hoverEnter()
389 */
402 */
390
403
391 /*!
404 /*!
392 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
405 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
393
406
394 This signal is emitted when user has hovered away from a \a slice.
407 This signal is emitted when user has hovered away from a \a slice.
395
408
396 \sa QPieSlice::hoverLeave()
409 \sa QPieSlice::hoverLeave()
397 */
410 */
398
411
399 /*!
412 /*!
400 \fn void QPieSeries::sizeFactorChanged()
413 \fn void QPieSeries::sizeFactorChanged()
401
414
402 This signal is emitted when size factor has been changed.
415 This signal is emitted when size factor has been changed.
403
416
404 \sa sizeFactor(), setSizeFactor()
417 \sa sizeFactor(), setSizeFactor()
405 */
418 */
406
419
407 /*!
420 /*!
408 \fn void QPieSeries::positionChanged()
421 \fn void QPieSeries::positionChanged()
409
422
410 This signal is emitted when position of the pie has been changed.
423 This signal is emitted when position of the pie has been changed.
411
424
412 \sa position(), setPosition()
425 \sa position(), setPosition()
413 */
426 */
414
427
415 void QPieSeries::sliceChanged()
428 void QPieSeries::sliceChanged()
416 {
429 {
417 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
430 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
418 Q_ASSERT(m_slices.contains(slice));
431 Q_ASSERT(m_slices.contains(slice));
419
432
420 ChangeSet changeSet;
433 ChangeSet changeSet;
421 changeSet.appendChanged(slice);
434 changeSet.appendChanged(slice);
422 emit changed(changeSet);
435 emit changed(changeSet);
423
436
424 updateDerivativeData();
437 updateDerivativeData();
425 }
438 }
426
439
427 void QPieSeries::sliceClicked()
440 void QPieSeries::sliceClicked()
428 {
441 {
429 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
442 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
430 Q_ASSERT(m_slices.contains(slice));
443 Q_ASSERT(m_slices.contains(slice));
431 emit clicked(slice);
444 emit clicked(slice);
432 }
445 }
433
446
434 void QPieSeries::sliceHoverEnter()
447 void QPieSeries::sliceHoverEnter()
435 {
448 {
436 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
449 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
437 Q_ASSERT(m_slices.contains(slice));
450 Q_ASSERT(m_slices.contains(slice));
438 emit hoverEnter(slice);
451 emit hoverEnter(slice);
439 }
452 }
440
453
441 void QPieSeries::sliceHoverLeave()
454 void QPieSeries::sliceHoverLeave()
442 {
455 {
443 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
456 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
444 Q_ASSERT(m_slices.contains(slice));
457 Q_ASSERT(m_slices.contains(slice));
445 emit hoverLeave(slice);
458 emit hoverLeave(slice);
446 }
459 }
447
460
448 void QPieSeries::toggleExploded(QPieSlice* slice)
461 void QPieSeries::toggleExploded(QPieSlice* slice)
449 {
462 {
450 Q_ASSERT(slice);
463 Q_ASSERT(slice);
451 slice->setExploded(!slice->isExploded());
464 slice->setExploded(!slice->isExploded());
452 }
465 }
453
466
454 void QPieSeries::highlightOn(QPieSlice* slice)
467 void QPieSeries::highlightOn(QPieSlice* slice)
455 {
468 {
456 Q_ASSERT(slice);
469 Q_ASSERT(slice);
457 QColor c = slice->brush().color().lighter();
470 QColor c = slice->brush().color().lighter();
458 slice->setBrush(c);
471 slice->setBrush(c);
459 slice->setLabelVisible(true);
460 }
472 }
461
473
462 void QPieSeries::highlightOff(QPieSlice* slice)
474 void QPieSeries::highlightOff(QPieSlice* slice)
463 {
475 {
464 Q_ASSERT(slice);
476 Q_ASSERT(slice);
465 QColor c = slice->brush().color().darker(150);
477 QColor c = slice->brush().color().darker(150);
466 slice->setBrush(c);
478 slice->setBrush(c);
467 slice->setLabelVisible(false);
468 }
479 }
469
480
470 void QPieSeries::updateDerivativeData()
481 void QPieSeries::updateDerivativeData()
471 {
482 {
472 m_total = 0;
483 m_total = 0;
473
484
474 // nothing to do?
485 // nothing to do?
475 if (m_slices.count() == 0)
486 if (m_slices.count() == 0)
476 return;
487 return;
477
488
478 // calculate total
489 // calculate total
479 foreach (QPieSlice* s, m_slices)
490 foreach (QPieSlice* s, m_slices)
480 m_total += s->value();
491 m_total += s->value();
481
492
482 // we must have some values
493 // we must have some values
483 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
494 if (m_total == 0) {
495 qDebug() << "QPieSeries::updateDerivativeData() total == 0";
496 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
497 }
484
498
485 // update slice attributes
499 // update slice attributes
486 qreal sliceAngle = m_pieStartAngle;
500 qreal sliceAngle = m_pieStartAngle;
487 foreach (QPieSlice* s, m_slices) {
501 foreach (QPieSlice* s, m_slices) {
488
502
489 bool changed = false;
503 bool changed = false;
490
504
491 qreal percentage = s->value() / m_total;
505 qreal percentage = s->value() / m_total;
492 if (s->m_percentage != percentage) {
506 if (s->m_percentage != percentage) {
493 s->m_percentage = percentage;
507 s->m_percentage = percentage;
494 changed = true;
508 changed = true;
495 }
509 }
496
510
497 qreal sliceSpan = m_pieAngleSpan * percentage;
511 qreal sliceSpan = m_pieAngleSpan * percentage;
498 if (s->m_angleSpan != sliceSpan) {
512 if (s->m_angleSpan != sliceSpan) {
499 s->m_angleSpan = sliceSpan;
513 s->m_angleSpan = sliceSpan;
500 changed = true;
514 changed = true;
501 }
515 }
502
516
503 if (s->m_startAngle != sliceAngle) {
517 if (s->m_startAngle != sliceAngle) {
504 s->m_startAngle = sliceAngle;
518 s->m_startAngle = sliceAngle;
505 changed = true;
519 changed = true;
506 }
520 }
507 sliceAngle += sliceSpan;
521 sliceAngle += sliceSpan;
508
522
509 if (changed)
523 if (changed)
510 emit s->changed();
524 emit s->changed();
511 }
525 }
512 }
526 }
513
527
514 #include "moc_qpieseries.cpp"
528 #include "moc_qpieseries.cpp"
515
529
516 QTCOMMERCIALCHART_END_NAMESPACE
530 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,129 +1,132
1 #ifndef PIESERIES_H
1 #ifndef PIESERIES_H
2 #define PIESERIES_H
2 #define PIESERIES_H
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QRectF>
6 #include <QRectF>
7 #include <QColor>
7 #include <QColor>
8 #include <QPen>
8 #include <QPen>
9 #include <QBrush>
9 #include <QBrush>
10 #include <QSignalMapper>
10 #include <QSignalMapper>
11
11
12 class QGraphicsObject;
12 class QGraphicsObject;
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 class PiePresenter;
14 class PiePresenter;
15 class PieSlice;
15 class PieSlice;
16 class QPieSlice;
16 class QPieSlice;
17
17
18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
19 {
19 {
20 Q_OBJECT
20 Q_OBJECT
21
21
22 public:
22 public:
23 enum PiePosition {
23 enum PiePosition {
24 PiePositionMaximized = 0,
24 PiePositionMaximized = 0,
25 PiePositionTopLeft,
25 PiePositionTopLeft,
26 PiePositionTopRight,
26 PiePositionTopRight,
27 PiePositionBottomLeft,
27 PiePositionBottomLeft,
28 PiePositionBottomRight
28 PiePositionBottomRight
29 };
29 };
30
30
31 class ChangeSet
31 class ChangeSet
32 {
32 {
33 public:
33 public:
34
34
35 // TODO: these should not really be exposed to the public API
35 // TODO: these should not really be exposed to the public API
36 void appendAdded(QPieSlice* slice);
36 void appendAdded(QPieSlice* slice);
37 void appendAdded(QList<QPieSlice*> slices);
37 void appendAdded(QList<QPieSlice*> slices);
38 void appendChanged(QPieSlice* slice);
38 void appendChanged(QPieSlice* slice);
39 void appendRemoved(QPieSlice* slice);
39 void appendRemoved(QPieSlice* slice);
40
40
41 QList<QPieSlice*> added() const;
41 QList<QPieSlice*> added() const;
42 QList<QPieSlice*> changed() const;
42 QList<QPieSlice*> changed() const;
43 QList<QPieSlice*> removed() const;
43 QList<QPieSlice*> removed() const;
44
44
45 bool isEmpty() const;
45 bool isEmpty() const;
46
46
47 private:
47 private:
48 QList<QPieSlice*> m_added;
48 QList<QPieSlice*> m_added;
49 QList<QPieSlice*> m_changed;
49 QList<QPieSlice*> m_changed;
50 QList<QPieSlice*> m_removed;
50 QList<QPieSlice*> m_removed;
51 };
51 };
52
52
53 public:
53 public:
54 QPieSeries(QObject *parent = 0);
54 QPieSeries(QObject *parent = 0);
55 virtual ~QPieSeries();
55 virtual ~QPieSeries();
56
56
57 public: // from QChartSeries
57 public: // from QChartSeries
58 QSeriesType type() const;
58 QSeriesType type() const;
59
59
60 public:
60 public:
61 void replace(QList<QPieSlice*> slices);
61 void replace(QList<QPieSlice*> slices);
62 void add(QList<QPieSlice*> slices);
62 void add(QList<QPieSlice*> slices);
63 void add(QPieSlice* slice);
63 void add(QPieSlice* slice);
64 QPieSlice* add(qreal value, QString name);
64 QPieSlice* add(qreal value, QString name);
65 QPieSeries& operator << (QPieSlice* slice);
65 void remove(QPieSlice* slice);
66 void remove(QPieSlice* slice);
66 void clear();
67 void clear();
67
68
68 int count() const;
69 int count() const;
69 QList<QPieSlice*> slices() const;
70 QList<QPieSlice*> slices() const;
70
71
71 void setSizeFactor(qreal sizeFactor);
72 void setSizeFactor(qreal sizeFactor);
72 qreal sizeFactor() const;
73 qreal sizeFactor() const;
73 void setPosition(PiePosition position);
74 void setPosition(PiePosition position);
74 PiePosition position() const;
75 PiePosition position() const;
75 void setSpan(qreal startAngle, qreal angleSpan);
76 void setSpan(qreal startAngle, qreal angleSpan);
76
77
77 void setLabelsVisible(bool visible = true);
78 void setLabelsVisible(bool visible = true);
78 void setClickExplodes(bool enable = true);
79 void setClickExplodes(bool enable = true);
79 void setHoverHighlighting(bool enable = true);
80 void setHoverHighlighting(bool enable = true);
80
81
82 qreal total() const;
83
81 // TODO: find slices?
84 // TODO: find slices?
82 // QList<QPieSlice*> findByValue(qreal value);
85 // QList<QPieSlice*> findByValue(qreal value);
83 // ...
86 // ...
84
87
85 // TODO: sorting slices?
88 // TODO: sorting slices?
86 // void sort(QPieSeries::SortByValue|label|??)
89 // void sort(QPieSeries::SortByValue|label|??)
87
90
88 // TODO: general graphics customization
91 // TODO: general graphics customization
89 // setDrawStyle(2d|3d)
92 // setDrawStyle(2d|3d)
90 // setDropShadows(bool)
93 // setDropShadows(bool)
91
94
92 Q_SIGNALS:
95 Q_SIGNALS:
93 void changed(const QPieSeries::ChangeSet& changeSet);
96 void changed(const QPieSeries::ChangeSet& changeSet);
94 void clicked(QPieSlice* slice);
97 void clicked(QPieSlice* slice);
95 void hoverEnter(QPieSlice* slice);
98 void hoverEnter(QPieSlice* slice);
96 void hoverLeave(QPieSlice* slice);
99 void hoverLeave(QPieSlice* slice);
97 void sizeFactorChanged();
100 void sizeFactorChanged();
98 void positionChanged();
101 void positionChanged();
99
102
100 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
103 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
101 void sliceChanged();
104 void sliceChanged();
102 void sliceClicked();
105 void sliceClicked();
103 void sliceHoverEnter();
106 void sliceHoverEnter();
104 void sliceHoverLeave();
107 void sliceHoverLeave();
105 void toggleExploded(QPieSlice* slice);
108 void toggleExploded(QPieSlice* slice);
106 void highlightOn(QPieSlice* slice);
109 void highlightOn(QPieSlice* slice);
107 void highlightOff(QPieSlice* slice);
110 void highlightOff(QPieSlice* slice);
108
111
109 private:
112 private:
110 void updateDerivativeData();
113 void updateDerivativeData();
111
114
112 private:
115 private:
113 Q_DISABLE_COPY(QPieSeries)
116 Q_DISABLE_COPY(QPieSeries)
114
117
115 // TODO: use PIML
118 // TODO: use PIML
116 friend class PiePresenter;
119 friend class PiePresenter;
117 friend class PieSlice;
120 friend class PieSlice;
118
121
119 QList<QPieSlice*> m_slices;
122 QList<QPieSlice*> m_slices;
120 qreal m_sizeFactor;
123 qreal m_sizeFactor;
121 PiePosition m_position;
124 PiePosition m_position;
122 qreal m_total;
125 qreal m_total;
123 qreal m_pieStartAngle;
126 qreal m_pieStartAngle;
124 qreal m_pieAngleSpan;
127 qreal m_pieAngleSpan;
125 };
128 };
126
129
127 QTCOMMERCIALCHART_END_NAMESPACE
130 QTCOMMERCIALCHART_END_NAMESPACE
128
131
129 #endif // PIESERIES_H
132 #endif // PIESERIES_H
General Comments 0
You need to be logged in to leave comments. Login now