##// END OF EJS Templates
Use signals from pieseries, visible hover and exploding slices
Jani Honkonen -
r157:036a0ec8efe0
parent child
Show More
@@ -1,33 +1,33
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <cmath>
3 #include <cmath>
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qchartview.h>
5 #include <qchartview.h>
6 #include <qpieseries.h>
6 #include <qpieseries.h>
7
7
8 QTCOMMERCIALCHART_USE_NAMESPACE
8 QTCOMMERCIALCHART_USE_NAMESPACE
9
9
10 int main(int argc, char *argv[])
10 int main(int argc, char *argv[])
11 {
11 {
12 QApplication a(argc, argv);
12 QApplication a(argc, argv);
13
13
14 // Create widget and scatter series
14 // Create widget and scatter series
15 QChartView *chartWidget = new QChartView();
15 QChartView *chartWidget = new QChartView();
16 QPieSeries *series = qobject_cast<QPieSeries *>(chartWidget->createSeries(QChartSeries::SeriesTypePie));
16 QPieSeries *series = qobject_cast<QPieSeries *>(chartWidget->createSeries(QChartSeries::SeriesTypePie));
17 Q_ASSERT(series);
17 Q_ASSERT(series);
18
18
19 // Add test data to the series
19 // Add test data to the series
20 series->add(QPieSlice(1, "test1", Qt::red));
20 series->add(QPieSlice(1, "test1", Qt::red, true));
21 series->add(QPieSlice(2, "test2", Qt::green));
21 series->add(QPieSlice(2, "test2", Qt::green));
22 series->add(QPieSlice(3, "test3", Qt::blue));
22 series->add(QPieSlice(3, "test3", Qt::blue));
23 series->add(QPieSlice(4, "test4", Qt::darkRed));
23 series->add(QPieSlice(4, "test4", Qt::darkRed, true));
24 series->add(QPieSlice(5, "test5", Qt::darkGreen));
24 series->add(QPieSlice(5, "test5", Qt::darkGreen));
25
25
26 // Use the chart widget as the central widget
26 // Use the chart widget as the central widget
27 QMainWindow w;
27 QMainWindow w;
28 w.resize(640, 480);
28 w.resize(640, 480);
29 w.setCentralWidget(chartWidget);
29 w.setCentralWidget(chartWidget);
30 w.show();
30 w.show();
31
31
32 return a.exec();
32 return a.exec();
33 }
33 }
@@ -1,272 +1,272
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 "barchartseries.h"
7 #include "barchartseries.h"
8 #include "stackedbarchartseries.h"
8 #include "stackedbarchartseries.h"
9 #include "percentbarchartseries.h"
9 #include "percentbarchartseries.h"
10 #include "qlinechartseries.h"
10 #include "qlinechartseries.h"
11 #include "qpieseries.h"
11 #include "qpieseries.h"
12 //items
12 //items
13 #include "axisitem_p.h"
13 #include "axisitem_p.h"
14 #include "bargroup.h"
14 #include "bargroup.h"
15 #include "stackedbargroup.h"
15 #include "stackedbargroup.h"
16 #include "linechartitem_p.h"
16 #include "linechartitem_p.h"
17 #include "percentbargroup.h"
17 #include "percentbargroup.h"
18 #include "linechartanimationitem_p.h"
18 #include "linechartanimationitem_p.h"
19 #include "piepresenter.h"
19 #include "piepresenter.h"
20
20
21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
22
22
23 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
23 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
24 m_chart(chart),
24 m_chart(chart),
25 m_dataset(dataset),
25 m_dataset(dataset),
26 m_chartTheme(0),
26 m_chartTheme(0),
27 m_domainIndex(0),
27 m_domainIndex(0),
28 m_marginSize(0),
28 m_marginSize(0),
29 m_axisX(new QChartAxis(this)),
29 m_axisX(new QChartAxis(this)),
30 m_axisY(new QChartAxis(this)),
30 m_axisY(new QChartAxis(this)),
31 m_rect(QRectF(QPoint(0,0),m_chart->size()))
31 m_rect(QRectF(QPoint(0,0),m_chart->size()))
32 {
32 {
33 setChartTheme(QChart::ChartThemeDefault);
33 setChartTheme(QChart::ChartThemeDefault);
34 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
34 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
35 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
35 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
36 createConnections();
36 createConnections();
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
47
48 QMapIterator<QChartAxis*,AxisItem*> i(m_axisItems);
48 QMapIterator<QChartAxis*,AxisItem*> i(m_axisItems);
49
49
50 while (i.hasNext()) {
50 while (i.hasNext()) {
51 i.next();
51 i.next();
52 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),i.value(),SLOT(handleGeometryChanged(const QRectF&)));
52 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),i.value(),SLOT(handleGeometryChanged(const QRectF&)));
53 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),i.value(),SLOT(handleDomainChanged(const Domain&)));
53 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),i.value(),SLOT(handleDomainChanged(const Domain&)));
54 }
54 }
55 }
55 }
56
56
57 void ChartPresenter::handleGeometryChanged()
57 void ChartPresenter::handleGeometryChanged()
58 {
58 {
59 m_rect = QRectF(QPoint(0,0),m_chart->size());
59 m_rect = QRectF(QPoint(0,0),m_chart->size());
60 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
60 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
61 Q_ASSERT(m_rect.isValid());
61 Q_ASSERT(m_rect.isValid());
62 emit geometryChanged(m_rect);
62 emit geometryChanged(m_rect);
63 }
63 }
64
64
65 int ChartPresenter::margin() const
65 int ChartPresenter::margin() const
66 {
66 {
67 return m_marginSize;
67 return m_marginSize;
68 }
68 }
69
69
70 void ChartPresenter::setMargin(int margin)
70 void ChartPresenter::setMargin(int margin)
71 {
71 {
72 m_marginSize = margin;
72 m_marginSize = margin;
73 }
73 }
74
74
75 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
75 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
76 {
76 {
77 switch(series->type())
77 switch(series->type())
78 {
78 {
79 case QChartSeries::SeriesTypeLine: {
79 case QChartSeries::SeriesTypeLine: {
80 QLineChartSeries* lineSeries = static_cast<QLineChartSeries*>(series);
80 QLineChartSeries* lineSeries = static_cast<QLineChartSeries*>(series);
81 LineChartItem* item = new LineChartAnimationItem(this,lineSeries,m_chart);
81 LineChartItem* item = new LineChartAnimationItem(this,lineSeries,m_chart);
82 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
82 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
83 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
83 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
84 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
84 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
85 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
85 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
86 m_chartItems.insert(series,item);
86 m_chartItems.insert(series,item);
87 break;
87 break;
88 }
88 }
89
89
90 case QChartSeries::SeriesTypeBar: {
90 case QChartSeries::SeriesTypeBar: {
91 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
91 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
92 BarGroup* item = new BarGroup(*barSeries,m_chart);
92 BarGroup* item = new BarGroup(*barSeries,m_chart);
93 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
93 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
94 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
94 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
95 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
95 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
96 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
96 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
97 m_chartItems.insert(series,item);
97 m_chartItems.insert(series,item);
98 // m_axisXItem->setVisible(false);
98 // m_axisXItem->setVisible(false);
99 break;
99 break;
100 }
100 }
101
101
102 case QChartSeries::SeriesTypeStackedBar: {
102 case QChartSeries::SeriesTypeStackedBar: {
103
103
104 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
104 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
105 StackedBarGroup* item = new StackedBarGroup(*stackedBarSeries,m_chart);
105 StackedBarGroup* item = new StackedBarGroup(*stackedBarSeries,m_chart);
106 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
106 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
107 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
107 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
108 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
108 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
109 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
109 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
110 m_chartItems.insert(series,item);
110 m_chartItems.insert(series,item);
111 break;
111 break;
112 }
112 }
113
113
114 case QChartSeries::SeriesTypePercentBar: {
114 case QChartSeries::SeriesTypePercentBar: {
115
115
116 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
116 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
117 PercentBarGroup* item = new PercentBarGroup(*percentBarSeries,m_chart);
117 PercentBarGroup* item = new PercentBarGroup(*percentBarSeries,m_chart);
118 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
118 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
119 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
119 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
120 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
120 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
121 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
121 QObject::connect(percentBarSeries,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::SeriesTypeScatter: {
126 case QChartSeries::SeriesTypeScatter: {
127 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
127 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
128 scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
128 scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
129 scatterSeries->d->setParentItem(this);
129 scatterSeries->d->setParentItem(this);
130 scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
130 scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
131 m_chartItems << scatterSeries->d;
131 m_chartItems << scatterSeries->d;
132 m_chartTheme->addObserver(scatterSeries->d);
132 m_chartTheme->addObserver(scatterSeries->d);
133
133
134 foreach (qreal x, scatterSeries->d->m_x) {
134 foreach (qreal x, scatterSeries->d->m_x) {
135 domain.m_minX = qMin(domain.m_minX, x);
135 domain.m_minX = qMin(domain.m_minX, x);
136 domain.m_maxX = qMax(domain.m_maxX, x);
136 domain.m_maxX = qMax(domain.m_maxX, x);
137 }
137 }
138 foreach (qreal y, scatterSeries->d->m_y) {
138 foreach (qreal y, scatterSeries->d->m_y) {
139 domain.m_minY = qMin(domain.m_minY, y);
139 domain.m_minY = qMin(domain.m_minY, y);
140 domain.m_maxY = qMax(domain.m_maxY, y);
140 domain.m_maxY = qMax(domain.m_maxY, y);
141 }
141 }
142
142
143 break;
143 break;
144 }
144 }
145 */
145 */
146
146
147 case QChartSeries::SeriesTypePie: {
147 case QChartSeries::SeriesTypePie: {
148 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
148 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
149 PiePresenter* pie = new PiePresenter(m_chart, pieSeries);
149 PiePresenter* pie = new PiePresenter(m_chart, pieSeries);
150 pieSeries->m_piePresenter = pie; // TODO: remove this pointer passing use signals&slots
150 QObject::connect(pieSeries, SIGNAL(changed(const PieChangeSet&)), pie, SLOT(handleSeriesChanged(const PieChangeSet&)));
151 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
151 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
152 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)), pie, SLOT(handleDomainChanged(const Domain&)));
152 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)), pie, SLOT(handleDomainChanged(const Domain&)));
153 m_chartItems.insert(series, pie);
153 m_chartItems.insert(series, pie);
154 break;
154 break;
155 }
155 }
156
156
157 default: {
157 default: {
158 qDebug()<< "Series type" << series->type() << "not implemented.";
158 qDebug()<< "Series type" << series->type() << "not implemented.";
159 break;
159 break;
160 }
160 }
161 }
161 }
162
162
163 if(m_rect.isValid()) emit geometryChanged(m_rect);
163 if(m_rect.isValid()) emit geometryChanged(m_rect);
164 }
164 }
165
165
166 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
166 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
167 {
167 {
168 //TODO:
168 //TODO:
169 }
169 }
170
170
171 void ChartPresenter::zoomInToRect(const QRectF& rect)
171 void ChartPresenter::zoomInToRect(const QRectF& rect)
172 {
172 {
173 if(!rect.isValid()) return;
173 if(!rect.isValid()) return;
174 QRectF r = rect.normalized();
174 QRectF r = rect.normalized();
175 r.translate(-m_marginSize, -m_marginSize);
175 r.translate(-m_marginSize, -m_marginSize);
176 Domain domain (m_dataset->domain().subDomain(r,m_rect.width(),m_rect.height()));
176 Domain domain (m_dataset->domain().subDomain(r,m_rect.width(),m_rect.height()));
177 m_dataset->addDomain(domain);
177 m_dataset->addDomain(domain);
178 }
178 }
179
179
180 void ChartPresenter::zoomIn()
180 void ChartPresenter::zoomIn()
181 {
181 {
182 if (!m_dataset->nextDomain()) {
182 if (!m_dataset->nextDomain()) {
183 QRectF rect = m_rect;
183 QRectF rect = m_rect;
184 rect.setWidth(rect.width()/2);
184 rect.setWidth(rect.width()/2);
185 rect.setHeight(rect.height()/2);
185 rect.setHeight(rect.height()/2);
186 rect.moveCenter(m_rect.center());
186 rect.moveCenter(m_rect.center());
187 Domain domain (m_dataset->domain().subDomain(rect,m_rect.width(),m_rect.height()));
187 Domain domain (m_dataset->domain().subDomain(rect,m_rect.width(),m_rect.height()));
188 m_dataset->addDomain(domain);
188 m_dataset->addDomain(domain);
189 }
189 }
190 }
190 }
191
191
192 void ChartPresenter::zoomOut()
192 void ChartPresenter::zoomOut()
193 {
193 {
194 m_dataset->previousDomain();
194 m_dataset->previousDomain();
195 }
195 }
196
196
197 void ChartPresenter::zoomReset()
197 void ChartPresenter::zoomReset()
198 {
198 {
199 m_dataset->clearDomains();
199 m_dataset->clearDomains();
200 }
200 }
201
201
202 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
202 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
203 {
203 {
204 delete m_chartTheme;
204 delete m_chartTheme;
205
205
206 m_chartTheme = ChartTheme::createTheme(theme);
206 m_chartTheme = ChartTheme::createTheme(theme);
207
207
208 m_chartTheme->decorate(m_chart);
208 m_chartTheme->decorate(m_chart);
209 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
209 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
210
210
211 int index=0;
211 int index=0;
212 while (i.hasNext()) {
212 while (i.hasNext()) {
213 i.next();
213 i.next();
214 index++;
214 index++;
215 m_chartTheme->decorate(i.value(),i.key(),index);
215 m_chartTheme->decorate(i.value(),i.key(),index);
216 }
216 }
217 }
217 }
218
218
219
219
220 QChart::ChartTheme ChartPresenter::chartTheme()
220 QChart::ChartTheme ChartPresenter::chartTheme()
221 {
221 {
222 return m_chartTheme->id();
222 return m_chartTheme->id();
223 }
223 }
224
224
225 QChartAxis* ChartPresenter::axisX()
225 QChartAxis* ChartPresenter::axisX()
226 {
226 {
227 return m_axisX;
227 return m_axisX;
228 }
228 }
229
229
230 QChartAxis* ChartPresenter::axisY()
230 QChartAxis* ChartPresenter::axisY()
231 {
231 {
232 return m_axisY;
232 return m_axisY;
233 }
233 }
234
234
235 QChartAxis* ChartPresenter::addAxisX()
235 QChartAxis* ChartPresenter::addAxisX()
236 {
236 {
237 //only one axis
237 //only one axis
238 if(m_axisX==0){
238 if(m_axisX==0){
239 m_axisX = new QChartAxis(this);
239 m_axisX = new QChartAxis(this);
240 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
240 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
241 }
241 }
242 return m_axisX;
242 return m_axisX;
243 }
243 }
244
244
245 QChartAxis* ChartPresenter::addAxisY()
245 QChartAxis* ChartPresenter::addAxisY()
246 {
246 {
247 if(m_axisY==0){
247 if(m_axisY==0){
248 m_axisY = new QChartAxis(this);
248 m_axisY = new QChartAxis(this);
249 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
249 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
250 return m_axisY;
250 return m_axisY;
251 }
251 }
252
252
253 QChartAxis* axis = new QChartAxis(this);
253 QChartAxis* axis = new QChartAxis(this);
254 m_axisItems[axis] = new AxisItem(axis,AxisItem::Y_AXIS,m_chart);
254 m_axisItems[axis] = new AxisItem(axis,AxisItem::Y_AXIS,m_chart);
255 return axis;
255 return axis;
256 }
256 }
257
257
258 void ChartPresenter::removeAxis(QChartAxis* axis)
258 void ChartPresenter::removeAxis(QChartAxis* axis)
259 {
259 {
260 AxisItem* item = m_axisItems.take(axis);
260 AxisItem* item = m_axisItems.take(axis);
261 if(item){
261 if(item){
262 delete item;
262 delete item;
263 delete axis;
263 delete axis;
264 }
264 }
265 //reset pointers to default ones
265 //reset pointers to default ones
266 if(axis == m_axisX) m_axisX=0;
266 if(axis == m_axisX) m_axisX=0;
267 else if(axis == m_axisY) m_axisY=0;
267 else if(axis == m_axisY) m_axisY=0;
268 }
268 }
269
269
270 #include "moc_chartpresenter_p.cpp"
270 #include "moc_chartpresenter_p.cpp"
271
271
272 QTCOMMERCIALCHART_END_NAMESPACE
272 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,112 +1,113
1
1
2 #include "piepresenter.h"
2 #include "piepresenter.h"
3 #include "pieslice.h"
3 #include "pieslice.h"
4 #include <QDebug>
4 #include <QDebug>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series) :
8 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series) :
9 ChartItem(parent),
9 ChartItem(parent),
10 m_pieSeries(series)
10 m_pieSeries(series)
11 {
11 {
12 Q_ASSERT(parent);
12 Q_ASSERT(parent);
13 Q_ASSERT(series);
13 Q_ASSERT(series);
14 m_rect = parentItem()->boundingRect();
14 m_rect = parentItem()->boundingRect();
15 setAcceptHoverEvents(true);
15 setAcceptHoverEvents(true);
16 }
16 }
17
17
18 PiePresenter::~PiePresenter()
18 PiePresenter::~PiePresenter()
19 {
19 {
20 while (m_slices.count())
20 while (m_slices.count())
21 delete m_slices.takeLast();
21 delete m_slices.takeLast();
22 }
22 }
23
23
24 void PiePresenter::seriesChanged()
24 void PiePresenter::handleSeriesChanged(const PieChangeSet& changeSet)
25 {
25 {
26 const qreal fullPie = 360;
26 const qreal fullPie = 360;
27 qreal total = 0;
27 qreal total = 0;
28
28
29 // calculate total
29 // calculate total
30 foreach (QPieSlice sliceData, m_pieSeries->slices())
30 foreach (QPieSlice sliceData, m_pieSeries->slices())
31 total += sliceData.m_value;
31 total += sliceData.m_value;
32
32
33 // TODO: no need to create new slices in case size changed; we should re-use the existing ones
33 // TODO: no need to create new slices in case size changed; we should re-use the existing ones
34 while (m_slices.count())
34 while (m_slices.count())
35 delete m_slices.takeLast();
35 delete m_slices.takeLast();
36
36
37 // create slices
37 // create slices
38 qreal angle = 0;
38 qreal angle = 0;
39 for (int i=0; i<m_pieSeries->count(); i++) {
39 for (int i=0; i<m_pieSeries->count(); i++) {
40 QPieSlice sliceData = m_pieSeries->slice(i);
40 QPieSlice sliceData = m_pieSeries->slice(i);
41 qreal span = sliceData.m_value / total * fullPie;
41 qreal span = sliceData.m_value / total * fullPie;
42 PieSlice *slice = new PieSlice(this, i, angle, span);
42 PieSlice *slice = new PieSlice(this, i, angle, span);
43 m_slices.append(slice);
43 m_slices.append(slice);
44 angle += span;
44 angle += span;
45 }
45 }
46
47 resize();
48 }
46 }
49
47
50 void PiePresenter::resize()
48 void PiePresenter::updateGeometry()
51 {
49 {
50 prepareGeometryChange();
51
52 m_pieRect = m_rect;
52 m_pieRect = m_rect;
53
53
54 if (m_pieRect.width() < m_pieRect.height()) {
54 if (m_pieRect.width() < m_pieRect.height()) {
55 m_pieRect.setWidth(m_pieRect.width() * m_pieSeries->m_sizeFactor);
55 m_pieRect.setWidth(m_pieRect.width() * m_pieSeries->sizeFactor());
56 m_pieRect.setHeight(m_pieRect.width());
56 m_pieRect.setHeight(m_pieRect.width());
57 m_pieRect.moveCenter(m_rect.center());
57 m_pieRect.moveCenter(m_rect.center());
58 } else {
58 } else {
59 m_pieRect.setHeight(m_pieRect.height() * m_pieSeries->m_sizeFactor);
59 m_pieRect.setHeight(m_pieRect.height() * m_pieSeries->sizeFactor());
60 m_pieRect.setWidth(m_pieRect.height());
60 m_pieRect.setWidth(m_pieRect.height());
61 m_pieRect.moveCenter(m_rect.center());
61 m_pieRect.moveCenter(m_rect.center());
62 }
62 }
63
63
64 switch (m_pieSeries->m_position) {
64 switch (m_pieSeries->position()) {
65 case QPieSeries::PiePositionTopLeft: {
65 case QPieSeries::PiePositionTopLeft: {
66 m_pieRect.setHeight(m_pieRect.height() / 2);
66 m_pieRect.setHeight(m_pieRect.height() / 2);
67 m_pieRect.setWidth(m_pieRect.height());
67 m_pieRect.setWidth(m_pieRect.height());
68 m_pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
68 m_pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
69 break;
69 break;
70 }
70 }
71 case QPieSeries::PiePositionTopRight: {
71 case QPieSeries::PiePositionTopRight: {
72 m_pieRect.setHeight(m_pieRect.height() / 2);
72 m_pieRect.setHeight(m_pieRect.height() / 2);
73 m_pieRect.setWidth(m_pieRect.height());
73 m_pieRect.setWidth(m_pieRect.height());
74 m_pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
74 m_pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
75 break;
75 break;
76 }
76 }
77 case QPieSeries::PiePositionBottomLeft: {
77 case QPieSeries::PiePositionBottomLeft: {
78 m_pieRect.setHeight(m_pieRect.height() / 2);
78 m_pieRect.setHeight(m_pieRect.height() / 2);
79 m_pieRect.setWidth(m_pieRect.height());
79 m_pieRect.setWidth(m_pieRect.height());
80 m_pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
80 m_pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
81 break;
81 break;
82 }
82 }
83 case QPieSeries::PiePositionBottomRight: {
83 case QPieSeries::PiePositionBottomRight: {
84 m_pieRect.setHeight(m_pieRect.height() / 2);
84 m_pieRect.setHeight(m_pieRect.height() / 2);
85 m_pieRect.setWidth(m_pieRect.height());
85 m_pieRect.setWidth(m_pieRect.height());
86 m_pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
86 m_pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
87 break;
87 break;
88 }
88 }
89 default:
89 default:
90 break;
90 break;
91 }
91 }
92
92
93 qDebug() << "presentation rect:" << m_rect;
93 qDebug() << "presentation rect:" << m_rect;
94 qDebug() << "pie rect:" << m_pieRect;
94 qDebug() << "pie rect:" << m_pieRect;
95 foreach (PieSlice *slice, m_slices)
96 slice->updateGeometry();
95 }
97 }
96
98
97 void PiePresenter::handleDomainChanged(const Domain& domain)
99 void PiePresenter::handleDomainChanged(const Domain& domain)
98 {
100 {
99 // TODO
101 // TODO
100 }
102 }
101
103
102 void PiePresenter::handleGeometryChanged(const QRectF& rect)
104 void PiePresenter::handleGeometryChanged(const QRectF& rect)
103 {
105 {
104 // TODO: allow user setting the size?
106 m_rect = rect;
105 // TODO: allow user defining the margins?
107 updateGeometry();
106 m_rect.setSize(rect.size());
108
107 resize();
108 }
109 }
109
110
110 #include "moc_piepresenter.cpp"
111 #include "moc_piepresenter.cpp"
111
112
112 QTCOMMERCIALCHART_END_NAMESPACE
113 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,43 +1,43
1 #ifndef PIEPRESENTER_H
1 #ifndef PIEPRESENTER_H
2 #define PIEPRESENTER_H
2 #define PIEPRESENTER_H
3
3
4 #include "chartitem_p.h"
4 #include "chartitem_p.h"
5 #include "qpieseries.h"
5 #include "qpieseries.h"
6
6
7 class QGraphicsItem;
7 class QGraphicsItem;
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 class PieSlice;
9 class PieSlice;
10
10
11 class PiePresenter : public QObject, public ChartItem
11 class PiePresenter : public QObject, public ChartItem
12 {
12 {
13 Q_OBJECT
13 Q_OBJECT
14
14
15 public:
15 public:
16 // TODO: use a generic data class instead of x and y
16 // TODO: use a generic data class instead of x and y
17 PiePresenter(QGraphicsItem *parent, QPieSeries *series);
17 PiePresenter(QGraphicsItem *parent, QPieSeries *series);
18 ~PiePresenter();
18 ~PiePresenter();
19
19
20 public: // from ChartItem
20 public: // from QGraphicsItem
21 QRectF boundingRect() const { return m_rect; }
21 QRectF boundingRect() const { return m_rect; }
22 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
22 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
23
23
24 public:
24 public:
25 void seriesChanged();
25 void updateGeometry();
26 void resize();
27 QRectF pieRect() const { return m_pieRect; }
26 QRectF pieRect() const { return m_pieRect; }
28
27
29 public Q_SLOTS:
28 public Q_SLOTS:
29 void handleSeriesChanged(const PieChangeSet& changeSet);
30 void handleDomainChanged(const Domain& domain);
30 void handleDomainChanged(const Domain& domain);
31 void handleGeometryChanged(const QRectF& rect);
31 void handleGeometryChanged(const QRectF& rect);
32
32
33 private:
33 private:
34 friend class PieSlice;
34 friend class PieSlice;
35 QList<PieSlice*> m_slices;
35 QList<PieSlice*> m_slices;
36 QPieSeries *m_pieSeries;
36 QPieSeries *m_pieSeries;
37 QRectF m_rect;
37 QRectF m_rect;
38 QRectF m_pieRect;
38 QRectF m_pieRect;
39 };
39 };
40
40
41 QTCOMMERCIALCHART_END_NAMESPACE
41 QTCOMMERCIALCHART_END_NAMESPACE
42
42
43 #endif // PIEPRESENTER_H
43 #endif // PIEPRESENTER_H
@@ -1,91 +1,124
1 #include "pieslice.h"
1 #include "pieslice.h"
2 #include "piepresenter.h"
2 #include "piepresenter.h"
3 #include "qpieseries.h"
3 #include <QPainter>
4 #include <QPainter>
4 #include <QDebug>
5 #include <QDebug>
6 #include <qmath.h>
5
7
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
9
8 PieSlice::PieSlice(PiePresenter *piePresentation, int seriesIndex, qreal startAngle, qreal span)
10 #define PI 3.14159265
9 :QGraphicsItem(piePresentation),
11 #define EXPLODE_OFFSET 20
12
13 QPointF offset(qreal angle, qreal length)
14 {
15 qreal dx = qSin(angle*(PI/180)) * length;
16 qreal dy = qCos(angle*(PI/180)) * length;
17 return QPointF(dx, -dy);
18 }
19
20 PieSlice::PieSlice(PiePresenter *presenter, int seriesIndex, qreal startAngle, qreal span)
21 :QGraphicsItem(presenter),
22 m_label(new QGraphicsTextItem(this)),
10 m_seriesIndex(seriesIndex),
23 m_seriesIndex(seriesIndex),
11 m_startAngle(startAngle),
24 m_startAngle(startAngle),
12 m_span(span)
25 m_span(span)
13 {
26 {
14 Q_ASSERT(piePresentation);
27 Q_ASSERT(presenter);
15 setAcceptHoverEvents(true);
28 setAcceptHoverEvents(true);
16 setAcceptedMouseButtons(Qt::LeftButton);
29 setAcceptedMouseButtons(Qt::LeftButton);
30 updateGeometry();
31
32 // TODO: use themes
33 m_pen = QPen(Qt::black);
34 m_brush = QBrush(sliceData().m_color);
17 }
35 }
18
36
19 PieSlice::~PieSlice()
37 PieSlice::~PieSlice()
20 {
38 {
21 }
39 }
22
40
23 QRectF PieSlice::boundingRect() const
41 QRectF PieSlice::boundingRect() const
24 {
42 {
25 return shape().boundingRect();
43 return m_rect;
26 }
44 }
27
45
28 QPainterPath PieSlice::shape() const
46 QPainterPath PieSlice::shape() const
29 {
47 {
30 QRectF rect = (static_cast<PiePresenter*>(parentItem()))->pieRect();
48 return m_path;
31 qreal angle = (-m_startAngle) + (90);
32 qreal span = -m_span;
33
34 QPainterPath path;
35 path.moveTo(rect.center());
36 path.arcTo(rect, angle, span);
37
38 // TODO: draw the shape so that it might have a hole in the center
39 // - Sin & Cos will be needed to find inner/outer arc endpoints
40
41 // dx, dy are offsets from the center
42 //qreal l = boundingRect().height();
43 //qreal dx = qSin(angle*(M_PI/180)) * l;
44 //qreal dy = qCos(angle*(M_PI/180)) * l;
45
46 // TODO: exploded slice?
47
48 return path;
49 }
49 }
50
50
51 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
51 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
52 {
52 {
53 painter->setRenderHint(QPainter::Antialiasing);
53 painter->setRenderHint(QPainter::Antialiasing);
54 // TODO: how to map theme settings to a pie slice? Now we
55 //painter->setPen(m_theme.linePen);
56 // TODO:
57
58 QPieSlice data = (static_cast<PiePresenter*>(parentItem()))->m_pieSeries->slice(m_seriesIndex);
59 painter->setBrush(data.m_color);
60
61
54
62 //painter->setBrush(m_theme.linePen.color());
55 // TODO: themes
63
56 painter->setPen(m_pen);
64 // From Qt docs:
57 painter->setBrush(m_brush);
65 // The startAngle and spanAngle must be specified in 1/16th of a degree, i.e. a full circle equals 5760 (16 * 360).
58 painter->drawPath(m_path);
66 // Positive values for the angles mean counter-clockwise while negative values mean the clockwise direction.
67 // Zero degrees is at the 3 o'clock position.
68 //
69 // For sake of simplicity convert this so that zero degrees is at 12 o'clock and full circle is 360.
70 //qreal angle = (-m_startAngle*16) + (90*16);
71 //qreal span = -m_span*16;
72 //painter->drawPie(boundingRect(), angle, span);
73
74 painter->drawPath(shape());
75
59
76 // Draw the label
60 // Draw the label
77 // TODO: do this better
61 // TODO: do this better
78 painter->drawText(boundingRect().center(), data.m_label);
62 //QTextItem text;
63 painter->drawText(m_center, sliceData().m_label);
79 }
64 }
80
65
81 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
66 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
82 {
67 {
83 QGraphicsItem::hoverEnterEvent(event);
68 QGraphicsItem::hoverEnterEvent(event);
84 qDebug() << "hover" << m_seriesIndex << m_startAngle << m_span;
69 m_brush = QBrush(sliceData().m_color.lighter());
70 update();
71 }
72
73 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
74 {
75 QGraphicsItem::hoverLeaveEvent(event);
76 m_brush = QBrush(sliceData().m_color);
77 update();
85 }
78 }
86
79
87 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent *event)
80 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent *event)
88 {
81 {
89 QGraphicsItem::mousePressEvent(event);
82 QGraphicsItem::mousePressEvent(event);
83 QPieSlice data = sliceData();
84 data.m_isExploded = !data.m_isExploded;
85 (static_cast<PiePresenter*>(parentItem()))->m_pieSeries->update(m_seriesIndex, data);
90 }
86 }
87
88 void PieSlice::updateGeometry()
89 {
90 prepareGeometryChange();
91
92 PiePresenter *presenter = static_cast<PiePresenter*>(parentItem());
93 QRectF rect = presenter->pieRect();
94 rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET);
95
96 qreal centerAngle = m_startAngle + (m_span/2);
97
98 if (presenter->m_pieSeries->slice(m_seriesIndex).m_isExploded) {
99 QPointF d = offset((centerAngle), EXPLODE_OFFSET);
100 rect.translate(d.x(), d.y());
101 }
102
103 qreal angle = (-m_startAngle) + (90);
104 qreal span = -m_span;
105
106 QPainterPath path;
107 path.moveTo(rect.center());
108 path.arcTo(rect, angle, span);
109
110 // TODO: draw the shape so that it might have a hole in the center
111
112 m_path = path;
113 m_rect = path.boundingRect();
114
115 qreal radius = rect.height() / 2;
116 m_center = rect.center() + offset(centerAngle, radius / 2);
117 }
118
119 QPieSlice PieSlice::sliceData()
120 {
121 return (static_cast<PiePresenter*>(parentItem()))->m_pieSeries->slice(m_seriesIndex);
122 }
123
91 QTCOMMERCIALCHART_END_NAMESPACE
124 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,36 +1,49
1 #ifndef PIESLICE_H
1 #ifndef PIESLICE_H
2 #define PIESLICE_H
2 #define PIESLICE_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 #include "qpieseries.h"
6 #include <QGraphicsItem>
7 #include <QGraphicsItem>
7 #include <QRectF>
8 #include <QRectF>
8 #include <QColor>
9 #include <QColor>
10 #include <QPen>
9
11
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 class PiePresenter;
13 class PiePresenter;
12
14
13 class PieSlice : public QGraphicsItem
15 class PieSlice : public QGraphicsItem
14 {
16 {
15 public:
17 public:
16 PieSlice(PiePresenter *piePresentation, int seriesIndex, qreal startAngle, qreal span);
18 PieSlice(PiePresenter *piePresenter, int seriesIndex, qreal startAngle, qreal span);
17 ~PieSlice();
19 ~PieSlice();
18
20
19 public: // from QGraphicsItem
21 public: // from QGraphicsItem
20 QRectF boundingRect() const;
22 QRectF boundingRect() const;
21 QPainterPath shape() const;
23 QPainterPath shape() const;
22 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
23 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
25 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
26 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
24 void mousePressEvent(QGraphicsSceneMouseEvent *event);
27 void mousePressEvent(QGraphicsSceneMouseEvent *event);
25
28
29 public:
30 void updateGeometry();
31
32 private:
33 QPieSlice sliceData();
34
26 private:
35 private:
36 QGraphicsTextItem* m_label;
27 int m_seriesIndex;
37 int m_seriesIndex;
28 qreal m_startAngle;
38 qreal m_startAngle;
29 qreal m_span;
39 qreal m_span;
40 QPainterPath m_path;
30 QRectF m_rect;
41 QRectF m_rect;
31 //SeriesTheme m_theme;
42 QPointF m_center;
43 QPen m_pen;
44 QBrush m_brush;
32 };
45 };
33
46
34 QTCOMMERCIALCHART_END_NAMESPACE
47 QTCOMMERCIALCHART_END_NAMESPACE
35
48
36 #endif // PIESLICE_H
49 #endif // PIESLICE_H
@@ -1,93 +1,87
1 #include "qpieseries.h"
1 #include "qpieseries.h"
2 #include "piepresenter.h"
2 #include "piepresenter.h"
3 #include "pieslice.h"
3 #include "pieslice.h"
4 #include <QDebug>
4 #include <QDebug>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 QPieSeries::QPieSeries(QObject *parent) :
8 QPieSeries::QPieSeries(QObject *parent) :
9 QChartSeries(parent),
9 QChartSeries(parent),
10 m_piePresenter(0),
11 m_sizeFactor(1.0),
10 m_sizeFactor(1.0),
12 m_position(PiePositionMaximized)
11 m_position(PiePositionMaximized)
13 {
12 {
14 }
13 }
15
14
16 QPieSeries::~QPieSeries()
15 QPieSeries::~QPieSeries()
17 {
16 {
18
17
19 }
18 }
20
19
21 void QPieSeries::set(QList<QPieSlice> slices)
20 void QPieSeries::set(QList<QPieSlice> slices)
22 {
21 {
23 m_slices = slices;
22 PieChangeSet changeSet;
24 if (m_piePresenter) {
23
25 m_piePresenter->seriesChanged();
24 for (int i=slices.count(); i<m_slices.count(); i++)
26 m_piePresenter->update();
25 changeSet.m_removed << i;
26
27 for (int i=0; i<slices.count(); i++) {
28 if (i < m_slices.count())
29 changeSet.m_changed << i;
30 else
31 changeSet.m_added << i;
27 }
32 }
33
34 m_slices = slices;
35 emit changed(changeSet);
28 }
36 }
29
37
30 void QPieSeries::add(QList<QPieSlice> slices)
38 void QPieSeries::add(QList<QPieSlice> slices)
31 {
39 {
40 PieChangeSet changeSet;
41 for (int i=0; i<slices.count(); i++)
42 changeSet.m_added << m_slices.count() + i;
43
32 m_slices += slices;
44 m_slices += slices;
33 if (m_piePresenter) {
45 emit changed(changeSet);
34 m_piePresenter->seriesChanged();
35 // TODO: m_piePresenter->seriesAppended()??
36 m_piePresenter->update();
37 }
38 }
46 }
39
47
40 void QPieSeries::add(QPieSlice slice)
48 void QPieSeries::add(QPieSlice slice)
41 {
49 {
42 add(QList<QPieSlice>() << slice);
50 add(QList<QPieSlice>() << slice);
43 }
51 }
44
52
45 QPieSlice QPieSeries::slice(int index) const
53 QPieSlice QPieSeries::slice(int index) const
46 {
54 {
47 if ((index >= 0) && (index < m_slices.count()))
55 if ((index >= 0) && (index < m_slices.count()))
48 return m_slices.at(index);
56 return m_slices.at(index);
49 return QPieSlice();
57 return QPieSlice();
50 }
58 }
51
59
52 bool QPieSeries::update(int index, QPieSlice slice)
60 bool QPieSeries::update(int index, QPieSlice slice)
53 {
61 {
54 if ((index >= 0) && (index < m_slices.count())) {
62 if ((index >= 0) && (index < m_slices.count())) {
55 m_slices[index] = slice;
63 m_slices[index] = slice;
56 if (m_piePresenter) {
64 PieChangeSet changeSet;
57 m_piePresenter->seriesChanged();
65 changeSet.m_changed << index;
58 // TODO: for a nice animation we need something like
66 emit changed(changeSet);
59 // m_piePresenter->sliceChanged(index, oldslice, newslice)
60 m_piePresenter->update();
61 }
62 return true;
67 return true;
63 }
68 }
64 return false;
69 return false;
65 }
70 }
66
71
67 void QPieSeries::setSizeFactor(qreal factor)
72 void QPieSeries::setSizeFactor(qreal factor)
68 {
73 {
69 if (factor > 0.0)
74 if (factor > 0.0)
70 m_sizeFactor = factor;
75 m_sizeFactor = factor;
71
76 emit sizeFactorChanged();
72 if (m_piePresenter) {
73 m_piePresenter->resize();
74 m_piePresenter->update();
75 // TODO: do we have to update the parent item also?
76 // - potential issue: what if this function is called from the parent context?
77 }
78 }
77 }
79
78
80 void QPieSeries::setPosition(PiePosition position)
79 void QPieSeries::setPosition(PiePosition position)
81 {
80 {
82 m_position = position;
81 m_position = position;
83 if (m_piePresenter) {
82 emit positionChanged();
84 m_piePresenter->resize();
85 m_piePresenter->update();
86 // TODO: do we have to update the parent item also?
87 // - potential issue: what if this function is called from the parent context?
88 }
89 }
83 }
90
84
91 #include "moc_qpieseries.cpp"
85 #include "moc_qpieseries.cpp"
92
86
93 QTCOMMERCIALCHART_END_NAMESPACE
87 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,95
1 #ifndef PIESERIES_H
1 #ifndef PIESERIES_H
2 #define PIESERIES_H
2 #define PIESERIES_H
3
3
4 #include "qchartseries.h"
4 #include "qchartseries.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QRectF>
6 #include <QRectF>
7 #include <QColor>
7 #include <QColor>
8
8
9 class QGraphicsObject;
9 class QGraphicsObject;
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 class PiePresenter;
11 class PiePresenter;
12 class PieSlice;
12 class PieSlice;
13
13
14 class QPieSlice
14 class QPieSlice
15 {
15 {
16 public:
16 public:
17 QPieSlice()
17 QPieSlice()
18 :m_value(0), m_label("<empty>"), m_color(Qt::white), m_isExploded(false) {}
18 :m_value(0), m_label("<empty>"), m_color(Qt::white), m_isExploded(false) {}
19
19
20 QPieSlice(qreal value, QString label, QColor color, bool exploded = false)
20 QPieSlice(qreal value, QString label, QColor color, bool exploded = false)
21 :m_value(value), m_label(label), m_color(color), m_isExploded(exploded) {}
21 :m_value(value), m_label(label), m_color(color), m_isExploded(exploded) {}
22 public:
22 public:
23 qreal m_value;
23 qreal m_value;
24 QString m_label;
24 QString m_label;
25 QColor m_color;
25 QColor m_color;
26 bool m_isExploded;
26 bool m_isExploded;
27 };
27 };
28
28
29 class PieChangeSet
30 {
31 public:
32 QList<int> m_added;
33 QList<int> m_removed;
34 QList<int> m_changed;
35 };
36
29 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries
37 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries
30 {
38 {
31 Q_OBJECT
39 Q_OBJECT
32
40
33 public:
41 public:
34 enum PiePosition {
42 enum PiePosition {
35 PiePositionMaximized = 0,
43 PiePositionMaximized = 0,
36 PiePositionTopLeft,
44 PiePositionTopLeft,
37 PiePositionTopRight,
45 PiePositionTopRight,
38 PiePositionBottomLeft,
46 PiePositionBottomLeft,
39 PiePositionBottomRight
47 PiePositionBottomRight
40 };
48 };
41
49
42 public:
50 public:
43 QPieSeries(QObject *parent = 0);
51 QPieSeries(QObject *parent = 0);
44 ~QPieSeries();
52 ~QPieSeries();
45
53
46 public: // from QChartSeries
54 public: // from QChartSeries
47 QChartSeriesType type() const { return QChartSeries::SeriesTypePie; }
55 QChartSeriesType type() const { return QChartSeries::SeriesTypePie; }
48
56
49 public:
57 public:
50 void set(QList<QPieSlice> slices);
58 void set(QList<QPieSlice> slices);
51 void add(QList<QPieSlice> slices);
59 void add(QList<QPieSlice> slices);
52 void add(QPieSlice slice);
60 void add(QPieSlice slice);
53
61
54 int count() const { return m_slices.count(); }
62 int count() const { return m_slices.count(); }
55
63
56 QList<QPieSlice> slices() const { return m_slices; }
64 QList<QPieSlice> slices() const { return m_slices; }
57 QPieSlice slice(int index) const;
65 QPieSlice slice(int index) const;
58 bool update(int index, QPieSlice slice);
66 bool update(int index, QPieSlice slice);
59
67
60 // TODO: convenience functions
68 // TODO: convenience functions
61 //void updateValue(int sliceIndex, qreal value);
69 //void updateValue(int sliceIndex, qreal value);
62 //void updateLabel(int sliceIndex, QString label);
70 //void updateLabel(int sliceIndex, QString label);
63 //void updateColor(int sliceIndex, QColor color);
71 //void updateColor(int sliceIndex, QColor color);
64 //void updateExploded(int slizeIndex, bool exploded);
72 //void updateExploded(int slizeIndex, bool exploded);
65
73
66 void setSizeFactor(qreal sizeFactor);
74 void setSizeFactor(qreal sizeFactor);
67 qreal sizeFactor() const { return m_sizeFactor; }
75 qreal sizeFactor() const { return m_sizeFactor; }
68
76
69 void setPosition(PiePosition position);
77 void setPosition(PiePosition position);
70 PiePosition position() const { return m_position; }
78 PiePosition position() const { return m_position; }
71
79
80 Q_SIGNALS:
81 void changed(const PieChangeSet& changeSet);
82 void sizeFactorChanged();
83 void positionChanged();
84
72 private:
85 private:
73 Q_DISABLE_COPY(QPieSeries)
86 Q_DISABLE_COPY(QPieSeries)
74 // TODO: use PIML
87 // TODO: use PIML
75 friend class ChartPresenter;
76 friend class ChartDataSet;
77 friend class PiePresenter;
78 PiePresenter *m_piePresenter;
79 QList<QPieSlice> m_slices;
88 QList<QPieSlice> m_slices;
80 qreal m_sizeFactor;
89 qreal m_sizeFactor;
81 PiePosition m_position;
90 PiePosition m_position;
82 };
91 };
83
92
84 QTCOMMERCIALCHART_END_NAMESPACE
93 QTCOMMERCIALCHART_END_NAMESPACE
85
94
86 #endif // PIESERIES_H
95 #endif // PIESERIES_H
General Comments 0
You need to be logged in to leave comments. Login now