##// END OF EJS Templates
Rename piepresenter -> piechartitem
Jani Honkonen -
r568:9b365faaa041
parent child
Show More
@@ -1,401 +1,401
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 #include "chartanimator_p.h"
6 #include "chartanimator_p.h"
7 //series
7 //series
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 "qareaseries.h"
12 #include "qareaseries.h"
13 #include "qpieseries.h"
13 #include "qpieseries.h"
14 #include "qscatterseries.h"
14 #include "qscatterseries.h"
15 #include "qsplineseries.h"
15 #include "qsplineseries.h"
16 //items
16 //items
17 #include "axisitem_p.h"
17 #include "axisitem_p.h"
18 #include "areachartitem_p.h"
18 #include "areachartitem_p.h"
19 #include "barpresenter_p.h"
19 #include "barpresenter_p.h"
20 #include "stackedbarpresenter_p.h"
20 #include "stackedbarpresenter_p.h"
21 #include "percentbarpresenter_p.h"
21 #include "percentbarpresenter_p.h"
22 #include "linechartitem_p.h"
22 #include "linechartitem_p.h"
23 #include "piepresenter_p.h"
23 #include "piechartitem_p.h"
24 #include "scatterchartitem_p.h"
24 #include "scatterchartitem_p.h"
25 #include "splinechartitem_p.h"
25 #include "splinechartitem_p.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
29 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 m_chart(chart),
30 m_chart(chart),
31 m_animator(0),
31 m_animator(0),
32 m_dataset(dataset),
32 m_dataset(dataset),
33 m_chartTheme(0),
33 m_chartTheme(0),
34 m_zoomIndex(0),
34 m_zoomIndex(0),
35 m_marginSize(0),
35 m_marginSize(0),
36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
37 m_options(QChart::NoAnimation)
37 m_options(QChart::NoAnimation)
38 {
38 {
39 createConnections();
39 createConnections();
40 setChartTheme(QChart::ChartThemeDefault);
40 setChartTheme(QChart::ChartThemeDefault);
41 }
41 }
42
42
43 ChartPresenter::~ChartPresenter()
43 ChartPresenter::~ChartPresenter()
44 {
44 {
45 delete m_chartTheme;
45 delete m_chartTheme;
46 }
46 }
47
47
48 void ChartPresenter::createConnections()
48 void ChartPresenter::createConnections()
49 {
49 {
50 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
50 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
51 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
51 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
52 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
52 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
53 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
53 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
54 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
54 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
55 }
55 }
56
56
57
57
58 QRectF ChartPresenter::geometry() const
58 QRectF ChartPresenter::geometry() const
59 {
59 {
60 return m_rect;
60 return m_rect;
61 }
61 }
62
62
63 void ChartPresenter::handleGeometryChanged()
63 void ChartPresenter::handleGeometryChanged()
64 {
64 {
65 QRectF rect(QPoint(0,0),m_chart->size());
65 QRectF rect(QPoint(0,0),m_chart->size());
66 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
66 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
67
67
68 //rewrite zoom stack
68 //rewrite zoom stack
69 for(int i=0;i<m_zoomStack.count();i++){
69 for(int i=0;i<m_zoomStack.count();i++){
70 QRectF r = m_zoomStack[i];
70 QRectF r = m_zoomStack[i];
71 qreal w = rect.width()/m_rect.width();
71 qreal w = rect.width()/m_rect.width();
72 qreal h = rect.height()/m_rect.height();
72 qreal h = rect.height()/m_rect.height();
73 QPointF tl = r.topLeft();
73 QPointF tl = r.topLeft();
74 tl.setX(tl.x()*w);
74 tl.setX(tl.x()*w);
75 tl.setY(tl.y()*h);
75 tl.setY(tl.y()*h);
76 QPointF br = r.bottomRight();
76 QPointF br = r.bottomRight();
77 br.setX(br.x()*w);
77 br.setX(br.x()*w);
78 br.setY(br.y()*h);
78 br.setY(br.y()*h);
79 r.setTopLeft(tl);
79 r.setTopLeft(tl);
80 r.setBottomRight(br);
80 r.setBottomRight(br);
81 m_zoomStack[i]=r;
81 m_zoomStack[i]=r;
82 }
82 }
83
83
84 m_rect = rect;
84 m_rect = rect;
85 Q_ASSERT(m_rect.isValid());
85 Q_ASSERT(m_rect.isValid());
86 emit geometryChanged(m_rect);
86 emit geometryChanged(m_rect);
87 }
87 }
88
88
89 int ChartPresenter::margin() const
89 int ChartPresenter::margin() const
90 {
90 {
91 return m_marginSize;
91 return m_marginSize;
92 }
92 }
93
93
94 void ChartPresenter::setMargin(int margin)
94 void ChartPresenter::setMargin(int margin)
95 {
95 {
96 m_marginSize = margin;
96 m_marginSize = margin;
97 }
97 }
98
98
99 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
99 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
100 {
100 {
101 AxisItem* item = new AxisItem(axis,this,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
101 AxisItem* item = new AxisItem(axis,this,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
102
102
103 if(m_options.testFlag(QChart::GridAxisAnimations)){
103 if(m_options.testFlag(QChart::GridAxisAnimations)){
104 m_animator->addAnimation(item);
104 m_animator->addAnimation(item);
105 }
105 }
106
106
107 if(axis==m_dataset->axisX()){
107 if(axis==m_dataset->axisX()){
108 m_chartTheme->decorate(axis,true);
108 m_chartTheme->decorate(axis,true);
109 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
109 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
110 //initialize
110 //initialize
111 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
111 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
112
112
113 }
113 }
114 else{
114 else{
115 m_chartTheme->decorate(axis,false);
115 m_chartTheme->decorate(axis,false);
116 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
116 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
117 //initialize
117 //initialize
118 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
118 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
119 }
119 }
120
120
121 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
122 //initialize
122 //initialize
123 item->handleGeometryChanged(m_rect);
123 item->handleGeometryChanged(m_rect);
124 m_axisItems.insert(axis, item);
124 m_axisItems.insert(axis, item);
125 }
125 }
126
126
127 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
127 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
128 {
128 {
129 AxisItem* item = m_axisItems.take(axis);
129 AxisItem* item = m_axisItems.take(axis);
130 Q_ASSERT(item);
130 Q_ASSERT(item);
131 if(m_animator) m_animator->removeAnimation(item);
131 if(m_animator) m_animator->removeAnimation(item);
132 delete item;
132 delete item;
133 }
133 }
134
134
135
135
136 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
136 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
137 {
137 {
138 ChartItem *item = 0 ;
138 ChartItem *item = 0 ;
139
139
140 switch(series->type())
140 switch(series->type())
141 {
141 {
142 case QSeries::SeriesTypeLine: {
142 case QSeries::SeriesTypeLine: {
143
143
144 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
144 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
145 LineChartItem* line = new LineChartItem(lineSeries,m_chart);
145 LineChartItem* line = new LineChartItem(lineSeries,m_chart);
146 if(m_options.testFlag(QChart::SeriesAnimations)) {
146 if(m_options.testFlag(QChart::SeriesAnimations)) {
147 m_animator->addAnimation(line);
147 m_animator->addAnimation(line);
148 }
148 }
149 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series));
149 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series));
150 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
150 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
151 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
151 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
152 item = line;
152 item = line;
153 break;
153 break;
154 }
154 }
155
155
156 case QSeries::SeriesTypeArea: {
156 case QSeries::SeriesTypeArea: {
157
157
158 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
158 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
159 AreaChartItem* area = new AreaChartItem(areaSeries,m_chart);
159 AreaChartItem* area = new AreaChartItem(areaSeries,m_chart);
160 if(m_options.testFlag(QChart::SeriesAnimations)) {
160 if(m_options.testFlag(QChart::SeriesAnimations)) {
161 m_animator->addAnimation(area->upperLineItem());
161 m_animator->addAnimation(area->upperLineItem());
162 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
162 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
163 }
163 }
164 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series));
164 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series));
165 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
165 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
166 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
166 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
167 item=area;
167 item=area;
168 break;
168 break;
169 }
169 }
170
170
171 case QSeries::SeriesTypeBar: {
171 case QSeries::SeriesTypeBar: {
172 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
172 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
173 BarPresenter* bar = new BarPresenter(barSeries,m_chart);
173 BarPresenter* bar = new BarPresenter(barSeries,m_chart);
174 if(m_options.testFlag(QChart::SeriesAnimations)) {
174 if(m_options.testFlag(QChart::SeriesAnimations)) {
175 // m_animator->addAnimation(bar);
175 // m_animator->addAnimation(bar);
176 }
176 }
177 m_chartTheme->decorate(bar, barSeries, m_dataset->seriesIndex(barSeries));
177 m_chartTheme->decorate(bar, barSeries, m_dataset->seriesIndex(barSeries));
178 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
178 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
179 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
179 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
180 item=bar;
180 item=bar;
181 break;
181 break;
182 }
182 }
183
183
184 case QSeries::SeriesTypeStackedBar: {
184 case QSeries::SeriesTypeStackedBar: {
185 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
185 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
186 StackedBarPresenter* bar = new StackedBarPresenter(stackedBarSeries,m_chart);
186 StackedBarPresenter* bar = new StackedBarPresenter(stackedBarSeries,m_chart);
187 if(m_options.testFlag(QChart::SeriesAnimations)) {
187 if(m_options.testFlag(QChart::SeriesAnimations)) {
188 // m_animator->addAnimation(bar);
188 // m_animator->addAnimation(bar);
189 }
189 }
190 m_chartTheme->decorate(bar, stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries));
190 m_chartTheme->decorate(bar, stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries));
191 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
191 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
192 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
192 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
193 item=bar;
193 item=bar;
194 break;
194 break;
195 }
195 }
196
196
197 case QSeries::SeriesTypePercentBar: {
197 case QSeries::SeriesTypePercentBar: {
198 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
198 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
199 PercentBarPresenter* bar = new PercentBarPresenter(percentBarSeries,m_chart);
199 PercentBarPresenter* bar = new PercentBarPresenter(percentBarSeries,m_chart);
200 if(m_options.testFlag(QChart::SeriesAnimations)) {
200 if(m_options.testFlag(QChart::SeriesAnimations)) {
201 // m_animator->addAnimation(bar);
201 // m_animator->addAnimation(bar);
202 }
202 }
203 m_chartTheme->decorate(bar, percentBarSeries, m_dataset->seriesIndex(percentBarSeries));
203 m_chartTheme->decorate(bar, percentBarSeries, m_dataset->seriesIndex(percentBarSeries));
204 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
204 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
205 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
205 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
206 item=bar;
206 item=bar;
207 break;
207 break;
208 }
208 }
209
209
210 case QSeries::SeriesTypeScatter: {
210 case QSeries::SeriesTypeScatter: {
211 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
211 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
212 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries, m_chart);
212 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries, m_chart);
213 if(m_options.testFlag(QChart::SeriesAnimations)) {
213 if(m_options.testFlag(QChart::SeriesAnimations)) {
214 m_animator->addAnimation(scatter);
214 m_animator->addAnimation(scatter);
215 }
215 }
216 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series));
216 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series));
217 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
217 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
218 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
218 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
219 item = scatter;
219 item = scatter;
220 break;
220 break;
221 }
221 }
222
222
223 case QSeries::SeriesTypePie: {
223 case QSeries::SeriesTypePie: {
224 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
224 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
225 PiePresenter* pie = new PiePresenter(m_chart, pieSeries);
225 PieChartItem* pie = new PieChartItem(m_chart, pieSeries);
226 if(m_options.testFlag(QChart::SeriesAnimations)) {
226 if(m_options.testFlag(QChart::SeriesAnimations)) {
227 // m_animator->addAnimation(pie);
227 // m_animator->addAnimation(pie);
228 }
228 }
229 m_chartTheme->decorate(pie, pieSeries, m_dataset->seriesIndex(series));
229 m_chartTheme->decorate(pie, pieSeries, m_dataset->seriesIndex(series));
230 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
230 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
231 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
231 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
232 // Hide all from background when there is only piechart
232 // Hide all from background when there is only piechart
233 // TODO: refactor this ugly code... should be one setting for this
233 // TODO: refactor this ugly code... should be one setting for this
234 if (m_chartItems.count() == 0) {
234 if (m_chartItems.count() == 0) {
235 m_chart->axisX()->hide();
235 m_chart->axisX()->hide();
236 m_chart->axisY()->hide();
236 m_chart->axisY()->hide();
237 m_chart->setChartBackgroundBrush(Qt::transparent);
237 m_chart->setChartBackgroundBrush(Qt::transparent);
238 }
238 }
239 item=pie;
239 item=pie;
240 break;
240 break;
241 }
241 }
242
242
243 case QSeries::SeriesTypeSpline: {
243 case QSeries::SeriesTypeSpline: {
244 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
244 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
245 SplineChartItem* spline = new SplineChartItem(splineSeries, m_chart);
245 SplineChartItem* spline = new SplineChartItem(splineSeries, m_chart);
246 if(m_options.testFlag(QChart::SeriesAnimations)) {
246 if(m_options.testFlag(QChart::SeriesAnimations)) {
247 m_animator->addAnimation(spline);
247 m_animator->addAnimation(spline);
248 }
248 }
249 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series));
249 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series));
250 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
250 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
251 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
251 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
252 item=spline;
252 item=spline;
253 break;
253 break;
254 }
254 }
255 default: {
255 default: {
256 qDebug()<< "Series type" << series->type() << "not implemented.";
256 qDebug()<< "Series type" << series->type() << "not implemented.";
257 break;
257 break;
258 }
258 }
259 }
259 }
260
260
261 //initialize
261 //initialize
262 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
262 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
263 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
263 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
264 m_chartItems.insert(series,item);
264 m_chartItems.insert(series,item);
265 zoomReset();
265 zoomReset();
266 }
266 }
267
267
268 void ChartPresenter::handleSeriesRemoved(QSeries* series)
268 void ChartPresenter::handleSeriesRemoved(QSeries* series)
269 {
269 {
270 ChartItem* item = m_chartItems.take(series);
270 ChartItem* item = m_chartItems.take(series);
271 Q_ASSERT(item);
271 Q_ASSERT(item);
272 if(m_animator) {
272 if(m_animator) {
273 //small hack to handle area animations
273 //small hack to handle area animations
274 if(series->type()==QSeries::SeriesTypeArea){
274 if(series->type()==QSeries::SeriesTypeArea){
275 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
275 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
276 AreaChartItem* area = static_cast<AreaChartItem*>(item);
276 AreaChartItem* area = static_cast<AreaChartItem*>(item);
277 m_animator->removeAnimation(area->upperLineItem());
277 m_animator->removeAnimation(area->upperLineItem());
278 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
278 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
279 }else
279 }else
280 m_animator->removeAnimation(item);
280 m_animator->removeAnimation(item);
281 }
281 }
282 delete item;
282 delete item;
283 }
283 }
284
284
285 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
285 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
286 {
286 {
287 if(m_chartTheme && m_chartTheme->id() == theme) return;
287 if(m_chartTheme && m_chartTheme->id() == theme) return;
288 delete m_chartTheme;
288 delete m_chartTheme;
289 m_chartTheme = ChartTheme::createTheme(theme);
289 m_chartTheme = ChartTheme::createTheme(theme);
290 m_chartTheme->decorate(m_chart);
290 m_chartTheme->decorate(m_chart);
291 m_chartTheme->decorate(m_chart->legend());
291 m_chartTheme->decorate(m_chart->legend());
292 resetAllElements();
292 resetAllElements();
293 }
293 }
294
294
295 QChart::ChartTheme ChartPresenter::chartTheme()
295 QChart::ChartTheme ChartPresenter::chartTheme()
296 {
296 {
297 return m_chartTheme->id();
297 return m_chartTheme->id();
298 }
298 }
299
299
300 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
300 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
301 {
301 {
302 if(m_options!=options) {
302 if(m_options!=options) {
303
303
304 m_options=options;
304 m_options=options;
305
305
306 if(m_options!=QChart::NoAnimation && !m_animator) {
306 if(m_options!=QChart::NoAnimation && !m_animator) {
307 m_animator= new ChartAnimator(this);
307 m_animator= new ChartAnimator(this);
308
308
309 }
309 }
310 resetAllElements();
310 resetAllElements();
311 }
311 }
312
312
313 }
313 }
314
314
315 void ChartPresenter::resetAllElements()
315 void ChartPresenter::resetAllElements()
316 {
316 {
317 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
317 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
318 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
318 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
319
319
320 foreach(QChartAxis* axis, axisList) {
320 foreach(QChartAxis* axis, axisList) {
321 handleAxisRemoved(axis);
321 handleAxisRemoved(axis);
322 handleAxisAdded(axis,m_dataset->domain(axis));
322 handleAxisAdded(axis,m_dataset->domain(axis));
323 }
323 }
324 foreach(QSeries* series, seriesList) {
324 foreach(QSeries* series, seriesList) {
325 handleSeriesRemoved(series);
325 handleSeriesRemoved(series);
326 handleSeriesAdded(series,m_dataset->domain(series));
326 handleSeriesAdded(series,m_dataset->domain(series));
327 }
327 }
328 }
328 }
329
329
330 void ChartPresenter::zoomIn()
330 void ChartPresenter::zoomIn()
331 {
331 {
332 QRectF rect = geometry();
332 QRectF rect = geometry();
333 rect.setWidth(rect.width()/2);
333 rect.setWidth(rect.width()/2);
334 rect.setHeight(rect.height()/2);
334 rect.setHeight(rect.height()/2);
335 rect.moveCenter(geometry().center());
335 rect.moveCenter(geometry().center());
336 zoomIn(rect);
336 zoomIn(rect);
337 }
337 }
338
338
339 void ChartPresenter::zoomIn(const QRectF& rect)
339 void ChartPresenter::zoomIn(const QRectF& rect)
340 {
340 {
341 QRectF r = rect.normalized();
341 QRectF r = rect.normalized();
342 r.translate(-m_marginSize, -m_marginSize);
342 r.translate(-m_marginSize, -m_marginSize);
343 if(m_animator) {
343 if(m_animator) {
344
344
345 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
345 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
346 m_animator->setState(ChartAnimator::ZoomInState,point);
346 m_animator->setState(ChartAnimator::ZoomInState,point);
347 }
347 }
348 m_dataset->zoomInDomain(r,geometry().size());
348 m_dataset->zoomInDomain(r,geometry().size());
349 m_zoomStack<<r;
349 m_zoomStack<<r;
350 m_zoomIndex++;
350 m_zoomIndex++;
351 if(m_animator) {
351 if(m_animator) {
352 m_animator->setState(ChartAnimator::ShowState);
352 m_animator->setState(ChartAnimator::ShowState);
353 }
353 }
354 }
354 }
355
355
356 void ChartPresenter::zoomOut()
356 void ChartPresenter::zoomOut()
357 {
357 {
358 if(m_zoomIndex==0) return;
358 if(m_zoomIndex==0) return;
359 if(m_animator)
359 if(m_animator)
360 {
360 {
361 m_animator->setState(ChartAnimator::ZoomOutState);
361 m_animator->setState(ChartAnimator::ZoomOutState);
362 }
362 }
363 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
363 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
364 m_zoomIndex--;
364 m_zoomIndex--;
365 m_zoomStack.resize(m_zoomIndex);
365 m_zoomStack.resize(m_zoomIndex);
366 if(m_animator){
366 if(m_animator){
367 m_animator->setState(ChartAnimator::ShowState);
367 m_animator->setState(ChartAnimator::ShowState);
368 }
368 }
369 }
369 }
370
370
371 void ChartPresenter::zoomReset()
371 void ChartPresenter::zoomReset()
372 {
372 {
373 m_zoomIndex=0;
373 m_zoomIndex=0;
374 m_zoomStack.resize(m_zoomIndex);
374 m_zoomStack.resize(m_zoomIndex);
375 }
375 }
376
376
377 void ChartPresenter::scroll(int dx,int dy)
377 void ChartPresenter::scroll(int dx,int dy)
378 {
378 {
379 if(m_animator){
379 if(m_animator){
380 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
380 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
381 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
381 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
382 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
382 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
383 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
383 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
384 }
384 }
385
385
386 m_dataset->scrollDomain(dx,dy,geometry().size());
386 m_dataset->scrollDomain(dx,dy,geometry().size());
387
387
388 if(m_animator){
388 if(m_animator){
389 m_animator->setState(ChartAnimator::ShowState);
389 m_animator->setState(ChartAnimator::ShowState);
390 }
390 }
391 }
391 }
392
392
393 QChart::AnimationOptions ChartPresenter::animationOptions() const
393 QChart::AnimationOptions ChartPresenter::animationOptions() const
394 {
394 {
395 return m_options;
395 return m_options;
396 }
396 }
397
397
398
398
399 #include "moc_chartpresenter_p.cpp"
399 #include "moc_chartpresenter_p.cpp"
400
400
401 QTCOMMERCIALCHART_END_NAMESPACE
401 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,305 +1,305
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qlegend.h"
3 #include "qlegend.h"
4 #include "qchartaxis.h"
4 #include "qchartaxis.h"
5 #include <QTime>
5 #include <QTime>
6
6
7 //series
7 //series
8 #include "qbarset.h"
8 #include "qbarset.h"
9 #include "qbarseries.h"
9 #include "qbarseries.h"
10 #include "qstackedbarseries.h"
10 #include "qstackedbarseries.h"
11 #include "qpercentbarseries.h"
11 #include "qpercentbarseries.h"
12 #include "qlineseries.h"
12 #include "qlineseries.h"
13 #include "qareaseries.h"
13 #include "qareaseries.h"
14 #include "qscatterseries.h"
14 #include "qscatterseries.h"
15 #include "qpieseries.h"
15 #include "qpieseries.h"
16 #include "qpieslice.h"
16 #include "qpieslice.h"
17 #include "qsplineseries.h"
17 #include "qsplineseries.h"
18
18
19 //items
19 //items
20 #include "axisitem_p.h"
20 #include "axisitem_p.h"
21 #include "barpresenter_p.h"
21 #include "barpresenter_p.h"
22 #include "stackedbarpresenter_p.h"
22 #include "stackedbarpresenter_p.h"
23 #include "percentbarpresenter_p.h"
23 #include "percentbarpresenter_p.h"
24 #include "linechartitem_p.h"
24 #include "linechartitem_p.h"
25 #include "areachartitem_p.h"
25 #include "areachartitem_p.h"
26 #include "scatterchartitem_p.h"
26 #include "scatterchartitem_p.h"
27 #include "piepresenter_p.h"
27 #include "piechartitem_p.h"
28 #include "splinechartitem_p.h"
28 #include "splinechartitem_p.h"
29
29
30 //themes
30 //themes
31 #include "chartthemedefault_p.h"
31 #include "chartthemedefault_p.h"
32 #include "chartthemevanilla_p.h"
32 #include "chartthemevanilla_p.h"
33 #include "chartthemeicy_p.h"
33 #include "chartthemeicy_p.h"
34 #include "chartthemegrayscale_p.h"
34 #include "chartthemegrayscale_p.h"
35 #include "chartthemescientific_p.h"
35 #include "chartthemescientific_p.h"
36
36
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 ChartTheme::ChartTheme(QChart::ChartTheme id)
40 ChartTheme::ChartTheme(QChart::ChartTheme id)
41 {
41 {
42 m_id = id;
42 m_id = id;
43 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
43 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
44 }
44 }
45
45
46
46
47 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
47 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
48 {
48 {
49 switch(theme) {
49 switch(theme) {
50 case QChart::ChartThemeVanilla:
50 case QChart::ChartThemeVanilla:
51 return new ChartThemeVanilla();
51 return new ChartThemeVanilla();
52 case QChart::ChartThemeIcy:
52 case QChart::ChartThemeIcy:
53 return new ChartThemeIcy();
53 return new ChartThemeIcy();
54 case QChart::ChartThemeGrayscale:
54 case QChart::ChartThemeGrayscale:
55 return new ChartThemeGrayscale();
55 return new ChartThemeGrayscale();
56 case QChart::ChartThemeScientific:
56 case QChart::ChartThemeScientific:
57 return new ChartThemeScientific();
57 return new ChartThemeScientific();
58 default:
58 default:
59 return new ChartThemeDefault();
59 return new ChartThemeDefault();
60 }
60 }
61 }
61 }
62
62
63 void ChartTheme::decorate(QChart* chart)
63 void ChartTheme::decorate(QChart* chart)
64 {
64 {
65 chart->setChartBackgroundBrush(m_backgroundGradient);
65 chart->setChartBackgroundBrush(m_backgroundGradient);
66 chart->setChartTitleFont(m_masterFont);
66 chart->setChartTitleFont(m_masterFont);
67 }
67 }
68
68
69 void ChartTheme::decorate(QLegend* legend)
69 void ChartTheme::decorate(QLegend* legend)
70 {
70 {
71 legend->setBackgroundBrush(m_backgroundGradient);
71 legend->setBackgroundBrush(m_backgroundGradient);
72 }
72 }
73
73
74 void ChartTheme::decorate(QAreaSeries* series, int index)
74 void ChartTheme::decorate(QAreaSeries* series, int index)
75 {
75 {
76 QPen pen;
76 QPen pen;
77 QBrush brush;
77 QBrush brush;
78
78
79 if (pen == series->pen()){
79 if (pen == series->pen()){
80 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
80 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
81 pen.setWidthF(2);
81 pen.setWidthF(2);
82 series->setPen(pen);
82 series->setPen(pen);
83 }
83 }
84
84
85 if (brush == series->brush()) {
85 if (brush == series->brush()) {
86 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
86 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
87 series->setBrush(brush);
87 series->setBrush(brush);
88 }
88 }
89 }
89 }
90
90
91
91
92 void ChartTheme::decorate(QLineSeries* series,int index)
92 void ChartTheme::decorate(QLineSeries* series,int index)
93 {
93 {
94 QPen pen;
94 QPen pen;
95 if(pen == series->pen()){
95 if(pen == series->pen()){
96 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
96 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
97 pen.setWidthF(2);
97 pen.setWidthF(2);
98 series->setPen(pen);
98 series->setPen(pen);
99 }
99 }
100 }
100 }
101
101
102 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int index)
102 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int index)
103 {
103 {
104 QList<QBarSet*> sets = series->barSets();
104 QList<QBarSet*> sets = series->barSets();
105 for (int i=0; i<sets.count(); i++) {
105 for (int i=0; i<sets.count(); i++) {
106 qreal pos = 0.5;
106 qreal pos = 0.5;
107 if (sets.count() > 1)
107 if (sets.count() > 1)
108 pos = (qreal) i / (qreal) (sets.count() - 1);
108 pos = (qreal) i / (qreal) (sets.count() - 1);
109 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
109 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
110 sets.at(i)->setBrush(QBrush(c));
110 sets.at(i)->setBrush(QBrush(c));
111
111
112 // Pick label color as far as possible from bar color (within gradient).
112 // Pick label color as far as possible from bar color (within gradient).
113 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
113 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
114 // TODO: better picking of label color?
114 // TODO: better picking of label color?
115 if (pos < 0.3) {
115 if (pos < 0.3) {
116 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
116 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
117 } else {
117 } else {
118 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
118 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
119 }
119 }
120 sets.at(i)->setFloatingValuePen(QPen(c));
120 sets.at(i)->setFloatingValuePen(QPen(c));
121 }
121 }
122 }
122 }
123
123
124 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int index)
124 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int index)
125 {
125 {
126 QList<QBarSet*> sets = series->barSets();
126 QList<QBarSet*> sets = series->barSets();
127 for (int i=0; i<sets.count(); i++) {
127 for (int i=0; i<sets.count(); i++) {
128 qreal pos = 0.5;
128 qreal pos = 0.5;
129 if (sets.count() > 1)
129 if (sets.count() > 1)
130 pos = (qreal) i / (qreal) (sets.count() - 1);
130 pos = (qreal) i / (qreal) (sets.count() - 1);
131 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
131 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
132 sets.at(i)->setBrush(QBrush(c));
132 sets.at(i)->setBrush(QBrush(c));
133
133
134 if (pos < 0.3) {
134 if (pos < 0.3) {
135 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
135 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
136 } else {
136 } else {
137 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
137 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
138 }
138 }
139 sets.at(i)->setFloatingValuePen(QPen(c));
139 sets.at(i)->setFloatingValuePen(QPen(c));
140 }
140 }
141 }
141 }
142
142
143 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int index)
143 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int index)
144 {
144 {
145 QList<QBarSet*> sets = series->barSets();
145 QList<QBarSet*> sets = series->barSets();
146 for (int i=0; i<sets.count(); i++) {
146 for (int i=0; i<sets.count(); i++) {
147 qreal pos = 0.5;
147 qreal pos = 0.5;
148 if (sets.count() > 1)
148 if (sets.count() > 1)
149 pos = (qreal) i / (qreal) (sets.count() - 1);
149 pos = (qreal) i / (qreal) (sets.count() - 1);
150 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
150 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
151 sets.at(i)->setBrush(QBrush(c));
151 sets.at(i)->setBrush(QBrush(c));
152
152
153 if (pos < 0.3) {
153 if (pos < 0.3) {
154 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
154 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
155 } else {
155 } else {
156 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
156 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
157 }
157 }
158 sets.at(i)->setFloatingValuePen(QPen(c));
158 sets.at(i)->setFloatingValuePen(QPen(c));
159 }
159 }
160 }
160 }
161
161
162 void ChartTheme::decorate(QScatterSeries* series, int index)
162 void ChartTheme::decorate(QScatterSeries* series, int index)
163 {
163 {
164
164
165 QPen pen;
165 QPen pen;
166 QBrush brush;
166 QBrush brush;
167
167
168 if (pen == series->pen()) {
168 if (pen == series->pen()) {
169 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
169 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
170 pen.setWidthF(2);
170 pen.setWidthF(2);
171 series->setPen(pen);
171 series->setPen(pen);
172 }
172 }
173
173
174 if (brush == series->brush()) {
174 if (brush == series->brush()) {
175 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
175 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
176 series->setBrush(brush);
176 series->setBrush(brush);
177 }
177 }
178 }
178 }
179
179
180 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int index)
180 void ChartTheme::decorate(PieChartItem* item, QPieSeries* series, int index)
181 {
181 {
182 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
182 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
183 for (int i(0); i < series->slices().count(); i++) {
183 for (int i(0); i < series->slices().count(); i++) {
184 qreal pos = (qreal) i / (qreal) series->count();
184 qreal pos = (qreal) i / (qreal) series->count();
185 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
185 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
186 series->slices().at(i)->setSlicePen(penColor);
186 series->slices().at(i)->setSlicePen(penColor);
187 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
187 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
188 series->slices().at(i)->setSliceBrush(brushColor);
188 series->slices().at(i)->setSliceBrush(brushColor);
189 }
189 }
190 }
190 }
191
191
192 void ChartTheme::decorate(QSplineSeries* series, int index)
192 void ChartTheme::decorate(QSplineSeries* series, int index)
193 {
193 {
194 QPen pen;
194 QPen pen;
195
195
196 if(pen == series->pen()){
196 if(pen == series->pen()){
197 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
197 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
198 pen.setWidthF(2);
198 pen.setWidthF(2);
199 series->setPen(pen);
199 series->setPen(pen);
200 }
200 }
201 }
201 }
202
202
203 void ChartTheme::decorate(QChartAxis* axis,bool axisX)
203 void ChartTheme::decorate(QChartAxis* axis,bool axisX)
204 {
204 {
205 if (axis->isAxisVisible()) {
205 if (axis->isAxisVisible()) {
206 axis->setLabelsBrush(m_axisLabelBrush);
206 axis->setLabelsBrush(m_axisLabelBrush);
207 axis->setLabelsPen(m_axisLabelPen);
207 axis->setLabelsPen(m_axisLabelPen);
208 // TODO: check the axis type (x or y) should define whether to show the shades or not
208 // TODO: check the axis type (x or y) should define whether to show the shades or not
209 if (m_backgroundShades == BackgroundShadesBoth
209 if (m_backgroundShades == BackgroundShadesBoth
210 || (m_backgroundShades == BackgroundShadesVertical && axisX)
210 || (m_backgroundShades == BackgroundShadesVertical && axisX)
211 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX)) {
211 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX)) {
212 axis->setShadesPen(m_backgroundShadesPen);
212 axis->setShadesPen(m_backgroundShadesPen);
213 axis->setShadesBrush(m_backgroundShadesBrush);
213 axis->setShadesBrush(m_backgroundShadesBrush);
214 } else {
214 } else {
215 // The shades not supposed to be shown for this axis, clear possible brush and pen
215 // The shades not supposed to be shown for this axis, clear possible brush and pen
216 axis->setShadesPen(Qt::NoPen);
216 axis->setShadesPen(Qt::NoPen);
217 axis->setShadesBrush(Qt::NoBrush);
217 axis->setShadesBrush(Qt::NoBrush);
218 }
218 }
219 axis->setAxisPen(m_axisLinePen);
219 axis->setAxisPen(m_axisLinePen);
220 axis->setGridLinePen(m_gridLinePen);
220 axis->setGridLinePen(m_gridLinePen);
221 axis->setLabelsFont(m_masterFont);
221 axis->setLabelsFont(m_masterFont);
222 }
222 }
223 }
223 }
224
224
225 void ChartTheme::generateSeriesGradients()
225 void ChartTheme::generateSeriesGradients()
226 {
226 {
227 // Generate gradients in HSV color space
227 // Generate gradients in HSV color space
228 foreach (QColor color, m_seriesColors) {
228 foreach (QColor color, m_seriesColors) {
229 QLinearGradient g;
229 QLinearGradient g;
230 qreal h = color.hsvHueF();
230 qreal h = color.hsvHueF();
231 qreal s = color.hsvSaturationF();
231 qreal s = color.hsvSaturationF();
232
232
233 // TODO: tune the algorithm to give nice results with most base colors defined in
233 // TODO: tune the algorithm to give nice results with most base colors defined in
234 // most themes. The rest of the gradients we can define manually in theme specific
234 // most themes. The rest of the gradients we can define manually in theme specific
235 // implementation.
235 // implementation.
236 QColor start = color;
236 QColor start = color;
237 start.setHsvF(h, 0.05, 0.95);
237 start.setHsvF(h, 0.05, 0.95);
238 g.setColorAt(0.0, start);
238 g.setColorAt(0.0, start);
239
239
240 g.setColorAt(0.5, color);
240 g.setColorAt(0.5, color);
241
241
242 QColor end = color;
242 QColor end = color;
243 end.setHsvF(h, s, 0.25);
243 end.setHsvF(h, s, 0.25);
244 g.setColorAt(1.0, end);
244 g.setColorAt(1.0, end);
245
245
246 m_seriesGradients << g;
246 m_seriesGradients << g;
247 }
247 }
248 }
248 }
249
249
250
250
251 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
251 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
252 {
252 {
253 Q_ASSERT(pos >=0.0 && pos <= 1.0);
253 Q_ASSERT(pos >=0.0 && pos <= 1.0);
254 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
254 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
255 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
255 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
256 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
256 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
257 QColor c;
257 QColor c;
258 c.setRgbF(r, g, b);
258 c.setRgbF(r, g, b);
259 return c;
259 return c;
260 }
260 }
261
261
262 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
262 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
263 {
263 {
264 Q_ASSERT(pos >=0 && pos <= 1.0);
264 Q_ASSERT(pos >=0 && pos <= 1.0);
265
265
266 // another possibility:
266 // another possibility:
267 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
267 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
268
268
269 QGradientStops stops = gradient.stops();
269 QGradientStops stops = gradient.stops();
270 int count = stops.count();
270 int count = stops.count();
271
271
272 // find previous stop relative to position
272 // find previous stop relative to position
273 QGradientStop prev = stops.first();
273 QGradientStop prev = stops.first();
274 for (int i=0; i<count; i++) {
274 for (int i=0; i<count; i++) {
275 QGradientStop stop = stops.at(i);
275 QGradientStop stop = stops.at(i);
276 if (pos > stop.first)
276 if (pos > stop.first)
277 prev = stop;
277 prev = stop;
278
278
279 // given position is actually a stop position?
279 // given position is actually a stop position?
280 if (pos == stop.first) {
280 if (pos == stop.first) {
281 //qDebug() << "stop color" << pos;
281 //qDebug() << "stop color" << pos;
282 return stop.second;
282 return stop.second;
283 }
283 }
284 }
284 }
285
285
286 // find next stop relative to position
286 // find next stop relative to position
287 QGradientStop next = stops.last();
287 QGradientStop next = stops.last();
288 for (int i=count-1; i>=0; i--) {
288 for (int i=count-1; i>=0; i--) {
289 QGradientStop stop = stops.at(i);
289 QGradientStop stop = stops.at(i);
290 if (pos < stop.first)
290 if (pos < stop.first)
291 next = stop;
291 next = stop;
292 }
292 }
293
293
294 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
294 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
295
295
296 qreal range = next.first - prev.first;
296 qreal range = next.first - prev.first;
297 qreal posDelta = pos - prev.first;
297 qreal posDelta = pos - prev.first;
298 qreal relativePos = posDelta / range;
298 qreal relativePos = posDelta / range;
299
299
300 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
300 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
301
301
302 return colorAt(prev.second, next.second, relativePos);
302 return colorAt(prev.second, next.second, relativePos);
303 }
303 }
304
304
305 QTCOMMERCIALCHART_END_NAMESPACE
305 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,81
1 #ifndef CHARTTHEME_H
1 #ifndef CHARTTHEME_H
2 #define CHARTTHEME_H
2 #define CHARTTHEME_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qchart.h"
5 #include "qchart.h"
6 #include <QColor>
6 #include <QColor>
7 #include <QGradientStops>
7 #include <QGradientStops>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class ChartItem;
11 class ChartItem;
12 class QSeries;
12 class QSeries;
13 class LineChartItem;
13 class LineChartItem;
14 class QLineSeries;
14 class QLineSeries;
15 class BarPresenter;
15 class BarPresenter;
16 class QBarSeries;
16 class QBarSeries;
17 class StackedBarPresenter;
17 class StackedBarPresenter;
18 class QStackedBarSeries;
18 class QStackedBarSeries;
19 class QPercentBarSeries;
19 class QPercentBarSeries;
20 class PercentBarPresenter;
20 class PercentBarPresenter;
21 class QScatterSeries;
21 class QScatterSeries;
22 class ScatterChartItem;
22 class ScatterChartItem;
23 class PiePresenter;
23 class PieChartItem;
24 class QPieSeries;
24 class QPieSeries;
25 class SplineChartItem;
25 class SplineChartItem;
26 class QSplineSeries;
26 class QSplineSeries;
27 class AreaChartItem;
27 class AreaChartItem;
28 class QAreaSeries;
28 class QAreaSeries;
29
29
30 class ChartTheme
30 class ChartTheme
31 {
31 {
32 public:
32 public:
33 enum BackgroundShadesMode {
33 enum BackgroundShadesMode {
34 BackgroundShadesNone = 0,
34 BackgroundShadesNone = 0,
35 BackgroundShadesVertical,
35 BackgroundShadesVertical,
36 BackgroundShadesHorizontal,
36 BackgroundShadesHorizontal,
37 BackgroundShadesBoth
37 BackgroundShadesBoth
38 };
38 };
39
39
40 protected:
40 protected:
41 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
41 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
42 public:
42 public:
43 static ChartTheme* createTheme(QChart::ChartTheme theme);
43 static ChartTheme* createTheme(QChart::ChartTheme theme);
44 QChart::ChartTheme id() const {return m_id;}
44 QChart::ChartTheme id() const {return m_id;}
45 void decorate(QChart* chart);
45 void decorate(QChart* chart);
46 void decorate(QLegend* legend);
46 void decorate(QLegend* legend);
47 //void decorate(ChartItem* item, QSeries* series,int index);
47 //void decorate(ChartItem* item, QSeries* series,int index);
48 void decorate(BarPresenter* item, QBarSeries* series, int index);
48 void decorate(BarPresenter* item, QBarSeries* series, int index);
49 void decorate(StackedBarPresenter* item, QStackedBarSeries* series, int index);
49 void decorate(StackedBarPresenter* item, QStackedBarSeries* series, int index);
50 void decorate(PercentBarPresenter* item, QPercentBarSeries* series, int index);
50 void decorate(PercentBarPresenter* item, QPercentBarSeries* series, int index);
51 void decorate(QLineSeries* series, int index);
51 void decorate(QLineSeries* series, int index);
52 void decorate(QAreaSeries* series, int index);
52 void decorate(QAreaSeries* series, int index);
53 void decorate(QScatterSeries* series, int index);
53 void decorate(QScatterSeries* series, int index);
54 void decorate(PiePresenter* item, QPieSeries* series, int index);
54 void decorate(PieChartItem* item, QPieSeries* series, int index);
55 void decorate(QSplineSeries* series, int index);
55 void decorate(QSplineSeries* series, int index);
56 void decorate(QChartAxis* axis, bool axisX);
56 void decorate(QChartAxis* axis, bool axisX);
57
57
58 public: // utils
58 public: // utils
59 void generateSeriesGradients();
59 void generateSeriesGradients();
60 static QColor colorAt(const QColor &start, const QColor &end, qreal pos);
60 static QColor colorAt(const QColor &start, const QColor &end, qreal pos);
61 static QColor colorAt(const QGradient &gradient, qreal pos);
61 static QColor colorAt(const QGradient &gradient, qreal pos);
62
62
63 protected:
63 protected:
64 QChart::ChartTheme m_id;
64 QChart::ChartTheme m_id;
65 QList<QColor> m_seriesColors;
65 QList<QColor> m_seriesColors;
66 QList<QGradient> m_seriesGradients;
66 QList<QGradient> m_seriesGradients;
67 QLinearGradient m_backgroundGradient;
67 QLinearGradient m_backgroundGradient;
68
68
69 QFont m_masterFont;
69 QFont m_masterFont;
70 QPen m_axisLinePen;
70 QPen m_axisLinePen;
71 QBrush m_axisLabelBrush;
71 QBrush m_axisLabelBrush;
72 QPen m_axisLabelPen;
72 QPen m_axisLabelPen;
73 QPen m_backgroundShadesPen;
73 QPen m_backgroundShadesPen;
74 QBrush m_backgroundShadesBrush;
74 QBrush m_backgroundShadesBrush;
75 BackgroundShadesMode m_backgroundShades;
75 BackgroundShadesMode m_backgroundShades;
76 QPen m_gridLinePen;
76 QPen m_gridLinePen;
77 };
77 };
78
78
79 QTCOMMERCIALCHART_END_NAMESPACE
79 QTCOMMERCIALCHART_END_NAMESPACE
80
80
81 #endif // CHARTTHEME_H
81 #endif // CHARTTHEME_H
@@ -1,16 +1,16
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/piechartitem.cpp \
8 $$PWD/qpieslice.cpp
8 $$PWD/qpieslice.cpp
9
9
10 PRIVATE_HEADERS += \
10 PRIVATE_HEADERS += \
11 $$PWD/piepresenter_p.h \
11 $$PWD/piechartitem_p.h \
12 $$PWD/pieslice_p.h \
12 $$PWD/pieslice_p.h \
13
13
14 PUBLIC_HEADERS += \
14 PUBLIC_HEADERS += \
15 $$PWD/qpieseries.h \
15 $$PWD/qpieseries.h \
16 $$PWD/qpieslice.h
16 $$PWD/qpieslice.h
@@ -1,143 +1,143
1 #include "piepresenter_p.h"
1 #include "piechartitem_p.h"
2 #include "pieslice_p.h"
2 #include "pieslice_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QDebug>
6 #include <QDebug>
7 #include <QPainter>
7 #include <QPainter>
8
8
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series)
12 PieChartItem::PieChartItem(QGraphicsItem *parent, QPieSeries *series)
13 :ChartItem(parent),
13 :ChartItem(parent),
14 m_series(series)
14 m_series(series)
15 {
15 {
16 Q_ASSERT(series);
16 Q_ASSERT(series);
17 connect(series, SIGNAL(changed()), this, SLOT(handleSeriesChanged()));
17 connect(series, SIGNAL(changed()), this, SLOT(handleSeriesChanged()));
18
18
19 // Note: the following does not affect as long as the item does not have anything to paint
19 // Note: the following does not affect as long as the item does not have anything to paint
20 setZValue(ChartPresenter::PieSeriesZValue);
20 setZValue(ChartPresenter::PieSeriesZValue);
21 }
21 }
22
22
23 PiePresenter::~PiePresenter()
23 PieChartItem::~PieChartItem()
24 {
24 {
25 // slices deleted automatically through QGraphicsItem
25 // slices deleted automatically through QGraphicsItem
26 }
26 }
27
27
28 void PiePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
28 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
29 {
29 {
30 // TODO: paint shadows for all components
30 // TODO: paint shadows for all components
31 // - get paths from items & merge & offset and draw with shadow color?
31 // - get paths from items & merge & offset and draw with shadow color?
32 //painter->setBrush(QBrush(Qt::red));
32 //painter->setBrush(QBrush(Qt::red));
33 //painter->drawRect(m_debugRect);
33 //painter->drawRect(m_debugRect);
34 }
34 }
35
35
36 void PiePresenter::handleSeriesChanged()
36 void PieChartItem::handleSeriesChanged()
37 {
37 {
38 QVector<PieSliceLayout> sliceLayout = calculateLayout();
38 QVector<PieSliceLayout> sliceLayout = calculateLayout();
39 applyLayout(sliceLayout);
39 applyLayout(sliceLayout);
40 update();
40 update();
41 }
41 }
42
42
43 void PiePresenter::handleSliceChanged()
43 void PieChartItem::handleSliceChanged()
44 {
44 {
45 // TODO: optimize don't need to handle all slices
45 // TODO: optimize don't need to handle all slices
46 QVector<PieSliceLayout> sliceLayout = calculateLayout();
46 QVector<PieSliceLayout> sliceLayout = calculateLayout();
47 applyLayout(sliceLayout);
47 applyLayout(sliceLayout);
48 update();
48 update();
49 }
49 }
50
50
51 void PiePresenter::handleDomainChanged(qreal, qreal, qreal, qreal)
51 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
52 {
52 {
53 // TODO
53 // TODO
54 }
54 }
55
55
56 void PiePresenter::handleGeometryChanged(const QRectF& rect)
56 void PieChartItem::handleGeometryChanged(const QRectF& rect)
57 {
57 {
58 prepareGeometryChange();
58 prepareGeometryChange();
59 m_rect = rect;
59 m_rect = rect;
60 QVector<PieSliceLayout> sliceLayout = calculateLayout();
60 QVector<PieSliceLayout> sliceLayout = calculateLayout();
61 applyLayout(sliceLayout);
61 applyLayout(sliceLayout);
62 update();
62 update();
63 }
63 }
64
64
65
65
66 QVector<PieSliceLayout> PiePresenter::calculateLayout()
66 QVector<PieSliceLayout> PieChartItem::calculateLayout()
67 {
67 {
68 // find pie center coordinates
68 // find pie center coordinates
69 QPointF center;
69 QPointF center;
70 center.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
70 center.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
71 center.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
71 center.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
72
72
73 // find maximum radius for pie
73 // find maximum radius for pie
74 qreal radius = m_rect.height() / 2;
74 qreal radius = m_rect.height() / 2;
75 if (m_rect.width() < m_rect.height())
75 if (m_rect.width() < m_rect.height())
76 radius = m_rect.width() / 2;
76 radius = m_rect.width() / 2;
77
77
78 // apply size factor
78 // apply size factor
79 radius *= m_series->pieSize();
79 radius *= m_series->pieSize();
80
80
81 QVector<PieSliceLayout> layout;
81 QVector<PieSliceLayout> layout;
82 foreach (QPieSlice* s, m_series->slices()) {
82 foreach (QPieSlice* s, m_series->slices()) {
83 PieSliceLayout sliceLayout;
83 PieSliceLayout sliceLayout;
84 sliceLayout.m_data = s;
84 sliceLayout.m_data = s;
85 sliceLayout.m_center = PieSlice::sliceCenter(center, radius, s);
85 sliceLayout.m_center = PieSlice::sliceCenter(center, radius, s);
86 sliceLayout.m_radius = radius;
86 sliceLayout.m_radius = radius;
87 sliceLayout.m_startAngle = s->startAngle();
87 sliceLayout.m_startAngle = s->startAngle();
88 sliceLayout.m_angleSpan = s->m_angleSpan;
88 sliceLayout.m_angleSpan = s->m_angleSpan;
89 layout << sliceLayout;
89 layout << sliceLayout;
90 }
90 }
91
91
92 return layout;
92 return layout;
93 }
93 }
94
94
95 void PiePresenter::applyLayout(const QVector<PieSliceLayout> &layout)
95 void PieChartItem::applyLayout(const QVector<PieSliceLayout> &layout)
96 {
96 {
97 //if(m_animator)
97 //if(m_animator)
98 // m_animator->applyLayout(this,points);
98 // m_animator->applyLayout(this,points);
99 //else
99 //else
100 setLayout(layout);
100 setLayout(layout);
101 }
101 }
102
102
103 void PiePresenter::setLayout(const QVector<PieSliceLayout> &layout)
103 void PieChartItem::setLayout(const QVector<PieSliceLayout> &layout)
104 {
104 {
105 foreach (PieSliceLayout l, layout) {
105 foreach (PieSliceLayout l, layout) {
106
106
107 // find slice
107 // find slice
108 PieSlice *slice = m_slices.value(l.m_data);
108 PieSlice *slice = m_slices.value(l.m_data);
109 if (!slice) {
109 if (!slice) {
110 // add a new slice
110 // add a new slice
111 slice = new PieSlice(this);
111 slice = new PieSlice(this);
112 m_slices.insert(l.m_data, slice);
112 m_slices.insert(l.m_data, slice);
113
113
114 // connect signals
114 // connect signals
115 connect(l.m_data, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
115 connect(l.m_data, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
116 connect(slice, SIGNAL(clicked()), l.m_data, SIGNAL(clicked()));
116 connect(slice, SIGNAL(clicked()), l.m_data, SIGNAL(clicked()));
117 connect(slice, SIGNAL(hoverEnter()), l.m_data, SIGNAL(hoverEnter()));
117 connect(slice, SIGNAL(hoverEnter()), l.m_data, SIGNAL(hoverEnter()));
118 connect(slice, SIGNAL(hoverLeave()), l.m_data, SIGNAL(hoverLeave()));
118 connect(slice, SIGNAL(hoverLeave()), l.m_data, SIGNAL(hoverLeave()));
119 }
119 }
120
120
121 // update
121 // update
122 slice->setLayout(l);
122 slice->setLayout(l);
123 slice->updateGeometry();
123 slice->updateGeometry();
124 slice->update();
124 slice->update();
125 }
125 }
126
126
127 // delete slices
127 // delete slices
128 foreach (QPieSlice *s, m_slices.keys()) {
128 foreach (QPieSlice *s, m_slices.keys()) {
129
129
130 bool found = false;
130 bool found = false;
131 foreach (PieSliceLayout l, layout) {
131 foreach (PieSliceLayout l, layout) {
132 if (l.m_data == s)
132 if (l.m_data == s)
133 found = true;
133 found = true;
134 }
134 }
135
135
136 if (!found)
136 if (!found)
137 delete m_slices.take(s);
137 delete m_slices.take(s);
138 }
138 }
139 }
139 }
140
140
141 #include "moc_piepresenter_p.cpp"
141 #include "moc_piechartitem_p.cpp"
142
142
143 QTCOMMERCIALCHART_END_NAMESPACE
143 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,48 +1,48
1 #ifndef PIEPRESENTER_H
1 #ifndef PIECHARTITEM_H
2 #define PIEPRESENTER_H
2 #define PIECHARTITEM_H
3
3
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include "pieslice_p.h"
6 #include "pieslice_p.h"
7
7
8 class QGraphicsItem;
8 class QGraphicsItem;
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 class QPieSlice;
10 class QPieSlice;
11
11
12 class PiePresenter : public QObject, public ChartItem
12 class PieChartItem : public QObject, public ChartItem
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15
15
16 public:
16 public:
17 // TODO: use a generic data class instead of x and y
17 // TODO: use a generic data class instead of x and y
18 PiePresenter(QGraphicsItem *parent, QPieSeries *series);
18 PieChartItem(QGraphicsItem *parent, QPieSeries *series);
19 ~PiePresenter();
19 ~PieChartItem();
20
20
21 public: // from QGraphicsItem
21 public: // from QGraphicsItem
22 QRectF boundingRect() const { return m_rect; }
22 QRectF boundingRect() const { return m_rect; }
23 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
23 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
24
24
25 public Q_SLOTS:
25 public Q_SLOTS:
26 void handleSeriesChanged();
26 void handleSeriesChanged();
27 void handleSliceChanged();
27 void handleSliceChanged();
28 void handleDomainChanged(qreal, qreal, qreal, qreal);
28 void handleDomainChanged(qreal, qreal, qreal, qreal);
29 void handleGeometryChanged(const QRectF& rect);
29 void handleGeometryChanged(const QRectF& rect);
30
30
31 private:
31 private:
32 QVector<PieSliceLayout> calculateLayout();
32 QVector<PieSliceLayout> calculateLayout();
33 void applyLayout(const QVector<PieSliceLayout> &layout);
33 void applyLayout(const QVector<PieSliceLayout> &layout);
34 void setLayout(const QVector<PieSliceLayout> &layout);
34 void setLayout(const QVector<PieSliceLayout> &layout);
35
35
36 private:
36 private:
37 friend class PieSlice;
37 friend class PieSlice;
38 QHash<QPieSlice*, PieSlice*> m_slices;
38 QHash<QPieSlice*, PieSlice*> m_slices;
39 QPieSeries *m_series;
39 QPieSeries *m_series;
40 QRectF m_rect;
40 QRectF m_rect;
41 QPointF m_pieCenter;
41 QPointF m_pieCenter;
42 qreal m_pieRadius;
42 qreal m_pieRadius;
43 QRectF m_debugRect;
43 QRectF m_debugRect;
44 };
44 };
45
45
46 QTCOMMERCIALCHART_END_NAMESPACE
46 QTCOMMERCIALCHART_END_NAMESPACE
47
47
48 #endif // PIEPRESENTER_H
48 #endif // PIECHARTITEM_H
@@ -1,208 +1,208
1 #include "pieslice_p.h"
1 #include "pieslice_p.h"
2 #include "piepresenter_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSlice::PieSlice(QGraphicsItem* parent)
23 PieSlice::PieSlice(QGraphicsItem* parent)
24 :QGraphicsObject(parent),
24 :QGraphicsObject(parent),
25 m_startAngle(0),
25 m_startAngle(0),
26 m_angleSpan(0),
26 m_angleSpan(0),
27 m_isExploded(false),
27 m_isExploded(false),
28 m_explodeDistanceFactor(0),
28 m_explodeDistanceFactor(0),
29 m_labelVisible(false),
29 m_labelVisible(false),
30 m_labelArmLengthFactor(0)
30 m_labelArmLengthFactor(0)
31 {
31 {
32 setAcceptHoverEvents(true);
32 setAcceptHoverEvents(true);
33 setAcceptedMouseButtons(Qt::LeftButton);
33 setAcceptedMouseButtons(Qt::LeftButton);
34 setZValue(ChartPresenter::PieSeriesZValue);
34 setZValue(ChartPresenter::PieSeriesZValue);
35 }
35 }
36
36
37 PieSlice::~PieSlice()
37 PieSlice::~PieSlice()
38 {
38 {
39
39
40 }
40 }
41
41
42 QRectF PieSlice::boundingRect() const
42 QRectF PieSlice::boundingRect() const
43 {
43 {
44 return m_slicePath.boundingRect();
44 return m_slicePath.boundingRect();
45 }
45 }
46
46
47 QPainterPath PieSlice::shape() const
47 QPainterPath PieSlice::shape() const
48 {
48 {
49 // Don't include the label and label arm.
49 // Don't include the label and label arm.
50 // This is used to detect a mouse clicks. We do not want clicks from label.
50 // This is used to detect a mouse clicks. We do not want clicks from label.
51 return m_slicePath;
51 return m_slicePath;
52 }
52 }
53
53
54 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
54 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
55 {
55 {
56 painter->setClipRect(parentItem()->boundingRect());
56 painter->setClipRect(parentItem()->boundingRect());
57
57
58 painter->save();
58 painter->save();
59 painter->setPen(m_slicePen);
59 painter->setPen(m_slicePen);
60 painter->setBrush(m_sliceBrush);
60 painter->setBrush(m_sliceBrush);
61 painter->drawPath(m_slicePath);
61 painter->drawPath(m_slicePath);
62 painter->restore();
62 painter->restore();
63
63
64 if (m_labelVisible) {
64 if (m_labelVisible) {
65 painter->save();
65 painter->save();
66 painter->setPen(m_labelArmPen);
66 painter->setPen(m_labelArmPen);
67 painter->drawPath(m_labelArmPath);
67 painter->drawPath(m_labelArmPath);
68 painter->restore();
68 painter->restore();
69
69
70 painter->setFont(m_labelFont);
70 painter->setFont(m_labelFont);
71 painter->drawText(m_labelTextRect.bottomLeft(), m_labelText);
71 painter->drawText(m_labelTextRect.bottomLeft(), m_labelText);
72 }
72 }
73 }
73 }
74
74
75 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
75 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
76 {
76 {
77 emit hoverEnter();
77 emit hoverEnter();
78 }
78 }
79
79
80 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
80 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
81 {
81 {
82 emit hoverLeave();
82 emit hoverLeave();
83 }
83 }
84
84
85 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
85 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
86 {
86 {
87 emit clicked();
87 emit clicked();
88 }
88 }
89
89
90 void PieSlice::setLayout(PieSliceLayout layout)
90 void PieSlice::setLayout(PieSliceLayout layout)
91 {
91 {
92 m_layout = layout;
92 m_layout = layout;
93 updateData(layout.m_data);
93 updateData(layout.m_data);
94 }
94 }
95
95
96 void PieSlice::updateGeometry()
96 void PieSlice::updateGeometry()
97 {
97 {
98 if (m_layout.m_radius <= 0)
98 if (m_layout.m_radius <= 0)
99 return;
99 return;
100
100
101 prepareGeometryChange();
101 prepareGeometryChange();
102
102
103 // update slice path
103 // update slice path
104 qreal centerAngle;
104 qreal centerAngle;
105 QPointF armStart;
105 QPointF armStart;
106 m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_startAngle, m_angleSpan, &centerAngle, &armStart);
106 m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_startAngle, m_angleSpan, &centerAngle, &armStart);
107
107
108 // update text rect
108 // update text rect
109 m_labelTextRect = labelTextRect(m_labelFont, m_labelText);
109 m_labelTextRect = labelTextRect(m_labelFont, m_labelText);
110
110
111 // update label arm path
111 // update label arm path
112 QPointF labelTextStart;
112 QPointF labelTextStart;
113 m_labelArmPath = labelArmPath(armStart, centerAngle, m_layout.m_radius * m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
113 m_labelArmPath = labelArmPath(armStart, centerAngle, m_layout.m_radius * m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
114
114
115 // update text position
115 // update text position
116 m_labelTextRect.moveBottomLeft(labelTextStart);
116 m_labelTextRect.moveBottomLeft(labelTextStart);
117
117
118 //qDebug() << "PieSlice::updateGeometry" << m_labelText << boundingRect() << m_startAngle << m_startAngle + m_angleSpan;
118 //qDebug() << "PieSlice::updateGeometry" << m_labelText << boundingRect() << m_startAngle << m_startAngle + m_angleSpan;
119 }
119 }
120
120
121 void PieSlice::updateData(const QPieSlice* sliceData)
121 void PieSlice::updateData(const QPieSlice* sliceData)
122 {
122 {
123 // TODO: compare what has changes to avoid unneccesary geometry updates
123 // TODO: compare what has changes to avoid unneccesary geometry updates
124
124
125 m_startAngle = sliceData->startAngle();
125 m_startAngle = sliceData->startAngle();
126 m_angleSpan = sliceData->m_angleSpan;
126 m_angleSpan = sliceData->m_angleSpan;
127 m_isExploded = sliceData->isExploded();
127 m_isExploded = sliceData->isExploded();
128 m_explodeDistanceFactor = sliceData->explodeDistanceFactor();
128 m_explodeDistanceFactor = sliceData->explodeDistanceFactor();
129 m_slicePen = sliceData->slicePen();
129 m_slicePen = sliceData->slicePen();
130 m_sliceBrush = sliceData->sliceBrush();
130 m_sliceBrush = sliceData->sliceBrush();
131
131
132 m_labelVisible = sliceData->isLabelVisible();
132 m_labelVisible = sliceData->isLabelVisible();
133 m_labelText = sliceData->label();
133 m_labelText = sliceData->label();
134 m_labelFont = sliceData->labelFont();
134 m_labelFont = sliceData->labelFont();
135 m_labelArmLengthFactor = sliceData->labelArmLengthFactor();
135 m_labelArmLengthFactor = sliceData->labelArmLengthFactor();
136 m_labelArmPen = sliceData->labelArmPen();
136 m_labelArmPen = sliceData->labelArmPen();
137 }
137 }
138
138
139 QPointF PieSlice::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
139 QPointF PieSlice::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
140 {
140 {
141 if (slice->isExploded()) {
141 if (slice->isExploded()) {
142 qreal centerAngle = slice->startAngle() + (slice->m_angleSpan/2);
142 qreal centerAngle = slice->startAngle() + (slice->m_angleSpan/2);
143 qreal len = radius * slice->explodeDistanceFactor();
143 qreal len = radius * slice->explodeDistanceFactor();
144 qreal dx = qSin(centerAngle*(PI/180)) * len;
144 qreal dx = qSin(centerAngle*(PI/180)) * len;
145 qreal dy = -qCos(centerAngle*(PI/180)) * len;
145 qreal dy = -qCos(centerAngle*(PI/180)) * len;
146 point += QPointF(dx, dy);
146 point += QPointF(dx, dy);
147 }
147 }
148 return point;
148 return point;
149 }
149 }
150
150
151 QPainterPath PieSlice::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
151 QPainterPath PieSlice::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
152 {
152 {
153 // calculate center angle
153 // calculate center angle
154 *centerAngle = startAngle + (angleSpan/2);
154 *centerAngle = startAngle + (angleSpan/2);
155
155
156 // calculate slice rectangle
156 // calculate slice rectangle
157 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
157 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
158
158
159 // slice path
159 // slice path
160 // TODO: draw the shape so that it might have a hole in the center
160 // TODO: draw the shape so that it might have a hole in the center
161 QPainterPath path;
161 QPainterPath path;
162 path.moveTo(rect.center());
162 path.moveTo(rect.center());
163 path.arcTo(rect, -startAngle + 90, -angleSpan);
163 path.arcTo(rect, -startAngle + 90, -angleSpan);
164 path.closeSubpath();
164 path.closeSubpath();
165
165
166 // calculate label arm start point
166 // calculate label arm start point
167 *armStart = center;
167 *armStart = center;
168 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
168 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
169
169
170 return path;
170 return path;
171 }
171 }
172
172
173 QPainterPath PieSlice::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
173 QPainterPath PieSlice::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
174 {
174 {
175 qreal dx = qSin(angle*(PI/180)) * length;
175 qreal dx = qSin(angle*(PI/180)) * length;
176 qreal dy = -qCos(angle*(PI/180)) * length;
176 qreal dy = -qCos(angle*(PI/180)) * length;
177 QPointF parm1 = start + QPointF(dx, dy);
177 QPointF parm1 = start + QPointF(dx, dy);
178
178
179 QPointF parm2 = parm1;
179 QPointF parm2 = parm1;
180 if (angle < 180) { // arm swings the other way on the left side
180 if (angle < 180) { // arm swings the other way on the left side
181 parm2 += QPointF(textWidth, 0);
181 parm2 += QPointF(textWidth, 0);
182 *textStart = parm1;
182 *textStart = parm1;
183 }
183 }
184 else {
184 else {
185 parm2 += QPointF(-textWidth,0);
185 parm2 += QPointF(-textWidth,0);
186 *textStart = parm2;
186 *textStart = parm2;
187 }
187 }
188
188
189 // elevate the text position a bit so that it does not hit the line
189 // elevate the text position a bit so that it does not hit the line
190 *textStart += QPointF(0, -5);
190 *textStart += QPointF(0, -5);
191
191
192 QPainterPath path;
192 QPainterPath path;
193 path.moveTo(start);
193 path.moveTo(start);
194 path.lineTo(parm1);
194 path.lineTo(parm1);
195 path.lineTo(parm2);
195 path.lineTo(parm2);
196
196
197 return path;
197 return path;
198 }
198 }
199
199
200 QRectF PieSlice::labelTextRect(QFont font, QString text)
200 QRectF PieSlice::labelTextRect(QFont font, QString text)
201 {
201 {
202 QFontMetricsF fm(font);
202 QFontMetricsF fm(font);
203 return fm.boundingRect(text);
203 return fm.boundingRect(text);
204 }
204 }
205
205
206 #include "moc_pieslice_p.cpp"
206 #include "moc_pieslice_p.cpp"
207
207
208 QTCOMMERCIALCHART_END_NAMESPACE
208 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,82 +1,82
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 "qpieseries.h"
7 #include <QGraphicsItem>
7 #include <QGraphicsItem>
8 #include <QRectF>
8 #include <QRectF>
9 #include <QColor>
9 #include <QColor>
10 #include <QPen>
10 #include <QPen>
11
11
12 #define PIESLICE_LABEL_GAP 5
12 #define PIESLICE_LABEL_GAP 5
13
13
14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 class PiePresenter;
15 class PieChartItem;
16 class PieSliceLabel;
16 class PieSliceLabel;
17 class QPieSlice;
17 class QPieSlice;
18
18
19 class PieSliceLayout
19 class PieSliceLayout
20 {
20 {
21 public:
21 public:
22 QPieSlice* m_data;
22 QPieSlice* m_data;
23 QPointF m_center;
23 QPointF m_center;
24 qreal m_radius;
24 qreal m_radius;
25 qreal m_startAngle;
25 qreal m_startAngle;
26 qreal m_angleSpan;
26 qreal m_angleSpan;
27 };
27 };
28
28
29 class PieSlice : public QGraphicsObject
29 class PieSlice : public QGraphicsObject
30 {
30 {
31 Q_OBJECT
31 Q_OBJECT
32
32
33 public:
33 public:
34 PieSlice(QGraphicsItem* parent = 0);
34 PieSlice(QGraphicsItem* parent = 0);
35 ~PieSlice();
35 ~PieSlice();
36
36
37 public: // from QGraphicsItem
37 public: // from QGraphicsItem
38 QRectF boundingRect() const;
38 QRectF boundingRect() const;
39 QPainterPath shape() const;
39 QPainterPath shape() const;
40 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
40 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
41 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
41 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
42 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
42 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
43 void mousePressEvent(QGraphicsSceneMouseEvent *event);
43 void mousePressEvent(QGraphicsSceneMouseEvent *event);
44
44
45 Q_SIGNALS:
45 Q_SIGNALS:
46 void clicked();
46 void clicked();
47 void hoverEnter();
47 void hoverEnter();
48 void hoverLeave();
48 void hoverLeave();
49
49
50 public:
50 public:
51 void setLayout(PieSliceLayout layout);
51 void setLayout(PieSliceLayout layout);
52 void updateGeometry();
52 void updateGeometry();
53 void updateData(const QPieSlice *sliceData);
53 void updateData(const QPieSlice *sliceData);
54 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
54 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
55 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
55 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
56 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
56 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
57 static QRectF labelTextRect(QFont font, QString text);
57 static QRectF labelTextRect(QFont font, QString text);
58
58
59 private:
59 private:
60 PieSliceLayout m_layout;
60 PieSliceLayout m_layout;
61
61
62 QPainterPath m_slicePath;
62 QPainterPath m_slicePath;
63 qreal m_startAngle;
63 qreal m_startAngle;
64 qreal m_angleSpan;
64 qreal m_angleSpan;
65 bool m_isExploded;
65 bool m_isExploded;
66 qreal m_explodeDistanceFactor;
66 qreal m_explodeDistanceFactor;
67 bool m_labelVisible;
67 bool m_labelVisible;
68 QPen m_slicePen;
68 QPen m_slicePen;
69 QBrush m_sliceBrush;
69 QBrush m_sliceBrush;
70
70
71 QPainterPath m_labelArmPath;
71 QPainterPath m_labelArmPath;
72 qreal m_labelArmLengthFactor;
72 qreal m_labelArmLengthFactor;
73 QPen m_labelArmPen;
73 QPen m_labelArmPen;
74
74
75 QRectF m_labelTextRect;
75 QRectF m_labelTextRect;
76 QFont m_labelFont;
76 QFont m_labelFont;
77 QString m_labelText;
77 QString m_labelText;
78 };
78 };
79
79
80 QTCOMMERCIALCHART_END_NAMESPACE
80 QTCOMMERCIALCHART_END_NAMESPACE
81
81
82 #endif // PIESLICE_H
82 #endif // PIESLICE_H
@@ -1,129 +1,129
1 #ifndef PIESERIES_H
1 #ifndef PIESERIES_H
2 #define PIESERIES_H
2 #define PIESERIES_H
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QRectF>
6 #include <QRectF>
7 #include <QColor>
7 #include <QColor>
8 #include <QPen>
8 #include <QPen>
9 #include <QBrush>
9 #include <QBrush>
10 #include <QSignalMapper>
10 #include <QSignalMapper>
11
11
12 class QGraphicsObject;
12 class QGraphicsObject;
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 class PiePresenter;
14 class PieChartItem;
15 class PieSlice;
15 class PieSlice;
16 class QPieSlice;
16 class QPieSlice;
17
17
18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
19 {
19 {
20 Q_OBJECT
20 Q_OBJECT
21
21
22 public:
22 public:
23
23
24 class ChangeSet
24 class ChangeSet
25 {
25 {
26 public:
26 public:
27
27
28 // TODO: these should not really be exposed to the public API
28 // TODO: these should not really be exposed to the public API
29 void appendAdded(QPieSlice* slice);
29 void appendAdded(QPieSlice* slice);
30 void appendAdded(QList<QPieSlice*> slices);
30 void appendAdded(QList<QPieSlice*> slices);
31 void appendChanged(QPieSlice* slice);
31 void appendChanged(QPieSlice* slice);
32 void appendRemoved(QPieSlice* slice);
32 void appendRemoved(QPieSlice* slice);
33
33
34 QList<QPieSlice*> added() const;
34 QList<QPieSlice*> added() const;
35 QList<QPieSlice*> changed() const;
35 QList<QPieSlice*> changed() const;
36 QList<QPieSlice*> removed() const;
36 QList<QPieSlice*> removed() const;
37
37
38 bool isEmpty() const;
38 bool isEmpty() const;
39
39
40 private:
40 private:
41 QList<QPieSlice*> m_added;
41 QList<QPieSlice*> m_added;
42 QList<QPieSlice*> m_changed;
42 QList<QPieSlice*> m_changed;
43 QList<QPieSlice*> m_removed;
43 QList<QPieSlice*> m_removed;
44 };
44 };
45
45
46 public:
46 public:
47 QPieSeries(QObject *parent = 0);
47 QPieSeries(QObject *parent = 0);
48 virtual ~QPieSeries();
48 virtual ~QPieSeries();
49
49
50 public: // from QChartSeries
50 public: // from QChartSeries
51 QSeriesType type() const;
51 QSeriesType type() const;
52
52
53 public:
53 public:
54
54
55 // slice setters
55 // slice setters
56 void add(QPieSlice* slice);
56 void add(QPieSlice* slice);
57 void add(QList<QPieSlice*> slices);
57 void add(QList<QPieSlice*> slices);
58 void replace(QList<QPieSlice*> slices);
58 void replace(QList<QPieSlice*> slices);
59 void remove(QPieSlice* slice);
59 void remove(QPieSlice* slice);
60 void clear();
60 void clear();
61
61
62 // sluce getters
62 // sluce getters
63 QList<QPieSlice*> slices() const;
63 QList<QPieSlice*> slices() const;
64
64
65 // calculated data
65 // calculated data
66 int count() const;
66 int count() const;
67 qreal total() const;
67 qreal total() const;
68
68
69 // pie customization
69 // pie customization
70 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
70 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
71 qreal pieHorizontalPosition() const;
71 qreal pieHorizontalPosition() const;
72 qreal pieVerticalPosition() const;
72 qreal pieVerticalPosition() const;
73 void setPieSize(qreal relativeSize);
73 void setPieSize(qreal relativeSize);
74 qreal pieSize() const;
74 qreal pieSize() const;
75 void setPieStartAngle(qreal startAngle);
75 void setPieStartAngle(qreal startAngle);
76 qreal pieStartAngle() const;
76 qreal pieStartAngle() const;
77 void setPieEndAngle(qreal endAngle);
77 void setPieEndAngle(qreal endAngle);
78 qreal pieEndAngle() const;
78 qreal pieEndAngle() const;
79
79
80 // convenience function
80 // convenience function
81 QPieSeries& operator << (QPieSlice* slice);
81 QPieSeries& operator << (QPieSlice* slice);
82 QPieSlice* add(qreal value, QString name);
82 QPieSlice* add(qreal value, QString name);
83 void setLabelsVisible(bool visible = true);
83 void setLabelsVisible(bool visible = true);
84
84
85 // TODO: find slices?
85 // TODO: find slices?
86 // QList<QPieSlice*> findByValue(qreal value);
86 // QList<QPieSlice*> findByValue(qreal value);
87 // ...
87 // ...
88
88
89 // TODO: sorting slices?
89 // TODO: sorting slices?
90 // void sort(QPieSeries::SortByValue|label|??)
90 // void sort(QPieSeries::SortByValue|label|??)
91
91
92 // TODO: general graphics customization
92 // TODO: general graphics customization
93 // setDrawStyle(2d|3d)
93 // setDrawStyle(2d|3d)
94 // setDropShadows
94 // setDropShadows
95
95
96 Q_SIGNALS:
96 Q_SIGNALS:
97 void clicked(QPieSlice* slice);
97 void clicked(QPieSlice* slice);
98 void hoverEnter(QPieSlice* slice);
98 void hoverEnter(QPieSlice* slice);
99 void hoverLeave(QPieSlice* slice);
99 void hoverLeave(QPieSlice* slice);
100 void changed(); // TODO: hide this in PIMPL
100 void changed(); // TODO: hide this in PIMPL
101
101
102 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
102 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
103 void sliceChanged();
103 void sliceChanged();
104 void sliceClicked();
104 void sliceClicked();
105 void sliceHoverEnter();
105 void sliceHoverEnter();
106 void sliceHoverLeave();
106 void sliceHoverLeave();
107
107
108 private:
108 private:
109 void updateDerivativeData();
109 void updateDerivativeData();
110
110
111 private:
111 private:
112 Q_DISABLE_COPY(QPieSeries)
112 Q_DISABLE_COPY(QPieSeries)
113
113
114 // TODO: use PIML
114 // TODO: use PIML
115 friend class PiePresenter;
115 friend class PieChartItem;
116 friend class PieSlice;
116 friend class PieSlice;
117
117
118 QList<QPieSlice*> m_slices;
118 QList<QPieSlice*> m_slices;
119 qreal m_pieRelativeHorPos;
119 qreal m_pieRelativeHorPos;
120 qreal m_pieRelativeVerPos;
120 qreal m_pieRelativeVerPos;
121 qreal m_pieRelativeSize;
121 qreal m_pieRelativeSize;
122 qreal m_pieStartAngle;
122 qreal m_pieStartAngle;
123 qreal m_pieEndAngle;
123 qreal m_pieEndAngle;
124 qreal m_total;
124 qreal m_total;
125 };
125 };
126
126
127 QTCOMMERCIALCHART_END_NAMESPACE
127 QTCOMMERCIALCHART_END_NAMESPACE
128
128
129 #endif // PIESERIES_H
129 #endif // PIESERIES_H
@@ -1,91 +1,91
1 #ifndef QPIESLICE_H
1 #ifndef QPIESLICE_H
2 #define QPIESLICE_H
2 #define QPIESLICE_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QObject>
5 #include <QObject>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8 #include <QFont>
8 #include <QFont>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
12 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
15 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed)
16 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
16 Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed)
17
17
18 public:
18 public:
19 QPieSlice(QObject *parent = 0);
19 QPieSlice(QObject *parent = 0);
20 QPieSlice(qreal value, QString label, QObject *parent = 0);
20 QPieSlice(qreal value, QString label, QObject *parent = 0);
21 virtual ~QPieSlice();
21 virtual ~QPieSlice();
22
22
23 // data
23 // data
24 void setValue(qreal value);
24 void setValue(qreal value);
25 qreal value() const;
25 qreal value() const;
26 void setLabel(QString label);
26 void setLabel(QString label);
27 QString label() const;
27 QString label() const;
28 void setLabelVisible(bool visible);
28 void setLabelVisible(bool visible);
29 bool isLabelVisible() const;
29 bool isLabelVisible() const;
30 void setExploded(bool exploded);
30 void setExploded(bool exploded);
31 bool isExploded() const;
31 bool isExploded() const;
32 void setExplodeDistanceFactor(qreal factor);
32 void setExplodeDistanceFactor(qreal factor);
33 qreal explodeDistanceFactor() const;
33 qreal explodeDistanceFactor() const;
34
34
35 // generated data
35 // generated data
36 qreal percentage() const;
36 qreal percentage() const;
37 qreal startAngle() const;
37 qreal startAngle() const;
38 qreal endAngle() const;
38 qreal endAngle() const;
39
39
40 // customization
40 // customization
41 void setSlicePen(const QPen &pen);
41 void setSlicePen(const QPen &pen);
42 QPen slicePen() const;
42 QPen slicePen() const;
43 void setSliceBrush(const QBrush &brush);
43 void setSliceBrush(const QBrush &brush);
44 QBrush sliceBrush() const;
44 QBrush sliceBrush() const;
45 void setLabelArmPen(const QPen &pen);
45 void setLabelArmPen(const QPen &pen);
46 QPen labelArmPen() const;
46 QPen labelArmPen() const;
47 void setLabelFont(const QFont &font);
47 void setLabelFont(const QFont &font);
48 QFont labelFont() const;
48 QFont labelFont() const;
49 void setLabelArmLengthFactor(qreal factor);
49 void setLabelArmLengthFactor(qreal factor);
50 qreal labelArmLengthFactor() const;
50 qreal labelArmLengthFactor() const;
51
51
52 // TODO: label position in general
52 // TODO: label position in general
53 // setLabelFlags(inside|outside|labelArmOn|labelArmOff|???)
53 // setLabelFlags(inside|outside|labelArmOn|labelArmOff|???)
54 // setLabelOrientation(horizontal|vertical|same as slice center angle|???)
54 // setLabelOrientation(horizontal|vertical|same as slice center angle|???)
55
55
56 Q_SIGNALS:
56 Q_SIGNALS:
57 void clicked();
57 void clicked();
58 void hoverEnter();
58 void hoverEnter();
59 void hoverLeave();
59 void hoverLeave();
60 void changed();
60 void changed();
61
61
62 private:
62 private:
63
63
64 // TODO: use private class
64 // TODO: use private class
65 friend class QPieSeries;
65 friend class QPieSeries;
66 friend class PiePresenter;
66 friend class PieChartItem;
67 friend class PieSlice;
67 friend class PieSlice;
68
68
69 // data
69 // data
70 qreal m_value;
70 qreal m_value;
71 QString m_label;
71 QString m_label;
72 bool m_isLabelVisible;
72 bool m_isLabelVisible;
73 bool m_isExploded;
73 bool m_isExploded;
74 qreal m_explodeDistanceFactor;
74 qreal m_explodeDistanceFactor;
75
75
76 // generated data
76 // generated data
77 qreal m_percentage;
77 qreal m_percentage;
78 qreal m_startAngle;
78 qreal m_startAngle;
79 qreal m_angleSpan;
79 qreal m_angleSpan;
80
80
81 // customization
81 // customization
82 QPen m_slicePen;
82 QPen m_slicePen;
83 QBrush m_sliceBrush;
83 QBrush m_sliceBrush;
84 QFont m_labelFont;
84 QFont m_labelFont;
85 QPen m_labelArmPen;
85 QPen m_labelArmPen;
86 qreal m_labelArmLengthFactor;
86 qreal m_labelArmLengthFactor;
87 };
87 };
88
88
89 QTCOMMERCIALCHART_END_NAMESPACE
89 QTCOMMERCIALCHART_END_NAMESPACE
90
90
91 #endif // QPIESLICE_H
91 #endif // QPIESLICE_H
General Comments 0
You need to be logged in to leave comments. Login now