##// END OF EJS Templates
Add _p to pie internal headers
Jani Honkonen -
r353:e5ed5bdfafc1
parent child
Show More
@@ -1,283 +1,283
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartdataset_p.h"
4 #include "chartdataset_p.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 //series
6 //series
7 #include "qbarseries.h"
7 #include "qbarseries.h"
8 #include "qstackedbarseries.h"
8 #include "qstackedbarseries.h"
9 #include "qpercentbarseries.h"
9 #include "qpercentbarseries.h"
10 #include "qlineseries.h"
10 #include "qlineseries.h"
11 #include "qpieseries.h"
11 #include "qpieseries.h"
12 #include "qscatterseries.h"
12 #include "qscatterseries.h"
13 //items
13 //items
14 #include "axisitem_p.h"
14 #include "axisitem_p.h"
15 #include "axisanimationitem_p.h"
15 #include "axisanimationitem_p.h"
16 #include "barpresenter.h"
16 #include "barpresenter.h"
17 #include "stackedbarpresenter.h"
17 #include "stackedbarpresenter.h"
18 #include "linechartitem_p.h"
18 #include "linechartitem_p.h"
19 #include "percentbarpresenter.h"
19 #include "percentbarpresenter.h"
20 #include "linechartanimationitem_p.h"
20 #include "linechartanimationitem_p.h"
21 #include "piepresenter.h"
21 #include "piepresenter_p.h"
22 #include "scatterpresenter_p.h"
22 #include "scatterpresenter_p.h"
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
26 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
27 m_chart(chart),
27 m_chart(chart),
28 m_dataset(dataset),
28 m_dataset(dataset),
29 m_chartTheme(0),
29 m_chartTheme(0),
30 m_marginSize(0),
30 m_marginSize(0),
31 m_rect(QRectF(QPoint(0,0),m_chart->size())),
31 m_rect(QRectF(QPoint(0,0),m_chart->size())),
32 m_options(0)
32 m_options(0)
33 {
33 {
34 createConnections();
34 createConnections();
35 setChartTheme(QChart::ChartThemeDefault);
35 setChartTheme(QChart::ChartThemeDefault);
36
36
37 }
37 }
38
38
39 ChartPresenter::~ChartPresenter()
39 ChartPresenter::~ChartPresenter()
40 {
40 {
41 }
41 }
42
42
43 void ChartPresenter::createConnections()
43 void ChartPresenter::createConnections()
44 {
44 {
45 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
45 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
46 QObject::connect(m_dataset,SIGNAL(seriesAdded(QChartSeries*)),this,SLOT(handleSeriesAdded(QChartSeries*)));
46 QObject::connect(m_dataset,SIGNAL(seriesAdded(QChartSeries*)),this,SLOT(handleSeriesAdded(QChartSeries*)));
47 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QChartSeries*)),this,SLOT(handleSeriesRemoved(QChartSeries*)));
47 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QChartSeries*)),this,SLOT(handleSeriesRemoved(QChartSeries*)));
48 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
48 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
49 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
49 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
50 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QChartSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QChartSeries*,const Domain&)));
50 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QChartSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QChartSeries*,const Domain&)));
51 QObject::connect(m_dataset,SIGNAL(axisLabelsChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisLabelsChanged(QChartAxis*,const QStringList&)));
51 QObject::connect(m_dataset,SIGNAL(axisLabelsChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisLabelsChanged(QChartAxis*,const QStringList&)));
52 }
52 }
53
53
54
54
55 QRectF ChartPresenter::geometry() const
55 QRectF ChartPresenter::geometry() const
56 {
56 {
57 return m_rect;
57 return m_rect;
58 }
58 }
59
59
60 void ChartPresenter::handleGeometryChanged()
60 void ChartPresenter::handleGeometryChanged()
61 {
61 {
62 m_rect = QRectF(QPoint(0,0),m_chart->size());
62 m_rect = QRectF(QPoint(0,0),m_chart->size());
63 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
63 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
64 Q_ASSERT(m_rect.isValid());
64 Q_ASSERT(m_rect.isValid());
65 emit geometryChanged(m_rect);
65 emit geometryChanged(m_rect);
66 }
66 }
67
67
68 int ChartPresenter::margin() const
68 int ChartPresenter::margin() const
69 {
69 {
70 return m_marginSize;
70 return m_marginSize;
71 }
71 }
72
72
73 void ChartPresenter::setMargin(int margin)
73 void ChartPresenter::setMargin(int margin)
74 {
74 {
75 m_marginSize = margin;
75 m_marginSize = margin;
76 }
76 }
77
77
78 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
78 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
79 {
79 {
80
80
81 AxisItem* item ;
81 AxisItem* item ;
82
82
83 if(!m_options.testFlag(QChart::GridAxisAnimations))
83 if(!m_options.testFlag(QChart::GridAxisAnimations))
84 {
84 {
85 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
85 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
86 }else{
86 }else{
87 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
87 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
88 }
88 }
89
89
90 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
90 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
91 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
91 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
92
92
93 item->handleAxisUpdate(axis);
93 item->handleAxisUpdate(axis);
94 item->handleGeometryChanged(m_rect);
94 item->handleGeometryChanged(m_rect);
95 m_chartTheme->decorate(axis,item);
95 m_chartTheme->decorate(axis,item);
96 m_axisItems.insert(axis,item);
96 m_axisItems.insert(axis,item);
97 }
97 }
98
98
99 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
99 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
100 {
100 {
101 AxisItem* item = m_axisItems.take(axis);
101 AxisItem* item = m_axisItems.take(axis);
102 Q_ASSERT(item);
102 Q_ASSERT(item);
103 delete item;
103 delete item;
104 }
104 }
105
105
106
106
107 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
107 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
108 {
108 {
109 switch(series->type())
109 switch(series->type())
110 {
110 {
111 case QChartSeries::SeriesTypeLine: {
111 case QChartSeries::SeriesTypeLine: {
112 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
112 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
113 LineChartItem* item;
113 LineChartItem* item;
114 if(m_options.testFlag(QChart::SeriesAnimations)){
114 if(m_options.testFlag(QChart::SeriesAnimations)){
115 item = new LineChartAnimationItem(this,lineSeries,m_chart);
115 item = new LineChartAnimationItem(this,lineSeries,m_chart);
116 }else{
116 }else{
117 item = new LineChartItem(this,lineSeries,m_chart);
117 item = new LineChartItem(this,lineSeries,m_chart);
118 }
118 }
119 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
119 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
121 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
122 m_chartItems.insert(series,item);
122 m_chartItems.insert(series,item);
123 break;
123 break;
124 }
124 }
125
125
126 case QChartSeries::SeriesTypeBar: {
126 case QChartSeries::SeriesTypeBar: {
127 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
127 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
128 BarPresenter* item = new BarPresenter(barSeries,m_chart);
128 BarPresenter* item = new BarPresenter(barSeries,m_chart);
129 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
129 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
130 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
130 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
131 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
131 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
132 m_chartItems.insert(series,item);
132 m_chartItems.insert(series,item);
133 // m_axisXItem->setVisible(false);
133 // m_axisXItem->setVisible(false);
134 break;
134 break;
135 }
135 }
136
136
137 case QChartSeries::SeriesTypeStackedBar: {
137 case QChartSeries::SeriesTypeStackedBar: {
138
138
139 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
139 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
140 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
140 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
141 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
141 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
142 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
142 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
143 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
143 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
144 m_chartItems.insert(series,item);
144 m_chartItems.insert(series,item);
145 break;
145 break;
146 }
146 }
147
147
148 case QChartSeries::SeriesTypePercentBar: {
148 case QChartSeries::SeriesTypePercentBar: {
149
149
150 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
150 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
151 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
151 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
152 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
152 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
153 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
153 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
154 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
154 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
155 m_chartItems.insert(series,item);
155 m_chartItems.insert(series,item);
156 break;
156 break;
157 }
157 }
158 case QChartSeries::SeriesTypeScatter: {
158 case QChartSeries::SeriesTypeScatter: {
159 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
159 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
160 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
160 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
161 QObject::connect(scatterPresenter, SIGNAL(clicked()), scatterSeries, SIGNAL(clicked()));
161 QObject::connect(scatterPresenter, SIGNAL(clicked()), scatterSeries, SIGNAL(clicked()));
162 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
162 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
163 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
163 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
164 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
164 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
165 m_chartItems.insert(scatterSeries, scatterPresenter);
165 m_chartItems.insert(scatterSeries, scatterPresenter);
166 break;
166 break;
167 }
167 }
168 case QChartSeries::SeriesTypePie: {
168 case QChartSeries::SeriesTypePie: {
169 QPieSeries *s = qobject_cast<QPieSeries *>(series);
169 QPieSeries *s = qobject_cast<QPieSeries *>(series);
170 PiePresenter* pie = new PiePresenter(m_chart, s);
170 PiePresenter* pie = new PiePresenter(m_chart, s);
171 m_chartTheme->decorate(pie, s, m_chartItems.count());
171 m_chartTheme->decorate(pie, s, m_chartItems.count());
172 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
172 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
173
173
174 // Hide all from background when there is only piechart
174 // Hide all from background when there is only piechart
175 // TODO: refactor this ugly code... should be one setting for this
175 // TODO: refactor this ugly code... should be one setting for this
176 if (m_chartItems.count() == 0) {
176 if (m_chartItems.count() == 0) {
177 m_chart->axisX()->setAxisVisible(false);
177 m_chart->axisX()->setAxisVisible(false);
178 m_chart->axisY()->setAxisVisible(false);
178 m_chart->axisY()->setAxisVisible(false);
179 m_chart->axisX()->setGridVisible(false);
179 m_chart->axisX()->setGridVisible(false);
180 m_chart->axisY()->setGridVisible(false);
180 m_chart->axisY()->setGridVisible(false);
181 m_chart->axisX()->setLabelsVisible(false);
181 m_chart->axisX()->setLabelsVisible(false);
182 m_chart->axisY()->setLabelsVisible(false);
182 m_chart->axisY()->setLabelsVisible(false);
183 m_chart->axisX()->setShadesVisible(false);
183 m_chart->axisX()->setShadesVisible(false);
184 m_chart->axisY()->setShadesVisible(false);
184 m_chart->axisY()->setShadesVisible(false);
185 m_chart->setChartBackgroundBrush(Qt::transparent);
185 m_chart->setChartBackgroundBrush(Qt::transparent);
186 }
186 }
187
187
188 m_chartItems.insert(series, pie);
188 m_chartItems.insert(series, pie);
189 break;
189 break;
190 }
190 }
191 default: {
191 default: {
192 qDebug()<< "Series type" << series->type() << "not implemented.";
192 qDebug()<< "Series type" << series->type() << "not implemented.";
193 break;
193 break;
194 }
194 }
195 }
195 }
196
196
197 if(m_rect.isValid()) emit geometryChanged(m_rect);
197 if(m_rect.isValid()) emit geometryChanged(m_rect);
198 }
198 }
199
199
200 void ChartPresenter::handleSeriesRemoved(QChartSeries* series)
200 void ChartPresenter::handleSeriesRemoved(QChartSeries* series)
201 {
201 {
202 ChartItem* item = m_chartItems.take(series);
202 ChartItem* item = m_chartItems.take(series);
203 delete item;
203 delete item;
204 }
204 }
205
205
206 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
206 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
207 {
207 {
208 //TODO:
208 //TODO:
209 }
209 }
210
210
211 void ChartPresenter::handleSeriesDomainChanged(QChartSeries* series, const Domain& domain)
211 void ChartPresenter::handleSeriesDomainChanged(QChartSeries* series, const Domain& domain)
212 {
212 {
213 m_chartItems.value(series)->handleDomainChanged(domain);
213 m_chartItems.value(series)->handleDomainChanged(domain);
214 }
214 }
215
215
216 void ChartPresenter::handleAxisLabelsChanged(QChartAxis* axis,const QStringList& labels)
216 void ChartPresenter::handleAxisLabelsChanged(QChartAxis* axis,const QStringList& labels)
217 {
217 {
218 m_axisItems.value(axis)->handleLabelsChanged(axis,labels);
218 m_axisItems.value(axis)->handleLabelsChanged(axis,labels);
219 }
219 }
220
220
221 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
221 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
222 {
222 {
223 delete m_chartTheme;
223 delete m_chartTheme;
224
224
225 m_chartTheme = ChartTheme::createTheme(theme);
225 m_chartTheme = ChartTheme::createTheme(theme);
226
226
227 m_chartTheme->decorate(m_chart);
227 m_chartTheme->decorate(m_chart);
228 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
228 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
229
229
230 int index=0;
230 int index=0;
231 while (i.hasNext()) {
231 while (i.hasNext()) {
232 i.next();
232 i.next();
233 m_chartTheme->decorate(i.value(),i.key(),index);
233 m_chartTheme->decorate(i.value(),i.key(),index);
234 index++;
234 index++;
235 }
235 }
236
236
237 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
237 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
238 while (j.hasNext()) {
238 while (j.hasNext()) {
239 j.next();
239 j.next();
240 m_chartTheme->decorate(j.key(),j.value());
240 m_chartTheme->decorate(j.key(),j.value());
241 }
241 }
242 }
242 }
243
243
244 QChart::ChartTheme ChartPresenter::chartTheme()
244 QChart::ChartTheme ChartPresenter::chartTheme()
245 {
245 {
246 return m_chartTheme->id();
246 return m_chartTheme->id();
247 }
247 }
248
248
249 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
249 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
250 {
250 {
251 if(m_options!=options) {
251 if(m_options!=options) {
252
252
253 m_options=options;
253 m_options=options;
254
254
255 //recreate elements
255 //recreate elements
256
256
257 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
257 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
258 QList<QChartSeries*> seriesList = m_chartItems.uniqueKeys();
258 QList<QChartSeries*> seriesList = m_chartItems.uniqueKeys();
259
259
260 foreach(QChartAxis* axis, axisList) {
260 foreach(QChartAxis* axis, axisList) {
261 handleAxisRemoved(axis);
261 handleAxisRemoved(axis);
262 handleAxisAdded(axis);
262 handleAxisAdded(axis);
263 }
263 }
264 foreach(QChartSeries* series, seriesList) {
264 foreach(QChartSeries* series, seriesList) {
265 handleSeriesRemoved(series);
265 handleSeriesRemoved(series);
266 handleSeriesAdded(series);
266 handleSeriesAdded(series);
267 }
267 }
268
268
269 //now reintialize view data
269 //now reintialize view data
270 //TODO: make it more nice
270 //TODO: make it more nice
271 m_dataset->setDomain(m_dataset->domainIndex());
271 m_dataset->setDomain(m_dataset->domainIndex());
272 }
272 }
273 }
273 }
274
274
275 QChart::AnimationOptions ChartPresenter::animationOptions() const
275 QChart::AnimationOptions ChartPresenter::animationOptions() const
276 {
276 {
277 return m_options;
277 return m_options;
278 }
278 }
279
279
280
280
281 #include "moc_chartpresenter_p.cpp"
281 #include "moc_chartpresenter_p.cpp"
282
282
283 QTCOMMERCIALCHART_END_NAMESPACE
283 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,267 +1,267
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartaxis.h"
3 #include "qchartaxis.h"
4 #include <QTime>
4 #include <QTime>
5
5
6 //series
6 //series
7 #include "qbarset.h"
7 #include "qbarset.h"
8 #include "qbarseries.h"
8 #include "qbarseries.h"
9 #include "qstackedbarseries.h"
9 #include "qstackedbarseries.h"
10 #include "qpercentbarseries.h"
10 #include "qpercentbarseries.h"
11 #include "qlineseries.h"
11 #include "qlineseries.h"
12 #include "qscatterseries.h"
12 #include "qscatterseries.h"
13 #include "qpieseries.h"
13 #include "qpieseries.h"
14 #include "qpieslice.h"
14 #include "qpieslice.h"
15
15
16 //items
16 //items
17 #include "axisitem_p.h"
17 #include "axisitem_p.h"
18 #include "barpresenter.h"
18 #include "barpresenter.h"
19 #include "stackedbarpresenter.h"
19 #include "stackedbarpresenter.h"
20 #include "linechartitem_p.h"
20 #include "linechartitem_p.h"
21 #include "percentbarpresenter.h"
21 #include "percentbarpresenter.h"
22 #include "scatterpresenter_p.h"
22 #include "scatterpresenter_p.h"
23 #include "piepresenter.h"
23 #include "piepresenter_p.h"
24
24
25 //themes
25 //themes
26 #include "chartthemevanilla_p.h"
26 #include "chartthemevanilla_p.h"
27 #include "chartthemeicy_p.h"
27 #include "chartthemeicy_p.h"
28 #include "chartthemegrayscale_p.h"
28 #include "chartthemegrayscale_p.h"
29 #include "chartthemescientific_p.h"
29 #include "chartthemescientific_p.h"
30
30
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /* TODO
34 /* TODO
35 case QChart::ChartThemeUnnamed1:
35 case QChart::ChartThemeUnnamed1:
36 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
36 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
37 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
37 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
38 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
38 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
39 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
39 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
41
41
42 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
42 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
43 m_gradientEndColor = QColor(QRgb(0xffafafaf));
43 m_gradientEndColor = QColor(QRgb(0xffafafaf));
44 */
44 */
45
45
46 ChartTheme::ChartTheme(QChart::ChartTheme id)
46 ChartTheme::ChartTheme(QChart::ChartTheme id)
47 {
47 {
48 m_id = id;
48 m_id = id;
49 m_seriesColor.append(QRgb(0xff000000));
49 m_seriesColor.append(QRgb(0xff000000));
50 m_seriesColor.append(QRgb(0xff707070));
50 m_seriesColor.append(QRgb(0xff707070));
51 m_gradientStartColor = QColor(QRgb(0xffffffff));
51 m_gradientStartColor = QColor(QRgb(0xffffffff));
52 m_gradientEndColor = QColor(QRgb(0xffafafaf));
52 m_gradientEndColor = QColor(QRgb(0xffafafaf));
53
53
54 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
54 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
55 }
55 }
56
56
57
57
58 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
58 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
59 {
59 {
60 switch(theme) {
60 switch(theme) {
61 case QChart::ChartThemeDefault:
61 case QChart::ChartThemeDefault:
62 return new ChartThemeIcy();
62 return new ChartThemeIcy();
63 case QChart::ChartThemeVanilla:
63 case QChart::ChartThemeVanilla:
64 return new ChartThemeVanilla();
64 return new ChartThemeVanilla();
65 case QChart::ChartThemeIcy:
65 case QChart::ChartThemeIcy:
66 return new ChartThemeIcy();
66 return new ChartThemeIcy();
67 case QChart::ChartThemeGrayscale:
67 case QChart::ChartThemeGrayscale:
68 return new ChartThemeGrayscale();
68 return new ChartThemeGrayscale();
69 case QChart::ChartThemeScientific:
69 case QChart::ChartThemeScientific:
70 return new ChartThemeScientific();
70 return new ChartThemeScientific();
71 }
71 }
72 }
72 }
73
73
74 void ChartTheme::decorate(QChart* chart)
74 void ChartTheme::decorate(QChart* chart)
75 {
75 {
76 QLinearGradient backgroundGradient;
76 QLinearGradient backgroundGradient;
77 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
77 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
78 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
78 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
79 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
79 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
80 chart->setChartBackgroundBrush(backgroundGradient);
80 chart->setChartBackgroundBrush(backgroundGradient);
81 }
81 }
82 //TODO helper to by removed later
82 //TODO helper to by removed later
83 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
83 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
84 {
84 {
85 switch(series->type())
85 switch(series->type())
86 {
86 {
87 case QChartSeries::SeriesTypeLine: {
87 case QChartSeries::SeriesTypeLine: {
88 QLineSeries* s = static_cast<QLineSeries*>(series);
88 QLineSeries* s = static_cast<QLineSeries*>(series);
89 LineChartItem* i = static_cast<LineChartItem*>(item);
89 LineChartItem* i = static_cast<LineChartItem*>(item);
90 decorate(i,s,count);
90 decorate(i,s,count);
91 break;
91 break;
92 }
92 }
93 case QChartSeries::SeriesTypeBar: {
93 case QChartSeries::SeriesTypeBar: {
94 QBarSeries* b = static_cast<QBarSeries*>(series);
94 QBarSeries* b = static_cast<QBarSeries*>(series);
95 BarPresenter* i = static_cast<BarPresenter*>(item);
95 BarPresenter* i = static_cast<BarPresenter*>(item);
96 decorate(i,b,count);
96 decorate(i,b,count);
97 break;
97 break;
98 }
98 }
99 case QChartSeries::SeriesTypeStackedBar: {
99 case QChartSeries::SeriesTypeStackedBar: {
100 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
100 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
101 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
101 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
102 decorate(i,s,count);
102 decorate(i,s,count);
103 break;
103 break;
104 }
104 }
105 case QChartSeries::SeriesTypePercentBar: {
105 case QChartSeries::SeriesTypePercentBar: {
106 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
106 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
107 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
107 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
108 decorate(i,s,count);
108 decorate(i,s,count);
109 break;
109 break;
110 }
110 }
111 case QChartSeries::SeriesTypeScatter: {
111 case QChartSeries::SeriesTypeScatter: {
112 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
112 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
113 Q_ASSERT(s);
113 Q_ASSERT(s);
114 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
114 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
115 Q_ASSERT(i);
115 Q_ASSERT(i);
116 decorate(i, s, count);
116 decorate(i, s, count);
117 break;
117 break;
118 }
118 }
119 case QChartSeries::SeriesTypePie: {
119 case QChartSeries::SeriesTypePie: {
120 QPieSeries* s = static_cast<QPieSeries*>(series);
120 QPieSeries* s = static_cast<QPieSeries*>(series);
121 PiePresenter* i = static_cast<PiePresenter*>(item);
121 PiePresenter* i = static_cast<PiePresenter*>(item);
122 decorate(i,s,count);
122 decorate(i,s,count);
123 break;
123 break;
124 }
124 }
125 default:
125 default:
126 qDebug()<<"Wrong item to be decorated by theme";
126 qDebug()<<"Wrong item to be decorated by theme";
127 break;
127 break;
128 }
128 }
129
129
130 }
130 }
131
131
132 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
132 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
133 {
133 {
134 QPen pen;
134 QPen pen;
135 if(pen != series->pen()){
135 if(pen != series->pen()){
136 item->setPen(series->pen());
136 item->setPen(series->pen());
137 return;
137 return;
138 }
138 }
139 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
139 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
140 pen.setWidthF(2);
140 pen.setWidthF(2);
141 item->setPen(pen);
141 item->setPen(pen);
142 }
142 }
143
143
144 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
144 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
145 {
145 {
146 for (int i=0; i<series->countSets(); i++) {
146 for (int i=0; i<series->countSets(); i++) {
147 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
147 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
148 }
148 }
149 }
149 }
150
150
151 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
151 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
152 {
152 {
153 for (int i=0; i<series->countSets(); i++) {
153 for (int i=0; i<series->countSets(); i++) {
154 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
154 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
155 }
155 }
156 }
156 }
157
157
158 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
158 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
159 {
159 {
160 for (int i=0; i<series->countSets(); i++) {
160 for (int i=0; i<series->countSets(); i++) {
161 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
161 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
162 }
162 }
163 }
163 }
164
164
165 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count)
165 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count)
166 {
166 {
167 Q_ASSERT(presenter);
167 Q_ASSERT(presenter);
168 Q_ASSERT(series);
168 Q_ASSERT(series);
169
169
170 QColor color = m_seriesColor.at(count % m_seriesColor.size());
170 QColor color = m_seriesColor.at(count % m_seriesColor.size());
171 // TODO: define alpha in the theme? or in the series?
171 // TODO: define alpha in the theme? or in the series?
172 //color.setAlpha(120);
172 //color.setAlpha(120);
173
173
174 QBrush brush(color, Qt::SolidPattern);
174 QBrush brush(color, Qt::SolidPattern);
175 presenter->m_markerBrush = brush;
175 presenter->m_markerBrush = brush;
176
176
177 QPen pen(brush, 3);
177 QPen pen(brush, 3);
178 pen.setColor(color);
178 pen.setColor(color);
179 presenter->m_markerPen = pen;
179 presenter->m_markerPen = pen;
180 }
180 }
181
181
182 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
182 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
183 {
183 {
184 // create a list of slice colors based on current theme
184 // create a list of slice colors based on current theme
185 int i = 0;
185 int i = 0;
186 QList<QColor> colors;
186 QList<QColor> colors;
187 while (colors.count() < series->count()) {
187 while (colors.count() < series->count()) {
188
188
189 // get base color
189 // get base color
190 QColor c = m_seriesColor[i++];
190 QColor c = m_seriesColor[i++];
191 i = i % m_seriesColor.count();
191 i = i % m_seriesColor.count();
192
192
193 // dont use black colors... looks bad
193 // dont use black colors... looks bad
194 if (c == Qt::black)
194 if (c == Qt::black)
195 continue;
195 continue;
196
196
197 // by default use the "raw" theme color
197 // by default use the "raw" theme color
198 if (!colors.contains(c)) {
198 if (!colors.contains(c)) {
199 colors << c;
199 colors << c;
200 continue;
200 continue;
201 }
201 }
202 // ...ok we need to generate something that looks like the same color
202 // ...ok we need to generate something that looks like the same color
203 // but different lightness
203 // but different lightness
204
204
205 int tryCount = 0;
205 int tryCount = 0;
206 while (tryCount++ < 100) {
206 while (tryCount++ < 100) {
207
207
208 // find maximum value we can raise the lightness
208 // find maximum value we can raise the lightness
209 int lMax = 255;
209 int lMax = 255;
210 if (lMax > 255 - c.red())
210 if (lMax > 255 - c.red())
211 lMax = 255 - c.red();
211 lMax = 255 - c.red();
212 if (lMax > 255 - c.green())
212 if (lMax > 255 - c.green())
213 lMax = 255 - c.green();
213 lMax = 255 - c.green();
214 if (lMax > 255 - c.blue())
214 if (lMax > 255 - c.blue())
215 lMax = 255 - c.blue();
215 lMax = 255 - c.blue();
216
216
217 // find maximum value we can make it darker
217 // find maximum value we can make it darker
218 int dMax = 255;
218 int dMax = 255;
219 if (dMax > c.red())
219 if (dMax > c.red())
220 dMax = c.red();
220 dMax = c.red();
221 if (dMax > c.green())
221 if (dMax > c.green())
222 dMax = c.green();
222 dMax = c.green();
223 if (dMax > c.blue())
223 if (dMax > c.blue())
224 dMax = c.blue();
224 dMax = c.blue();
225
225
226 int max = dMax + lMax;
226 int max = dMax + lMax;
227 if (max == 0) {
227 if (max == 0) {
228 // no room to make color lighter or darker...
228 // no room to make color lighter or darker...
229 qDebug() << "cannot generate a color for pie!";
229 qDebug() << "cannot generate a color for pie!";
230 break;
230 break;
231 }
231 }
232
232
233 // generate random color
233 // generate random color
234 int r = c.red() - dMax;
234 int r = c.red() - dMax;
235 int g = c.green() - dMax;
235 int g = c.green() - dMax;
236 int b = c.blue() - dMax;
236 int b = c.blue() - dMax;
237 int d = qrand() % max;
237 int d = qrand() % max;
238 c.setRgb(r+d, g+d, b+d);
238 c.setRgb(r+d, g+d, b+d);
239
239
240 // found a unique color?
240 // found a unique color?
241 if (!colors.contains(c))
241 if (!colors.contains(c))
242 break;
242 break;
243 }
243 }
244
244
245 qDebug() << "generated a color for pie" << c;
245 qDebug() << "generated a color for pie" << c;
246 colors << c;
246 colors << c;
247 }
247 }
248
248
249 // finally update colors
249 // finally update colors
250 foreach (QPieSlice* s, series->slices()) {
250 foreach (QPieSlice* s, series->slices()) {
251 QColor c = colors.takeFirst();
251 QColor c = colors.takeFirst();
252 s->setPen(c);
252 s->setPen(c);
253 s->setBrush(c);
253 s->setBrush(c);
254 }
254 }
255 }
255 }
256
256
257
257
258 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
258 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
259 {
259 {
260 //TODO: dummy defults for now
260 //TODO: dummy defults for now
261 axis->setLabelsBrush(Qt::black);
261 axis->setLabelsBrush(Qt::black);
262 axis->setLabelsPen(Qt::NoPen);
262 axis->setLabelsPen(Qt::NoPen);
263 axis->setShadesPen(Qt::NoPen);
263 axis->setShadesPen(Qt::NoPen);
264 axis->setShadesOpacity(0.5);
264 axis->setShadesOpacity(0.5);
265 }
265 }
266
266
267 QTCOMMERCIALCHART_END_NAMESPACE
267 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,18 +1,18
1 INCLUDEPATH += $$PWD
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
2 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/qpieseries.cpp \
5 $$PWD/qpieseries.cpp \
6 $$PWD/pieslice.cpp \
6 $$PWD/pieslice.cpp \
7 $$PWD/piepresenter.cpp \
7 $$PWD/piepresenter.cpp \
8 $$PWD/pieslicelabel.cpp \
8 $$PWD/pieslicelabel.cpp \
9 $$PWD/qpieslice.cpp
9 $$PWD/qpieslice.cpp
10
10
11 PRIVATE_HEADERS += \
11 PRIVATE_HEADERS += \
12 $$PWD/piepresenter.h \
12 $$PWD/piepresenter_p.h \
13 $$PWD/pieslice.h \
13 $$PWD/pieslice_p.h \
14 $$PWD/pieslicelabel.h
14 $$PWD/pieslicelabel_p.h
15
15
16 PUBLIC_HEADERS += \
16 PUBLIC_HEADERS += \
17 $$PWD/qpieseries.h \
17 $$PWD/qpieseries.h \
18 $$PWD/qpieslice.h
18 $$PWD/qpieslice.h
@@ -1,210 +1,210
1
1
2 #include "piepresenter.h"
2 #include "piepresenter_p.h"
3 #include "pieslice.h"
3 #include "pieslice_p.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "pieslicelabel.h"
5 #include "pieslicelabel_p.h"
6 #include "qpieseries.h"
6 #include "qpieseries.h"
7 #include <qmath.h>
7 #include <qmath.h>
8 #include <QDebug>
8 #include <QDebug>
9 #include <QFontMetrics>
9 #include <QFontMetrics>
10
10
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series)
14 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series)
15 :ChartItem(parent),
15 :ChartItem(parent),
16 m_series(series)
16 m_series(series)
17 {
17 {
18 Q_ASSERT(series);
18 Q_ASSERT(series);
19 connect(series, SIGNAL(changed(const QPieSeries::ChangeSet&)), this, SLOT(handleSeriesChanged(const QPieSeries::ChangeSet&)));
19 connect(series, SIGNAL(changed(const QPieSeries::ChangeSet&)), this, SLOT(handleSeriesChanged(const QPieSeries::ChangeSet&)));
20 connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry()));
20 connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry()));
21 connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry()));
21 connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry()));
22
22
23 if (m_series->count()) {
23 if (m_series->count()) {
24 QPieSeries::ChangeSet changeSet;
24 QPieSeries::ChangeSet changeSet;
25 changeSet.appendAdded(m_series->m_slices);
25 changeSet.appendAdded(m_series->m_slices);
26 handleSeriesChanged(changeSet);
26 handleSeriesChanged(changeSet);
27 }
27 }
28 }
28 }
29
29
30 PiePresenter::~PiePresenter()
30 PiePresenter::~PiePresenter()
31 {
31 {
32 // slices deleted automatically through QGraphicsItem
32 // slices deleted automatically through QGraphicsItem
33 }
33 }
34
34
35 void PiePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
35 void PiePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
36 {
36 {
37 // TODO: paint shadows for all components
37 // TODO: paint shadows for all components
38 // - get paths from items & merge & offset and draw with shadow color?
38 // - get paths from items & merge & offset and draw with shadow color?
39 }
39 }
40
40
41 void PiePresenter::handleSeriesChanged(const QPieSeries::ChangeSet& changeSet)
41 void PiePresenter::handleSeriesChanged(const QPieSeries::ChangeSet& changeSet)
42 {
42 {
43 //qDebug() << "PiePresenter::handleSeriesChanged()";
43 //qDebug() << "PiePresenter::handleSeriesChanged()";
44 //qDebug() << " added : " << changeSet.added();
44 //qDebug() << " added : " << changeSet.added();
45 //qDebug() << " changed: " << changeSet.changed();
45 //qDebug() << " changed: " << changeSet.changed();
46 //qDebug() << " removed: " << changeSet.removed();
46 //qDebug() << " removed: " << changeSet.removed();
47
47
48 foreach (QPieSlice* s, changeSet.added())
48 foreach (QPieSlice* s, changeSet.added())
49 addSlice(s);
49 addSlice(s);
50
50
51 foreach (QPieSlice* s, changeSet.changed())
51 foreach (QPieSlice* s, changeSet.changed())
52 updateSlice(s);
52 updateSlice(s);
53
53
54 foreach (QPieSlice* s, changeSet.removed())
54 foreach (QPieSlice* s, changeSet.removed())
55 deleteSlice(s);
55 deleteSlice(s);
56
56
57 // every change possibly changes the actual pie size
57 // every change possibly changes the actual pie size
58 updateGeometry();
58 updateGeometry();
59 }
59 }
60
60
61 void PiePresenter::handleDomainChanged(const Domain& domain)
61 void PiePresenter::handleDomainChanged(const Domain& domain)
62 {
62 {
63 // TODO
63 // TODO
64 }
64 }
65
65
66 void PiePresenter::handleGeometryChanged(const QRectF& rect)
66 void PiePresenter::handleGeometryChanged(const QRectF& rect)
67 {
67 {
68 m_rect = rect;
68 m_rect = rect;
69 prepareGeometryChange();
69 prepareGeometryChange();
70 updateGeometry();
70 updateGeometry();
71 }
71 }
72
72
73 void PiePresenter::updateGeometry()
73 void PiePresenter::updateGeometry()
74 {
74 {
75 if (!m_rect.isValid() || m_rect.isEmpty())
75 if (!m_rect.isValid() || m_rect.isEmpty())
76 return;
76 return;
77
77
78 // calculate maximum rectangle for pie
78 // calculate maximum rectangle for pie
79 QRectF pieRect = m_rect;
79 QRectF pieRect = m_rect;
80 if (pieRect.width() < pieRect.height()) {
80 if (pieRect.width() < pieRect.height()) {
81 pieRect.setWidth(pieRect.width() * m_series->sizeFactor());
81 pieRect.setWidth(pieRect.width() * m_series->sizeFactor());
82 pieRect.setHeight(pieRect.width());
82 pieRect.setHeight(pieRect.width());
83 pieRect.moveCenter(m_rect.center());
83 pieRect.moveCenter(m_rect.center());
84 } else {
84 } else {
85 pieRect.setHeight(pieRect.height() * m_series->sizeFactor());
85 pieRect.setHeight(pieRect.height() * m_series->sizeFactor());
86 pieRect.setWidth(pieRect.height());
86 pieRect.setWidth(pieRect.height());
87 pieRect.moveCenter(m_rect.center());
87 pieRect.moveCenter(m_rect.center());
88 }
88 }
89
89
90 // position the pie rectangle
90 // position the pie rectangle
91 switch (m_series->position()) {
91 switch (m_series->position()) {
92 case QPieSeries::PiePositionTopLeft: {
92 case QPieSeries::PiePositionTopLeft: {
93 pieRect.setHeight(pieRect.height() / 2);
93 pieRect.setHeight(pieRect.height() / 2);
94 pieRect.setWidth(pieRect.height());
94 pieRect.setWidth(pieRect.height());
95 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
95 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
96 break;
96 break;
97 }
97 }
98 case QPieSeries::PiePositionTopRight: {
98 case QPieSeries::PiePositionTopRight: {
99 pieRect.setHeight(pieRect.height() / 2);
99 pieRect.setHeight(pieRect.height() / 2);
100 pieRect.setWidth(pieRect.height());
100 pieRect.setWidth(pieRect.height());
101 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
101 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
102 break;
102 break;
103 }
103 }
104 case QPieSeries::PiePositionBottomLeft: {
104 case QPieSeries::PiePositionBottomLeft: {
105 pieRect.setHeight(pieRect.height() / 2);
105 pieRect.setHeight(pieRect.height() / 2);
106 pieRect.setWidth(pieRect.height());
106 pieRect.setWidth(pieRect.height());
107 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
107 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
108 break;
108 break;
109 }
109 }
110 case QPieSeries::PiePositionBottomRight: {
110 case QPieSeries::PiePositionBottomRight: {
111 pieRect.setHeight(pieRect.height() / 2);
111 pieRect.setHeight(pieRect.height() / 2);
112 pieRect.setWidth(pieRect.height());
112 pieRect.setWidth(pieRect.height());
113 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
113 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
114 break;
114 break;
115 }
115 }
116 default:
116 default:
117 break;
117 break;
118 }
118 }
119
119
120 // calculate how much space we need around the pie rectangle (labels & exploding)
120 // calculate how much space we need around the pie rectangle (labels & exploding)
121 qreal delta = 0;
121 qreal delta = 0;
122 qreal pieRadius = pieRect.height() / 2;
122 qreal pieRadius = pieRect.height() / 2;
123 foreach (QPieSlice* s, m_series->m_slices) {
123 foreach (QPieSlice* s, m_series->m_slices) {
124
124
125 // calculate the farthest point in the slice from the pie center
125 // calculate the farthest point in the slice from the pie center
126 qreal centerAngle = s->angle() + (s->angleSpan() / 2);
126 qreal centerAngle = s->angle() + (s->angleSpan() / 2);
127 qreal len = pieRadius + s->labelArmLength() + s->explodeDistance();
127 qreal len = pieRadius + s->labelArmLength() + s->explodeDistance();
128 QPointF dp(qSin(centerAngle*(PI/180)) * len, -qCos(centerAngle*(PI/180)) * len);
128 QPointF dp(qSin(centerAngle*(PI/180)) * len, -qCos(centerAngle*(PI/180)) * len);
129 QPointF p = pieRect.center() + dp;
129 QPointF p = pieRect.center() + dp;
130
130
131 // TODO: consider the label text
131 // TODO: consider the label text
132
132
133 // calculate how much the radius must get smaller to fit that point in the base rectangle
133 // calculate how much the radius must get smaller to fit that point in the base rectangle
134 qreal dt = m_rect.top() - p.y();
134 qreal dt = m_rect.top() - p.y();
135 if (dt > delta) delta = dt;
135 if (dt > delta) delta = dt;
136 qreal dl = m_rect.left() - p.x();
136 qreal dl = m_rect.left() - p.x();
137 if (dl > delta) delta = dl;
137 if (dl > delta) delta = dl;
138 qreal dr = p.x() - m_rect.right();
138 qreal dr = p.x() - m_rect.right();
139 if (dr > delta) delta = dr;
139 if (dr > delta) delta = dr;
140 qreal db = p.y() - m_rect.bottom();
140 qreal db = p.y() - m_rect.bottom();
141 if (db > delta) delta = db;
141 if (db > delta) delta = db;
142
142
143 //if (!m_rect.contains(p)) qDebug() << s->label() << dt << dl << dr << db << "delta" << delta;
143 //if (!m_rect.contains(p)) qDebug() << s->label() << dt << dl << dr << db << "delta" << delta;
144 }
144 }
145
145
146 // shrink the pie rectangle so that everything outside it fits the base rectangle
146 // shrink the pie rectangle so that everything outside it fits the base rectangle
147 pieRect.adjust(delta, delta, -delta, -delta);
147 pieRect.adjust(delta, delta, -delta, -delta);
148
148
149 // update slices
149 // update slices
150 if (m_pieRect != pieRect) {
150 if (m_pieRect != pieRect) {
151 m_pieRect = pieRect;
151 m_pieRect = pieRect;
152 //qDebug() << "PiePresenter::updateGeometry()" << m_rect << m_pieRect;
152 //qDebug() << "PiePresenter::updateGeometry()" << m_rect << m_pieRect;
153 foreach (PieSlice* s, m_slices.values()) {
153 foreach (PieSlice* s, m_slices.values()) {
154 s->setPieRect(m_pieRect);
154 s->setPieRect(m_pieRect);
155 s->updateGeometry();
155 s->updateGeometry();
156 s->update();
156 s->update();
157 }
157 }
158 }
158 }
159 }
159 }
160
160
161 void PiePresenter::addSlice(QPieSlice* sliceData)
161 void PiePresenter::addSlice(QPieSlice* sliceData)
162 {
162 {
163 //qDebug() << "PiePresenter::addSlice()" << sliceData;
163 //qDebug() << "PiePresenter::addSlice()" << sliceData;
164
164
165 if (m_slices.keys().contains(sliceData)) {
165 if (m_slices.keys().contains(sliceData)) {
166 Q_ASSERT(0); // TODO: how to handle this nicely?
166 Q_ASSERT(0); // TODO: how to handle this nicely?
167 return;
167 return;
168 }
168 }
169
169
170 // create slice
170 // create slice
171 PieSlice *slice = new PieSlice(this);
171 PieSlice *slice = new PieSlice(this);
172 slice->setPieRect(m_pieRect);
172 slice->setPieRect(m_pieRect);
173 slice->updateData(sliceData);
173 slice->updateData(sliceData);
174 slice->updateGeometry();
174 slice->updateGeometry();
175 slice->update();
175 slice->update();
176 m_slices.insert(sliceData, slice);
176 m_slices.insert(sliceData, slice);
177
177
178 // connect signals
178 // connect signals
179 connect(slice, SIGNAL(clicked()), sliceData, SIGNAL(clicked()));
179 connect(slice, SIGNAL(clicked()), sliceData, SIGNAL(clicked()));
180 connect(slice, SIGNAL(hoverEnter()), sliceData, SIGNAL(hoverEnter()));
180 connect(slice, SIGNAL(hoverEnter()), sliceData, SIGNAL(hoverEnter()));
181 connect(slice, SIGNAL(hoverLeave()), sliceData, SIGNAL(hoverLeave()));
181 connect(slice, SIGNAL(hoverLeave()), sliceData, SIGNAL(hoverLeave()));
182 }
182 }
183
183
184 void PiePresenter::updateSlice(QPieSlice* sliceData)
184 void PiePresenter::updateSlice(QPieSlice* sliceData)
185 {
185 {
186 //qDebug() << "PiePresenter::updateSlice()" << sliceData;
186 //qDebug() << "PiePresenter::updateSlice()" << sliceData;
187
187
188 if (!m_slices.contains(sliceData)) {
188 if (!m_slices.contains(sliceData)) {
189 Q_ASSERT(0); // TODO: how to handle this nicely?
189 Q_ASSERT(0); // TODO: how to handle this nicely?
190 return;
190 return;
191 }
191 }
192
192
193 m_slices[sliceData]->updateData(sliceData);
193 m_slices[sliceData]->updateData(sliceData);
194 }
194 }
195
195
196 void PiePresenter::deleteSlice(QPieSlice* sliceData)
196 void PiePresenter::deleteSlice(QPieSlice* sliceData)
197 {
197 {
198 //qDebug() << "PiePresenter::deleteSlice()" << sliceData;
198 //qDebug() << "PiePresenter::deleteSlice()" << sliceData;
199
199
200 if (!m_slices.contains(sliceData)) {
200 if (!m_slices.contains(sliceData)) {
201 Q_ASSERT(0); // TODO: how to handle this nicely?
201 Q_ASSERT(0); // TODO: how to handle this nicely?
202 return;
202 return;
203 }
203 }
204
204
205 delete m_slices.take(sliceData);
205 delete m_slices.take(sliceData);
206 }
206 }
207
207
208 #include "moc_piepresenter.cpp"
208 #include "moc_piepresenter_p.cpp"
209
209
210 QTCOMMERCIALCHART_END_NAMESPACE
210 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/piechart/piepresenter.h to src/piechart/piepresenter_p.h
NO CONTENT: file renamed from src/piechart/piepresenter.h to src/piechart/piepresenter_p.h
@@ -1,135 +1,135
1 #include "pieslice.h"
1 #include "pieslice_p.h"
2 #include "pieslicelabel.h"
2 #include "pieslicelabel_p.h"
3 #include "piepresenter.h"
3 #include "piepresenter_p.h"
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "qpieslice.h"
5 #include "qpieslice.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 QPointF offset(qreal angle, qreal length)
14 QPointF offset(qreal angle, qreal length)
15 {
15 {
16 qreal dx = qSin(angle*(PI/180)) * length;
16 qreal dx = qSin(angle*(PI/180)) * length;
17 qreal dy = qCos(angle*(PI/180)) * length;
17 qreal dy = qCos(angle*(PI/180)) * length;
18 return QPointF(dx, -dy);
18 return QPointF(dx, -dy);
19 }
19 }
20
20
21 PieSlice::PieSlice(QGraphicsItem* parent)
21 PieSlice::PieSlice(QGraphicsItem* parent)
22 :QGraphicsObject(parent),
22 :QGraphicsObject(parent),
23 m_slicelabel(new PieSliceLabel(this)),
23 m_slicelabel(new PieSliceLabel(this)),
24 m_angle(0),
24 m_angle(0),
25 m_angleSpan(0),
25 m_angleSpan(0),
26 m_isExploded(false),
26 m_isExploded(false),
27 m_explodeDistance(0)
27 m_explodeDistance(0)
28 {
28 {
29 setAcceptHoverEvents(true);
29 setAcceptHoverEvents(true);
30 setAcceptedMouseButtons(Qt::LeftButton);
30 setAcceptedMouseButtons(Qt::LeftButton);
31 }
31 }
32
32
33 PieSlice::~PieSlice()
33 PieSlice::~PieSlice()
34 {
34 {
35
35
36 }
36 }
37
37
38 QRectF PieSlice::boundingRect() const
38 QRectF PieSlice::boundingRect() const
39 {
39 {
40 return m_path.boundingRect();
40 return m_path.boundingRect();
41 }
41 }
42
42
43 QPainterPath PieSlice::shape() const
43 QPainterPath PieSlice::shape() const
44 {
44 {
45 return m_path;
45 return m_path;
46 }
46 }
47
47
48 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setPen(m_pen);
50 painter->setPen(m_pen);
51 painter->setBrush(m_brush);
51 painter->setBrush(m_brush);
52 painter->drawPath(m_path);
52 painter->drawPath(m_path);
53 }
53 }
54
54
55 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
55 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
56 {
56 {
57 emit hoverEnter();
57 emit hoverEnter();
58 }
58 }
59
59
60 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
60 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
61 {
61 {
62 emit hoverLeave();
62 emit hoverLeave();
63 }
63 }
64
64
65 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
65 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
66 {
66 {
67 emit clicked();
67 emit clicked();
68 }
68 }
69
69
70 void PieSlice::setPieRect(QRectF rect)
70 void PieSlice::setPieRect(QRectF rect)
71 {
71 {
72 m_pieRect = rect;
72 m_pieRect = rect;
73 }
73 }
74
74
75 void PieSlice::updateGeometry()
75 void PieSlice::updateGeometry()
76 {
76 {
77 if (!m_pieRect.isValid() || m_pieRect.isEmpty())
77 if (!m_pieRect.isValid() || m_pieRect.isEmpty())
78 return;
78 return;
79
79
80 prepareGeometryChange();
80 prepareGeometryChange();
81
81
82 // calculate center angle
82 // calculate center angle
83 qreal centerAngle = m_angle + (m_angleSpan/2);
83 qreal centerAngle = m_angle + (m_angleSpan/2);
84
84
85 // adjust rect for exploding
85 // adjust rect for exploding
86 QRectF rect = m_pieRect;
86 QRectF rect = m_pieRect;
87 if (m_isExploded) {
87 if (m_isExploded) {
88 qreal dx = qSin(centerAngle*(PI/180)) * m_explodeDistance;
88 qreal dx = qSin(centerAngle*(PI/180)) * m_explodeDistance;
89 qreal dy = -qCos(centerAngle*(PI/180)) * m_explodeDistance;
89 qreal dy = -qCos(centerAngle*(PI/180)) * m_explodeDistance;
90 rect.translate(dx, dy);
90 rect.translate(dx, dy);
91 }
91 }
92
92
93 // update slice path
93 // update slice path
94 // TODO: draw the shape so that it might have a hole in the center
94 // TODO: draw the shape so that it might have a hole in the center
95 QPainterPath path;
95 QPainterPath path;
96 path.moveTo(rect.center());
96 path.moveTo(rect.center());
97 path.arcTo(rect, -m_angle + 90, -m_angleSpan);
97 path.arcTo(rect, -m_angle + 90, -m_angleSpan);
98 path.closeSubpath();
98 path.closeSubpath();
99 m_path = path;
99 m_path = path;
100
100
101 // update label position
101 // update label position
102 qreal radius = rect.height() / 2;
102 qreal radius = rect.height() / 2;
103 QPointF edgeCenter = rect.center() + offset(centerAngle, radius + 5);
103 QPointF edgeCenter = rect.center() + offset(centerAngle, radius + 5);
104 m_slicelabel->setArmStartPoint(edgeCenter);
104 m_slicelabel->setArmStartPoint(edgeCenter);
105 m_slicelabel->setArmAngle(centerAngle);
105 m_slicelabel->setArmAngle(centerAngle);
106 m_slicelabel->updateGeometry();
106 m_slicelabel->updateGeometry();
107 m_slicelabel->update();
107 m_slicelabel->update();
108
108
109 //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span;
109 //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span;
110 }
110 }
111
111
112 void PieSlice::updateData(const QPieSlice* sliceData)
112 void PieSlice::updateData(const QPieSlice* sliceData)
113 {
113 {
114 // TODO: compare what has changes to avoid unneccesary geometry updates
114 // TODO: compare what has changes to avoid unneccesary geometry updates
115
115
116 m_angle = sliceData->angle();
116 m_angle = sliceData->angle();
117 m_angleSpan = sliceData->angleSpan();
117 m_angleSpan = sliceData->angleSpan();
118 m_isExploded = sliceData->isExploded();
118 m_isExploded = sliceData->isExploded();
119 m_explodeDistance = sliceData->explodeDistance(); // TODO: expose to public API
119 m_explodeDistance = sliceData->explodeDistance(); // TODO: expose to public API
120 m_pen = sliceData->pen();
120 m_pen = sliceData->pen();
121 m_brush = sliceData->brush();
121 m_brush = sliceData->brush();
122
122
123 m_slicelabel->setVisible(sliceData->isLabelVisible());
123 m_slicelabel->setVisible(sliceData->isLabelVisible());
124 m_slicelabel->setText(sliceData->label());
124 m_slicelabel->setText(sliceData->label());
125 m_slicelabel->setPen(sliceData->labelPen());
125 m_slicelabel->setPen(sliceData->labelPen());
126 m_slicelabel->setFont(sliceData->labelFont());
126 m_slicelabel->setFont(sliceData->labelFont());
127 m_slicelabel->setArmLength(sliceData->labelArmLength());
127 m_slicelabel->setArmLength(sliceData->labelArmLength());
128
128
129 updateGeometry();
129 updateGeometry();
130 update();
130 update();
131 }
131 }
132
132
133 #include "moc_pieslice.cpp"
133 #include "moc_pieslice_p.cpp"
134
134
135 QTCOMMERCIALCHART_END_NAMESPACE
135 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/piechart/pieslice.h to src/piechart/pieslice_p.h
NO CONTENT: file renamed from src/piechart/pieslice.h to src/piechart/pieslice_p.h
@@ -1,72 +1,72
1 #include "pieslicelabel.h"
1 #include "pieslicelabel_p.h"
2 #include <QPainter>
2 #include <QPainter>
3 #include <qmath.h>
3 #include <qmath.h>
4 #include <QGraphicsTextItem>
4 #include <QGraphicsTextItem>
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 #define PI 3.14159265
9 #define PI 3.14159265
10
10
11 PieSliceLabel::PieSliceLabel(QGraphicsItem* parent)
11 PieSliceLabel::PieSliceLabel(QGraphicsItem* parent)
12 :QGraphicsItem(parent),
12 :QGraphicsItem(parent),
13 m_armAngle(0),
13 m_armAngle(0),
14 m_armLength(0)
14 m_armLength(0)
15 {
15 {
16
16
17 }
17 }
18
18
19 void PieSliceLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
19 void PieSliceLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
20 {
20 {
21 painter->setPen(m_pen);
21 painter->setPen(m_pen);
22 painter->drawPath(m_armPath);
22 painter->drawPath(m_armPath);
23
23
24 // TODO: do we need a pen for text?
24 // TODO: do we need a pen for text?
25 painter->setFont(m_font);
25 painter->setFont(m_font);
26 painter->drawText(m_textRect.bottomLeft(), m_text);
26 painter->drawText(m_textRect.bottomLeft(), m_text);
27
27
28 //qDebug() << "PieSliceLabel::paint" << m_text << m_textRect;
28 //qDebug() << "PieSliceLabel::paint" << m_text << m_textRect;
29 }
29 }
30
30
31 void PieSliceLabel::updateGeometry()
31 void PieSliceLabel::updateGeometry()
32 {
32 {
33 prepareGeometryChange();
33 prepareGeometryChange();
34
34
35 // calculate text size
35 // calculate text size
36 QFontMetricsF fm(m_font);
36 QFontMetricsF fm(m_font);
37 QRectF textRect = fm.boundingRect(m_text);
37 QRectF textRect = fm.boundingRect(m_text);
38
38
39 // calculate path for arm and text start point
39 // calculate path for arm and text start point
40 qreal dx = qSin(m_armAngle*(PI/180)) * m_armLength;
40 qreal dx = qSin(m_armAngle*(PI/180)) * m_armLength;
41 qreal dy = -qCos(m_armAngle*(PI/180)) * m_armLength;
41 qreal dy = -qCos(m_armAngle*(PI/180)) * m_armLength;
42 QPointF parm1 = m_armStartPoint + QPointF(dx, dy);
42 QPointF parm1 = m_armStartPoint + QPointF(dx, dy);
43
43
44 // calculate horizontal arm and text position
44 // calculate horizontal arm and text position
45 QPointF parm2 = parm1;
45 QPointF parm2 = parm1;
46 textRect.moveBottomLeft(parm1);
46 textRect.moveBottomLeft(parm1);
47 if (m_armAngle < 180) { // arm swings the other way on the left side
47 if (m_armAngle < 180) { // arm swings the other way on the left side
48 parm2 += QPointF(m_textRect.width(), 0);
48 parm2 += QPointF(m_textRect.width(), 0);
49 } else {
49 } else {
50 parm2 += QPointF(-m_textRect.width(),0);
50 parm2 += QPointF(-m_textRect.width(),0);
51 textRect.moveBottomLeft(parm2);
51 textRect.moveBottomLeft(parm2);
52 }
52 }
53
53
54 // add a little offset to text so that it does not touch the arm
54 // add a little offset to text so that it does not touch the arm
55 qreal yOffset = m_pen.widthF() ? m_pen.widthF() : 2;
55 qreal yOffset = m_pen.widthF() ? m_pen.widthF() : 2;
56 textRect.translate(0, -yOffset);
56 textRect.translate(0, -yOffset);
57
57
58 // update arm path
58 // update arm path
59 QPainterPath path;
59 QPainterPath path;
60 path.moveTo(m_armStartPoint);
60 path.moveTo(m_armStartPoint);
61 path.lineTo(parm1);
61 path.lineTo(parm1);
62 path.lineTo(parm2);
62 path.lineTo(parm2);
63
63
64 // update paths & rects
64 // update paths & rects
65 m_armPath = path;
65 m_armPath = path;
66 m_textRect = textRect;
66 m_textRect = textRect;
67 m_rect = path.boundingRect().united(m_textRect);
67 m_rect = path.boundingRect().united(m_textRect);
68
68
69 //qDebug() << "PieSliceLabel::updateGeometry" << m_text << m_armStartPoint << m_armLength << m_armAngle << m_textRect;
69 //qDebug() << "PieSliceLabel::updateGeometry" << m_text << m_armStartPoint << m_armLength << m_armAngle << m_textRect;
70 }
70 }
71
71
72 QTCOMMERCIALCHART_END_NAMESPACE
72 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/piechart/pieslicelabel.h to src/piechart/pieslicelabel_p.h
NO CONTENT: file renamed from src/piechart/pieslicelabel.h to src/piechart/pieslicelabel_p.h
@@ -1,537 +1,534
1 #include "qpieseries.h"
1 #include "qpieseries.h"
2 #include "qpieslice.h"
2 #include "qpieslice.h"
3 #include "piepresenter.h"
4 #include "pieslice.h"
5 #include <QFontMetrics>
6 #include <QDebug>
3 #include <QDebug>
7
4
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
6
10
7
11 /*!
8 /*!
12 \class QPieSeries::ChangeSet
9 \class QPieSeries::ChangeSet
13 \brief Defines the changes in the series.
10 \brief Defines the changes in the series.
14
11
15 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.
16
13
17 \sa QPieSeries::changed()
14 \sa QPieSeries::changed()
18 */
15 */
19
16
20 /*!
17 /*!
21 \internal
18 \internal
22 */
19 */
23 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
24 {
21 {
25 if (!m_added.contains(slice))
22 if (!m_added.contains(slice))
26 m_added << slice;
23 m_added << slice;
27 }
24 }
28
25
29 /*!
26 /*!
30 \internal
27 \internal
31 */
28 */
32 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
33 {
30 {
34 foreach (QPieSlice* s, slices)
31 foreach (QPieSlice* s, slices)
35 appendAdded(s);
32 appendAdded(s);
36 }
33 }
37
34
38 /*!
35 /*!
39 \internal
36 \internal
40 */
37 */
41 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
42 {
39 {
43 if (!m_changed.contains(slice))
40 if (!m_changed.contains(slice))
44 m_changed << slice;
41 m_changed << slice;
45 }
42 }
46
43
47 /*!
44 /*!
48 \internal
45 \internal
49 */
46 */
50 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
51 {
48 {
52 if (!m_removed.contains(slice))
49 if (!m_removed.contains(slice))
53 m_removed << slice;
50 m_removed << slice;
54 }
51 }
55
52
56 /*!
53 /*!
57 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.
58 \sa QPieSeries::changed()
55 \sa QPieSeries::changed()
59 */
56 */
60 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
61 {
58 {
62 return m_added;
59 return m_added;
63 }
60 }
64
61
65 /*!
62 /*!
66 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.
67 \sa QPieSeries::changed()
64 \sa QPieSeries::changed()
68 */
65 */
69 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
70 {
67 {
71 return m_changed;
68 return m_changed;
72 }
69 }
73
70
74 /*!
71 /*!
75 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.
76 \sa QPieSeries::changed()
73 \sa QPieSeries::changed()
77 */
74 */
78 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
79 {
76 {
80 return m_removed;
77 return m_removed;
81 }
78 }
82
79
83
80
84 /*!
81 /*!
85 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.
86 */
83 */
87 bool QPieSeries::ChangeSet::isEmpty() const
84 bool QPieSeries::ChangeSet::isEmpty() const
88 {
85 {
89 if (m_added.count() || m_changed.count() || m_removed.count())
86 if (m_added.count() || m_changed.count() || m_removed.count())
90 return false;
87 return false;
91 return true;
88 return true;
92 }
89 }
93
90
94 /*!
91 /*!
95 \enum QPieSeries::PiePosition
92 \enum QPieSeries::PiePosition
96
93
97 This enum describes pie position within its bounding rectangle
94 This enum describes pie position within its bounding rectangle
98
95
99 \value PiePositionMaximized
96 \value PiePositionMaximized
100 \value PiePositionTopLeft
97 \value PiePositionTopLeft
101 \value PiePositionTopRight
98 \value PiePositionTopRight
102 \value PiePositionBottomLeft
99 \value PiePositionBottomLeft
103 \value PiePositionBottomRight
100 \value PiePositionBottomRight
104 */
101 */
105
102
106 /*!
103 /*!
107 \class QPieSeries
104 \class QPieSeries
108 \brief Pie series API for QtCommercial Charts
105 \brief Pie series API for QtCommercial Charts
109
106
110 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.
111 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.
112 The actual slice size (span) is determined by that relative value.
109 The actual slice size (span) is determined by that relative value.
113
110
114 By default the pie is defined as full but it can be a partial pie.
111 By default the pie is defined as full but it can be a partial pie.
115 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.
116
113
117 Example on how to create a chart with pie series:
114 Example on how to create a chart with pie series:
118 \snippet ../example/piechart/main.cpp 1
115 \snippet ../example/piechart/main.cpp 1
119
116
120 To help with the most common user intercation scenarions there some convenience functions. Specifically
117 To help with the most common user intercation scenarions there some convenience functions. Specifically
121 exploding and higlighting:
118 exploding and higlighting:
122 \snippet ../example/piechart/main.cpp 2
119 \snippet ../example/piechart/main.cpp 2
123
120
124 */
121 */
125
122
126 /*!
123 /*!
127 Constructs a series object which is a child of \a parent.
124 Constructs a series object which is a child of \a parent.
128 */
125 */
129 QPieSeries::QPieSeries(QObject *parent) :
126 QPieSeries::QPieSeries(QObject *parent) :
130 QChartSeries(parent),
127 QChartSeries(parent),
131 m_sizeFactor(1.0),
128 m_sizeFactor(1.0),
132 m_position(PiePositionMaximized),
129 m_position(PiePositionMaximized),
133 m_pieStartAngle(0),
130 m_pieStartAngle(0),
134 m_pieAngleSpan(360)
131 m_pieAngleSpan(360)
135 {
132 {
136
133
137 }
134 }
138
135
139 /*!
136 /*!
140 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
137 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
141 */
138 */
142 QPieSeries::~QPieSeries()
139 QPieSeries::~QPieSeries()
143 {
140 {
144
141
145 }
142 }
146
143
147 /*!
144 /*!
148 Returns QChartSeries::SeriesTypePie.
145 Returns QChartSeries::SeriesTypePie.
149 */
146 */
150 QChartSeries::QChartSeriesType QPieSeries::type() const
147 QChartSeries::QChartSeriesType QPieSeries::type() const
151 {
148 {
152 return QChartSeries::SeriesTypePie;
149 return QChartSeries::SeriesTypePie;
153 }
150 }
154
151
155 /*!
152 /*!
156 \internal \a data
153 \internal \a data
157 */
154 */
158 bool QPieSeries::setData(QList<qreal> data)
155 bool QPieSeries::setData(QList<qreal> data)
159 {
156 {
160 // TODO: remove this function
157 // TODO: remove this function
161 QList<QPieSlice*> slices;
158 QList<QPieSlice*> slices;
162 foreach (qreal value, data)
159 foreach (qreal value, data)
163 slices << new QPieSlice(value, QString::number(value));
160 slices << new QPieSlice(value, QString::number(value));
164 set(slices);
161 set(slices);
165 return true;
162 return true;
166 }
163 }
167
164
168 /*!
165 /*!
169 Sets an array of \a slices to the series.
166 Sets an array of \a slices to the series.
170 Slice ownership is passed to the series.
167 Slice ownership is passed to the series.
171 */
168 */
172 void QPieSeries::set(QList<QPieSlice*> slices)
169 void QPieSeries::set(QList<QPieSlice*> slices)
173 {
170 {
174 clear();
171 clear();
175 add(slices);
172 add(slices);
176 }
173 }
177
174
178 /*!
175 /*!
179 Adds an array of \a slices to the series.
176 Adds an array of \a slices to the series.
180 Slice ownership is passed to the series.
177 Slice ownership is passed to the series.
181 */
178 */
182 void QPieSeries::add(QList<QPieSlice*> slices)
179 void QPieSeries::add(QList<QPieSlice*> slices)
183 {
180 {
184 ChangeSet changeSet;
181 ChangeSet changeSet;
185 foreach (QPieSlice* s, slices) {
182 foreach (QPieSlice* s, slices) {
186 s->setParent(this);
183 s->setParent(this);
187 m_slices << s;
184 m_slices << s;
188 changeSet.appendAdded(s);
185 changeSet.appendAdded(s);
189 }
186 }
190
187
191 updateDerivativeData();
188 updateDerivativeData();
192
189
193 foreach (QPieSlice* s, slices) {
190 foreach (QPieSlice* s, slices) {
194 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
191 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
195 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
192 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
196 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
193 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
197 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
194 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
198 }
195 }
199
196
200 emit changed(changeSet);
197 emit changed(changeSet);
201 }
198 }
202
199
203 /*!
200 /*!
204 Adds a single \a slice to the series.
201 Adds a single \a slice to the series.
205 Slice ownership is passed to the series.
202 Slice ownership is passed to the series.
206 */
203 */
207 void QPieSeries::add(QPieSlice* slice)
204 void QPieSeries::add(QPieSlice* slice)
208 {
205 {
209 add(QList<QPieSlice*>() << slice);
206 add(QList<QPieSlice*>() << slice);
210 }
207 }
211
208
212
209
213 /*!
210 /*!
214 Adds a single slice to the series with give \a value and \a name.
211 Adds a single slice to the series with give \a value and \a name.
215 Slice ownership is passed to the series.
212 Slice ownership is passed to the series.
216 */
213 */
217 QPieSlice* QPieSeries::add(qreal value, QString name)
214 QPieSlice* QPieSeries::add(qreal value, QString name)
218 {
215 {
219 QPieSlice* slice = new QPieSlice(value, name);
216 QPieSlice* slice = new QPieSlice(value, name);
220 add(slice);
217 add(slice);
221 return slice;
218 return slice;
222 }
219 }
223
220
224 /*!
221 /*!
225 Removes a single \a slice from the series and deletes the slice.
222 Removes a single \a slice from the series and deletes the slice.
226
223
227 Do not reference this pointer after this call.
224 Do not reference this pointer after this call.
228 */
225 */
229 void QPieSeries::remove(QPieSlice* slice)
226 void QPieSeries::remove(QPieSlice* slice)
230 {
227 {
231 if (!m_slices.removeOne(slice)) {
228 if (!m_slices.removeOne(slice)) {
232 Q_ASSERT(0); // TODO: how should this be reported?
229 Q_ASSERT(0); // TODO: how should this be reported?
233 return;
230 return;
234 }
231 }
235
232
236 ChangeSet changeSet;
233 ChangeSet changeSet;
237 changeSet.appendRemoved(slice);
234 changeSet.appendRemoved(slice);
238 emit changed(changeSet);
235 emit changed(changeSet);
239
236
240 delete slice;
237 delete slice;
241 slice = NULL;
238 slice = NULL;
242
239
243 updateDerivativeData();
240 updateDerivativeData();
244 }
241 }
245
242
246 /*!
243 /*!
247 Clears all slices from the series.
244 Clears all slices from the series.
248 */
245 */
249 void QPieSeries::clear()
246 void QPieSeries::clear()
250 {
247 {
251 if (m_slices.count() == 0)
248 if (m_slices.count() == 0)
252 return;
249 return;
253
250
254 ChangeSet changeSet;
251 ChangeSet changeSet;
255 foreach (QPieSlice* s, m_slices) {
252 foreach (QPieSlice* s, m_slices) {
256 changeSet.appendRemoved(s);
253 changeSet.appendRemoved(s);
257 m_slices.removeOne(s);
254 m_slices.removeOne(s);
258 delete s;
255 delete s;
259 }
256 }
260 emit changed(changeSet);
257 emit changed(changeSet);
261 updateDerivativeData();
258 updateDerivativeData();
262 }
259 }
263
260
264 /*!
261 /*!
265 Counts the number of the slices in this series.
262 Counts the number of the slices in this series.
266 */
263 */
267 int QPieSeries::count() const
264 int QPieSeries::count() const
268 {
265 {
269 return m_slices.count();
266 return m_slices.count();
270 }
267 }
271
268
272 /*!
269 /*!
273 Returns a list of slices that belong to this series.
270 Returns a list of slices that belong to this series.
274 */
271 */
275 QList<QPieSlice*> QPieSeries::slices() const
272 QList<QPieSlice*> QPieSeries::slices() const
276 {
273 {
277 return m_slices;
274 return m_slices;
278 }
275 }
279
276
280 /*!
277 /*!
281 Sets the size \a factor of the pie. 1.0 is the default value.
278 Sets the size \a factor of the pie. 1.0 is the default value.
282 Note that the pie will not grow beyond its absolute maximum size.
279 Note that the pie will not grow beyond its absolute maximum size.
283 In practice its use is to make the pie appear smaller.
280 In practice its use is to make the pie appear smaller.
284 \sa sizeFactor()
281 \sa sizeFactor()
285 */
282 */
286 void QPieSeries::setSizeFactor(qreal factor)
283 void QPieSeries::setSizeFactor(qreal factor)
287 {
284 {
288 if (factor < 0.0)
285 if (factor < 0.0)
289 return;
286 return;
290
287
291 if (m_sizeFactor != factor) {
288 if (m_sizeFactor != factor) {
292 m_sizeFactor = factor;
289 m_sizeFactor = factor;
293 emit sizeFactorChanged();
290 emit sizeFactorChanged();
294 }
291 }
295 }
292 }
296
293
297 /*!
294 /*!
298 Gets the size factor of the pie.
295 Gets the size factor of the pie.
299 \sa setSizeFactor()
296 \sa setSizeFactor()
300 */
297 */
301 qreal QPieSeries::sizeFactor() const
298 qreal QPieSeries::sizeFactor() const
302 {
299 {
303 return m_sizeFactor;
300 return m_sizeFactor;
304 }
301 }
305
302
306 /*!
303 /*!
307 Sets the \a position of the pie within its bounding rectangle.
304 Sets the \a position of the pie within its bounding rectangle.
308 \sa PiePosition, position()
305 \sa PiePosition, position()
309 */
306 */
310 void QPieSeries::setPosition(PiePosition position)
307 void QPieSeries::setPosition(PiePosition position)
311 {
308 {
312 if (m_position != position) {
309 if (m_position != position) {
313 m_position = position;
310 m_position = position;
314 emit positionChanged();
311 emit positionChanged();
315 }
312 }
316 }
313 }
317
314
318 /*!
315 /*!
319 Gets the position of the pie within its bounding rectangle.
316 Gets the position of the pie within its bounding rectangle.
320 \sa PiePosition, setPosition()
317 \sa PiePosition, setPosition()
321 */
318 */
322 QPieSeries::PiePosition QPieSeries::position() const
319 QPieSeries::PiePosition QPieSeries::position() const
323 {
320 {
324 return m_position;
321 return m_position;
325 }
322 }
326
323
327
324
328 /*!
325 /*!
329 Sets the \a startAngle and \a angleSpan of this series.
326 Sets the \a startAngle and \a angleSpan of this series.
330
327
331 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
328 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
332 */
329 */
333 void QPieSeries::setSpan(qreal startAngle, qreal angleSpan)
330 void QPieSeries::setSpan(qreal startAngle, qreal angleSpan)
334 {
331 {
335 if (startAngle >= 0 && startAngle < 360 &&
332 if (startAngle >= 0 && startAngle < 360 &&
336 angleSpan > 0 && angleSpan <= 360) {
333 angleSpan > 0 && angleSpan <= 360) {
337 m_pieStartAngle = startAngle;
334 m_pieStartAngle = startAngle;
338 m_pieAngleSpan = angleSpan;
335 m_pieAngleSpan = angleSpan;
339 updateDerivativeData();
336 updateDerivativeData();
340 }
337 }
341 }
338 }
342
339
343 /*!
340 /*!
344 Sets the all the slice labels \a visible or invisible.
341 Sets the all the slice labels \a visible or invisible.
345
342
346 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
343 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
347 */
344 */
348 void QPieSeries::setLabelsVisible(bool visible)
345 void QPieSeries::setLabelsVisible(bool visible)
349 {
346 {
350 foreach (QPieSlice* s, m_slices)
347 foreach (QPieSlice* s, m_slices)
351 s->setLabelVisible(visible);
348 s->setLabelVisible(visible);
352 }
349 }
353
350
354 /*!
351 /*!
355 Convenience method for exploding a slice when user clicks the pie. Set \a enable to true to
352 Convenience method for exploding a slice when user clicks the pie. Set \a enable to true to
356 explode slices by clicking.
353 explode slices by clicking.
357
354
358 \sa QPieSlice::isExploded(), QPieSlice::setExploded(), QPieSlice::setExplodeDistance()
355 \sa QPieSlice::isExploded(), QPieSlice::setExploded(), QPieSlice::setExplodeDistance()
359 */
356 */
360 void QPieSeries::enableClickExplodes(bool enable)
357 void QPieSeries::enableClickExplodes(bool enable)
361 {
358 {
362 if (enable)
359 if (enable)
363 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
360 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
364 else
361 else
365 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
362 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
366 }
363 }
367
364
368 /*!
365 /*!
369 Convenience method for highlighting a slice when user hovers over the slice.
366 Convenience method for highlighting a slice when user hovers over the slice.
370 It changes the slice color to be lighter and shows the label of the slice.
367 It changes the slice color to be lighter and shows the label of the slice.
371 Set \a enable to true to highlight a slice when user hovers on top of it.
368 Set \a enable to true to highlight a slice when user hovers on top of it.
372
369
373 \sa QPieSlice::isExploded(), QPieSlice::setExploded()
370 \sa QPieSlice::isExploded(), QPieSlice::setExploded()
374 */
371 */
375
372
376 void QPieSeries::enableHoverHighlight(bool enable)
373 void QPieSeries::enableHoverHighlight(bool enable)
377 {
374 {
378 if (enable) {
375 if (enable) {
379 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
376 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
380 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
377 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
381 } else {
378 } else {
382 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
379 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
383 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
380 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
384 }
381 }
385 }
382 }
386
383
387 /*!
384 /*!
388 \fn void QPieSeries::changed(const QPieSeries::ChangeSet& changeSet)
385 \fn void QPieSeries::changed(const QPieSeries::ChangeSet& changeSet)
389
386
390 This signal emitted when something has changed in the series.
387 This signal emitted when something has changed in the series.
391 The \a changeSet contains the details of which slices have been added, changed or removed.
388 The \a changeSet contains the details of which slices have been added, changed or removed.
392
389
393 \sa QPieSeries::ChangeSet, QPieSlice::changed()
390 \sa QPieSeries::ChangeSet, QPieSlice::changed()
394 */
391 */
395
392
396 /*!
393 /*!
397 \fn void QPieSeries::clicked(QPieSlice* slice)
394 \fn void QPieSeries::clicked(QPieSlice* slice)
398
395
399 This signal is emitted when a \a slice has been clicked.
396 This signal is emitted when a \a slice has been clicked.
400
397
401 \sa QPieSlice::clicked()
398 \sa QPieSlice::clicked()
402 */
399 */
403
400
404 /*!
401 /*!
405 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
402 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
406
403
407 This signal is emitted when user has hovered over a \a slice.
404 This signal is emitted when user has hovered over a \a slice.
408
405
409 \sa QPieSlice::hoverEnter()
406 \sa QPieSlice::hoverEnter()
410 */
407 */
411
408
412 /*!
409 /*!
413 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
410 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
414
411
415 This signal is emitted when user has hovered away from a \a slice.
412 This signal is emitted when user has hovered away from a \a slice.
416
413
417 \sa QPieSlice::hoverLeave()
414 \sa QPieSlice::hoverLeave()
418 */
415 */
419
416
420 /*!
417 /*!
421 \fn void QPieSeries::sizeFactorChanged()
418 \fn void QPieSeries::sizeFactorChanged()
422
419
423 This signal is emitted when size factor has been changed.
420 This signal is emitted when size factor has been changed.
424
421
425 \sa sizeFactor(), setSizeFactor()
422 \sa sizeFactor(), setSizeFactor()
426 */
423 */
427
424
428 /*!
425 /*!
429 \fn void QPieSeries::positionChanged()
426 \fn void QPieSeries::positionChanged()
430
427
431 This signal is emitted when position of the pie has been changed.
428 This signal is emitted when position of the pie has been changed.
432
429
433 \sa position(), setPosition()
430 \sa position(), setPosition()
434 */
431 */
435
432
436 void QPieSeries::sliceChanged()
433 void QPieSeries::sliceChanged()
437 {
434 {
438 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
435 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
439 Q_ASSERT(m_slices.contains(slice));
436 Q_ASSERT(m_slices.contains(slice));
440
437
441 ChangeSet changeSet;
438 ChangeSet changeSet;
442 changeSet.appendChanged(slice);
439 changeSet.appendChanged(slice);
443 emit changed(changeSet);
440 emit changed(changeSet);
444
441
445 updateDerivativeData();
442 updateDerivativeData();
446 }
443 }
447
444
448 void QPieSeries::sliceClicked()
445 void QPieSeries::sliceClicked()
449 {
446 {
450 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
447 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
451 Q_ASSERT(m_slices.contains(slice));
448 Q_ASSERT(m_slices.contains(slice));
452 emit clicked(slice);
449 emit clicked(slice);
453 }
450 }
454
451
455 void QPieSeries::sliceHoverEnter()
452 void QPieSeries::sliceHoverEnter()
456 {
453 {
457 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
454 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
458 Q_ASSERT(m_slices.contains(slice));
455 Q_ASSERT(m_slices.contains(slice));
459 emit hoverEnter(slice);
456 emit hoverEnter(slice);
460 }
457 }
461
458
462 void QPieSeries::sliceHoverLeave()
459 void QPieSeries::sliceHoverLeave()
463 {
460 {
464 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
461 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
465 Q_ASSERT(m_slices.contains(slice));
462 Q_ASSERT(m_slices.contains(slice));
466 emit hoverLeave(slice);
463 emit hoverLeave(slice);
467 }
464 }
468
465
469 void QPieSeries::toggleExploded(QPieSlice* slice)
466 void QPieSeries::toggleExploded(QPieSlice* slice)
470 {
467 {
471 Q_ASSERT(slice);
468 Q_ASSERT(slice);
472 slice->setExploded(!slice->isExploded());
469 slice->setExploded(!slice->isExploded());
473 }
470 }
474
471
475 void QPieSeries::highlightOn(QPieSlice* slice)
472 void QPieSeries::highlightOn(QPieSlice* slice)
476 {
473 {
477 Q_ASSERT(slice);
474 Q_ASSERT(slice);
478 QColor c = slice->brush().color().lighter();
475 QColor c = slice->brush().color().lighter();
479 slice->setBrush(c);
476 slice->setBrush(c);
480 slice->setLabelVisible(true);
477 slice->setLabelVisible(true);
481 }
478 }
482
479
483 void QPieSeries::highlightOff(QPieSlice* slice)
480 void QPieSeries::highlightOff(QPieSlice* slice)
484 {
481 {
485 Q_ASSERT(slice);
482 Q_ASSERT(slice);
486 QColor c = slice->brush().color().darker(150);
483 QColor c = slice->brush().color().darker(150);
487 slice->setBrush(c);
484 slice->setBrush(c);
488 slice->setLabelVisible(false);
485 slice->setLabelVisible(false);
489 }
486 }
490
487
491 void QPieSeries::updateDerivativeData()
488 void QPieSeries::updateDerivativeData()
492 {
489 {
493 m_total = 0;
490 m_total = 0;
494
491
495 // nothing to do?
492 // nothing to do?
496 if (m_slices.count() == 0)
493 if (m_slices.count() == 0)
497 return;
494 return;
498
495
499 // calculate total
496 // calculate total
500 foreach (QPieSlice* s, m_slices)
497 foreach (QPieSlice* s, m_slices)
501 m_total += s->value();
498 m_total += s->value();
502
499
503 // we must have some values
500 // we must have some values
504 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
501 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
505
502
506 // update slice attributes
503 // update slice attributes
507 qreal sliceAngle = m_pieStartAngle;
504 qreal sliceAngle = m_pieStartAngle;
508 foreach (QPieSlice* s, m_slices) {
505 foreach (QPieSlice* s, m_slices) {
509
506
510 bool changed = false;
507 bool changed = false;
511
508
512 qreal percentage = s->value() / m_total;
509 qreal percentage = s->value() / m_total;
513 if (s->m_percentage != percentage) {
510 if (s->m_percentage != percentage) {
514 s->m_percentage = percentage;
511 s->m_percentage = percentage;
515 changed = true;
512 changed = true;
516 }
513 }
517
514
518 qreal sliceSpan = m_pieAngleSpan * percentage;
515 qreal sliceSpan = m_pieAngleSpan * percentage;
519 if (s->m_angleSpan != sliceSpan) {
516 if (s->m_angleSpan != sliceSpan) {
520 s->m_angleSpan = sliceSpan;
517 s->m_angleSpan = sliceSpan;
521 changed = true;
518 changed = true;
522 }
519 }
523
520
524 if (s->m_angle != sliceAngle) {
521 if (s->m_angle != sliceAngle) {
525 s->m_angle = sliceAngle;
522 s->m_angle = sliceAngle;
526 changed = true;
523 changed = true;
527 }
524 }
528 sliceAngle += sliceSpan;
525 sliceAngle += sliceSpan;
529
526
530 if (changed)
527 if (changed)
531 emit s->changed();
528 emit s->changed();
532 }
529 }
533 }
530 }
534
531
535 #include "moc_qpieseries.cpp"
532 #include "moc_qpieseries.cpp"
536
533
537 QTCOMMERCIALCHART_END_NAMESPACE
534 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now