##// END OF EJS Templates
Fixed bug with changing theme when several series exist
Tero Ahola -
r538:3b2495c81f70
parent child
Show More
@@ -1,302 +1,315
1 #include "chartdataset_p.h"
1 #include "chartdataset_p.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 //series
3 //series
4 #include "qlineseries.h"
4 #include "qlineseries.h"
5 #include "qareaseries.h"
5 #include "qareaseries.h"
6 #include "qbarseries.h"
6 #include "qbarseries.h"
7 #include "qstackedbarseries.h"
7 #include "qstackedbarseries.h"
8 #include "qpercentbarseries.h"
8 #include "qpercentbarseries.h"
9 #include "qpieseries.h"
9 #include "qpieseries.h"
10 #include "qscatterseries.h"
10 #include "qscatterseries.h"
11 #include "qsplineseries.h"
11 #include "qsplineseries.h"
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
16 m_axisX(new QChartAxis(this)),
16 m_axisX(new QChartAxis(this)),
17 m_axisY(new QChartAxis(this)),
17 m_axisY(new QChartAxis(this)),
18 m_domainIndex(0),
18 m_domainIndex(0),
19 m_axisXInitialized(false)
19 m_axisXInitialized(false)
20 {
20 {
21 }
21 }
22
22
23 ChartDataSet::~ChartDataSet()
23 ChartDataSet::~ChartDataSet()
24 {
24 {
25 }
25 }
26
26
27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
28 {
28 {
29 if(axisY==0) axisY = m_axisY;
29 if(axisY==0) axisY = m_axisY;
30
30
31 QChartAxis* axis = m_seriesAxisMap.value(series);
31 QChartAxis* axis = m_seriesAxisMap.value(series);
32
32
33 if(axis) {
33 if(axis) {
34 qWarning() << "Can not add series. Series already on the chart";
34 qWarning() << "Can not add series. Series already on the chart";
35 return;
35 return;
36 }
36 }
37
37
38 if(!series->parent()){
38 if(!series->parent()){
39 series->setParent(this); // take ownership
39 series->setParent(this); // take ownership
40 };
40 };
41
41
42 if(!axisY->parent()){
42 if(!axisY->parent()){
43 axisY->setParent(this); // take ownership
43 axisY->setParent(this); // take ownership
44 }
44 }
45
45
46 Domain* domain = m_axisDomainMap.value(axisY);
46 Domain* domain = m_axisDomainMap.value(axisY);
47
47
48 if(!domain) {
48 if(!domain) {
49 domain = new Domain();
49 domain = new Domain();
50 QObject::connect(axisY,SIGNAL(rangeChanged(qreal,qreal,int)),domain,SLOT(handleAxisRangeYChanged(qreal,qreal,int)));
50 QObject::connect(axisY,SIGNAL(rangeChanged(qreal,qreal,int)),domain,SLOT(handleAxisRangeYChanged(qreal,qreal,int)));
51 QObject::connect(axisX(),SIGNAL(rangeChanged(qreal,qreal,int)),domain,SLOT(handleAxisRangeXChanged(qreal,qreal,int)));
51 QObject::connect(axisX(),SIGNAL(rangeChanged(qreal,qreal,int)),domain,SLOT(handleAxisRangeXChanged(qreal,qreal,int)));
52 //initialize
52 //initialize
53 m_axisDomainMap.insert(axisY,domain);
53 m_axisDomainMap.insert(axisY,domain);
54 emit axisAdded(axisY,domain);
54 emit axisAdded(axisY,domain);
55 }
55 }
56
56
57 if(!m_axisXInitialized){
57 if(!m_axisXInitialized){
58 emit axisAdded(axisX(),domain);
58 emit axisAdded(axisX(),domain);
59 m_axisXInitialized=true;
59 m_axisXInitialized=true;
60 }
60 }
61
61
62 calculateDomain(series,domain);
62 calculateDomain(series,domain);
63
63
64 m_seriesAxisMap.insert(series,axisY);
64 m_seriesAxisMap.insert(series,axisY);
65 emit seriesAdded(series,domain);
65 emit seriesAdded(series,domain);
66
66
67 }
67 }
68
68
69 void ChartDataSet::removeSeries(QSeries* series)
69 void ChartDataSet::removeSeries(QSeries* series)
70 {
70 {
71
71
72 QChartAxis* axis = m_seriesAxisMap.value(series);
72 QChartAxis* axis = m_seriesAxisMap.value(series);
73
73
74 if(!axis){
74 if(!axis){
75 qWarning()<<"Can not remove series. Series not found on the chart.";
75 qWarning()<<"Can not remove series. Series not found on the chart.";
76 return;
76 return;
77 }
77 }
78 emit seriesRemoved(series);
78 emit seriesRemoved(series);
79 m_seriesAxisMap.remove(series);
79 m_seriesAxisMap.remove(series);
80
80
81 if(series->parent()==this){
81 if(series->parent()==this){
82 delete series;
82 delete series;
83 series=0;
83 series=0;
84 }
84 }
85
85
86 QList<QChartAxis*> axes = m_seriesAxisMap.values();
86 QList<QChartAxis*> axes = m_seriesAxisMap.values();
87
87
88 int i = axes.indexOf(axis);
88 int i = axes.indexOf(axis);
89
89
90 if(i==-1){
90 if(i==-1){
91 Domain* domain = m_axisDomainMap.take(axis);
91 Domain* domain = m_axisDomainMap.take(axis);
92 emit axisRemoved(axis);
92 emit axisRemoved(axis);
93 if(axis!=axisY()){
93 if(axis!=axisY()){
94 if(axis->parent()==this){
94 if(axis->parent()==this){
95 delete axis;
95 delete axis;
96 axis=0;
96 axis=0;
97 }
97 }
98 }
98 }
99 delete domain;
99 delete domain;
100 }
100 }
101
101
102 if(m_seriesAxisMap.values().size()==0)
102 if(m_seriesAxisMap.values().size()==0)
103 {
103 {
104 m_axisXInitialized=false;
104 m_axisXInitialized=false;
105 emit axisRemoved(axisX());
105 emit axisRemoved(axisX());
106 }
106 }
107 }
107 }
108
108
109 void ChartDataSet::removeAllSeries()
109 void ChartDataSet::removeAllSeries()
110 {
110 {
111
111
112 QList<QSeries*> series = m_seriesAxisMap.keys();
112 QList<QSeries*> series = m_seriesAxisMap.keys();
113
113
114 foreach(QSeries* s , series) {
114 foreach(QSeries* s , series) {
115 removeSeries(s);
115 removeSeries(s);
116 }
116 }
117
117
118 Q_ASSERT(m_seriesAxisMap.count()==0);
118 Q_ASSERT(m_seriesAxisMap.count()==0);
119 Q_ASSERT(m_axisDomainMap.count()==0);
119 Q_ASSERT(m_axisDomainMap.count()==0);
120
120
121 }
121 }
122
122
123 //to be removed with PIMPL
123 //to be removed with PIMPL
124 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain) const
124 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain) const
125 {
125 {
126 switch(series->type())
126 switch(series->type())
127 {
127 {
128 case QSeries::SeriesTypeLine:
128 case QSeries::SeriesTypeLine:
129 case QSeries::SeriesTypeSpline:
129 case QSeries::SeriesTypeSpline:
130 case QSeries::SeriesTypeScatter:
130 case QSeries::SeriesTypeScatter:
131 {
131 {
132
132
133 QXYSeries* xySeries = static_cast<QXYSeries*>(series);
133 QXYSeries* xySeries = static_cast<QXYSeries*>(series);
134
134
135 qreal minX(domain->minX());
135 qreal minX(domain->minX());
136 qreal minY(domain->minY());
136 qreal minY(domain->minY());
137 qreal maxX(domain->maxX());
137 qreal maxX(domain->maxX());
138 qreal maxY(domain->maxY());
138 qreal maxY(domain->maxY());
139
139
140 for (int i = 0; i < xySeries->count(); i++)
140 for (int i = 0; i < xySeries->count(); i++)
141 {
141 {
142 qreal x = xySeries->x(i);
142 qreal x = xySeries->x(i);
143 qreal y = xySeries->y(i);
143 qreal y = xySeries->y(i);
144 minX = qMin(minX, x);
144 minX = qMin(minX, x);
145 minY = qMin(minY, y);
145 minY = qMin(minY, y);
146 maxX = qMax(maxX, x);
146 maxX = qMax(maxX, x);
147 maxY = qMax(maxY, y);
147 maxY = qMax(maxY, y);
148 }
148 }
149
149
150 domain->setRange(minX, maxX, minY, maxY);
150 domain->setRange(minX, maxX, minY, maxY);
151 break;
151 break;
152 }
152 }
153 case QSeries::SeriesTypeArea: {
153 case QSeries::SeriesTypeArea: {
154
154
155 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
155 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
156
156
157 QLineSeries* upperSeries = areaSeries->upperSeries();
157 QLineSeries* upperSeries = areaSeries->upperSeries();
158 QLineSeries* lowerSeries = areaSeries->lowerSeries();
158 QLineSeries* lowerSeries = areaSeries->lowerSeries();
159
159
160 for (int i = 0; i < upperSeries->count(); i++)
160 for (int i = 0; i < upperSeries->count(); i++)
161 {
161 {
162 qreal x = upperSeries->x(i);
162 qreal x = upperSeries->x(i);
163 qreal y = upperSeries->y(i);
163 qreal y = upperSeries->y(i);
164 domain->setMinX(qMin(domain->minX(),x));
164 domain->setMinX(qMin(domain->minX(),x));
165 domain->setMinY(qMin(domain->minY(),y));
165 domain->setMinY(qMin(domain->minY(),y));
166 domain->setMaxX(qMax(domain->maxX(),x));
166 domain->setMaxX(qMax(domain->maxX(),x));
167 domain->setMaxY(qMax(domain->maxY(),y));
167 domain->setMaxY(qMax(domain->maxY(),y));
168 }
168 }
169 if(lowerSeries) {
169 if(lowerSeries) {
170 for (int i = 0; i < lowerSeries->count(); i++)
170 for (int i = 0; i < lowerSeries->count(); i++)
171 {
171 {
172 qreal x = lowerSeries->x(i);
172 qreal x = lowerSeries->x(i);
173 qreal y = lowerSeries->y(i);
173 qreal y = lowerSeries->y(i);
174 domain->setMinX(qMin(domain->minX(),x));
174 domain->setMinX(qMin(domain->minX(),x));
175 domain->setMinY(qMin(domain->minY(),y));
175 domain->setMinY(qMin(domain->minY(),y));
176 domain->setMaxX(qMax(domain->maxX(),x));
176 domain->setMaxX(qMax(domain->maxX(),x));
177 domain->setMaxY(qMax(domain->maxY(),y));
177 domain->setMaxY(qMax(domain->maxY(),y));
178 }}
178 }}
179 break;
179 break;
180 }
180 }
181 case QSeries::SeriesTypeBar: {
181 case QSeries::SeriesTypeBar: {
182 qDebug() << "QChartSeries::SeriesTypeBar";
182 qDebug() << "QChartSeries::SeriesTypeBar";
183 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
183 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
184 qreal x = barSeries->categoryCount();
184 qreal x = barSeries->categoryCount();
185 qreal y = barSeries->max();
185 qreal y = barSeries->max();
186 domain->setMinX(qMin(domain->minX(),x));
186 domain->setMinX(qMin(domain->minX(),x));
187 domain->setMinY(qMin(domain->minY(),y));
187 domain->setMinY(qMin(domain->minY(),y));
188 domain->setMaxX(qMax(domain->maxX(),x));
188 domain->setMaxX(qMax(domain->maxX(),x));
189 domain->setMaxY(qMax(domain->maxY(),y));
189 domain->setMaxY(qMax(domain->maxY(),y));
190 break;
190 break;
191 }
191 }
192 case QSeries::SeriesTypeStackedBar: {
192 case QSeries::SeriesTypeStackedBar: {
193 qDebug() << "QChartSeries::SeriesTypeStackedBar";
193 qDebug() << "QChartSeries::SeriesTypeStackedBar";
194
194
195 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
195 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
196 qreal x = stackedBarSeries->categoryCount();
196 qreal x = stackedBarSeries->categoryCount();
197 qreal y = stackedBarSeries->maxCategorySum();
197 qreal y = stackedBarSeries->maxCategorySum();
198 domain->setMinX(qMin(domain->minX(),x));
198 domain->setMinX(qMin(domain->minX(),x));
199 domain->setMinY(qMin(domain->minY(),y));
199 domain->setMinY(qMin(domain->minY(),y));
200 domain->setMaxX(qMax(domain->maxX(),x));
200 domain->setMaxX(qMax(domain->maxX(),x));
201 domain->setMaxY(qMax(domain->maxY(),y));
201 domain->setMaxY(qMax(domain->maxY(),y));
202 break;
202 break;
203 }
203 }
204 case QSeries::SeriesTypePercentBar: {
204 case QSeries::SeriesTypePercentBar: {
205 qDebug() << "QChartSeries::SeriesTypePercentBar";
205 qDebug() << "QChartSeries::SeriesTypePercentBar";
206
206
207 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
207 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
208 qreal x = percentBarSeries->categoryCount();
208 qreal x = percentBarSeries->categoryCount();
209 domain->setMinX(qMin(domain->minX(),x));
209 domain->setMinX(qMin(domain->minX(),x));
210 domain->setMinY(0);
210 domain->setMinY(0);
211 domain->setMaxX(qMax(domain->maxX(),x));
211 domain->setMaxX(qMax(domain->maxX(),x));
212 domain->setMaxY(100);
212 domain->setMaxY(100);
213 break;
213 break;
214 }
214 }
215
215
216 case QSeries::SeriesTypePie: {
216 case QSeries::SeriesTypePie: {
217 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
217 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
218 // TODO: domain stuff
218 // TODO: domain stuff
219 break;
219 break;
220 }
220 }
221
221
222
222
223 default: {
223 default: {
224 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
224 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
225 return;
225 return;
226 break;
226 break;
227 }
227 }
228
228
229 }
229 }
230 }
230 }
231
231
232 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
232 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
233 {
233 {
234 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
234 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
235 while (i.hasNext()) {
235 while (i.hasNext()) {
236 i.next();
236 i.next();
237 i.value()->zoomIn(rect,size);
237 i.value()->zoomIn(rect,size);
238 }
238 }
239 }
239 }
240
240
241 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
241 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
242 {
242 {
243 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
243 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
244 while (i.hasNext()) {
244 while (i.hasNext()) {
245 i.next();
245 i.next();
246 i.value()->zoomOut(rect,size);
246 i.value()->zoomOut(rect,size);
247 }
247 }
248 }
248 }
249
249
250 int ChartDataSet::seriesCount(QSeries::QSeriesType type)
250 int ChartDataSet::seriesCount(QSeries::QSeriesType type)
251 {
251 {
252 int count=0;
252 int count=0;
253 QMapIterator<QSeries*, QChartAxis*> i( m_seriesAxisMap);
253 QMapIterator<QSeries*, QChartAxis*> i( m_seriesAxisMap);
254 while (i.hasNext()) {
254 while (i.hasNext()) {
255 i.next();
255 i.next();
256 if(i.key()->type()==type) count++;
256 if(i.key()->type()==type) count++;
257 }
257 }
258 return count;
258 return count;
259 }
259 }
260
260
261 int ChartDataSet::seriesIndex(QSeries *series)
262 {
263 int count(-1);
264 QMapIterator<QSeries*, QChartAxis*> i(m_seriesAxisMap);
265 while (i.hasNext()) {
266 i.next();
267 count++;
268 if (i.key() == series)
269 return count;
270 }
271 return count;
272 }
273
261 QChartAxis* ChartDataSet::axisY(QSeries* series) const
274 QChartAxis* ChartDataSet::axisY(QSeries* series) const
262 {
275 {
263 if(series == 0) return m_axisY;
276 if(series == 0) return m_axisY;
264 return m_seriesAxisMap.value(series);
277 return m_seriesAxisMap.value(series);
265 }
278 }
266
279
267 Domain* ChartDataSet::domain(QSeries* series) const
280 Domain* ChartDataSet::domain(QSeries* series) const
268 {
281 {
269 QChartAxis* axis = m_seriesAxisMap.value(series);
282 QChartAxis* axis = m_seriesAxisMap.value(series);
270 if(axis){
283 if(axis){
271 return m_axisDomainMap.value(axis);
284 return m_axisDomainMap.value(axis);
272 }else
285 }else
273 return 0;
286 return 0;
274 }
287 }
275
288
276 Domain* ChartDataSet::domain(QChartAxis* axis) const
289 Domain* ChartDataSet::domain(QChartAxis* axis) const
277 {
290 {
278 if(axis==axisX()) {
291 if(axis==axisX()) {
279 return m_axisDomainMap.value(axisY());
292 return m_axisDomainMap.value(axisY());
280 }
293 }
281 else {
294 else {
282 return m_axisDomainMap.value(axis);
295 return m_axisDomainMap.value(axis);
283 }
296 }
284 }
297 }
285
298
286 QChartAxis* ChartDataSet::axis(QSeries* series) const
299 QChartAxis* ChartDataSet::axis(QSeries* series) const
287 {
300 {
288 return m_seriesAxisMap.value(series);
301 return m_seriesAxisMap.value(series);
289 }
302 }
290
303
291 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
304 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
292 {
305 {
293 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
306 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
294 while (i.hasNext()) {
307 while (i.hasNext()) {
295 i.next();
308 i.next();
296 i.value()->move(dx,dy,size);
309 i.value()->move(dx,dy,size);
297 }
310 }
298 }
311 }
299
312
300 #include "moc_chartdataset_p.cpp"
313 #include "moc_chartdataset_p.cpp"
301
314
302 QTCOMMERCIALCHART_END_NAMESPACE
315 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,58 +1,59
1 #ifndef CHARTDATASET_P_H_
1 #ifndef CHARTDATASET_P_H_
2 #define CHARTDATASET_P_H_
2 #define CHARTDATASET_P_H_
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include "domain_p.h"
5 #include "domain_p.h"
6 #include <QVector>
6 #include <QVector>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QChartAxis;
10 class QChartAxis;
11
11
12 class ChartDataSet : public QObject
12 class ChartDataSet : public QObject
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 public:
15 public:
16 ChartDataSet(QObject* parent=0);
16 ChartDataSet(QObject* parent=0);
17 virtual ~ChartDataSet();
17 virtual ~ChartDataSet();
18
18
19 void addSeries(QSeries* series,QChartAxis *axisY = 0);
19 void addSeries(QSeries* series,QChartAxis *axisY = 0);
20 void removeSeries(QSeries* series);
20 void removeSeries(QSeries* series);
21 void removeAllSeries();
21 void removeAllSeries();
22
22
23 void zoomInDomain(const QRectF& rect, const QSizeF& size);
23 void zoomInDomain(const QRectF& rect, const QSizeF& size);
24 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
24 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
25 void scrollDomain(int dx,int dy,const QSizeF& size);
25 void scrollDomain(int dx,int dy,const QSizeF& size);
26
26
27 int seriesCount(QSeries::QSeriesType type);
27 int seriesCount(QSeries::QSeriesType type);
28 int seriesIndex(QSeries *series);
28
29
29 Domain* domain(QSeries* series) const;
30 Domain* domain(QSeries* series) const;
30 Domain* domain(QChartAxis* axis) const;
31 Domain* domain(QChartAxis* axis) const;
31 QChartAxis* axis(QSeries* series) const;
32 QChartAxis* axis(QSeries* series) const;
32
33
33 QChartAxis* axisX() const { return m_axisX;};
34 QChartAxis* axisX() const { return m_axisX;};
34 QChartAxis* axisY(QSeries* series = 0) const;
35 QChartAxis* axisY(QSeries* series = 0) const;
35
36
36 signals:
37 signals:
37 void seriesAdded(QSeries* series,Domain* domain);
38 void seriesAdded(QSeries* series,Domain* domain);
38 void seriesRemoved(QSeries* series);
39 void seriesRemoved(QSeries* series);
39 void axisAdded(QChartAxis* axis,Domain* domain);
40 void axisAdded(QChartAxis* axis,Domain* domain);
40 void axisRemoved(QChartAxis* axis);
41 void axisRemoved(QChartAxis* axis);
41
42
42 private:
43 private:
43 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
44 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
44 void calculateDomain(QSeries* series,Domain* domain) const;
45 void calculateDomain(QSeries* series,Domain* domain) const;
45
46
46 private:
47 private:
47 QMap<QSeries*, QChartAxis*> m_seriesAxisMap;
48 QMap<QSeries*, QChartAxis*> m_seriesAxisMap;
48 QMap<QChartAxis*, Domain*> m_axisDomainMap;
49 QMap<QChartAxis*, Domain*> m_axisDomainMap;
49 QChartAxis* m_axisX;
50 QChartAxis* m_axisX;
50 QChartAxis* m_axisY;
51 QChartAxis* m_axisY;
51
52
52 int m_domainIndex;
53 int m_domainIndex;
53 bool m_axisXInitialized;
54 bool m_axisXInitialized;
54 };
55 };
55
56
56 QTCOMMERCIALCHART_END_NAMESPACE
57 QTCOMMERCIALCHART_END_NAMESPACE
57
58
58 #endif /* CHARTENGINE_P_H_ */
59 #endif /* CHARTENGINE_P_H_ */
@@ -1,390 +1,389
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 "piepresenter_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 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
108 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
109 //initialize
109 //initialize
110 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
110 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
111 }
111 }
112 else{
112 else{
113 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
113 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
114 //initialize
114 //initialize
115 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
115 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
116 }
116 }
117
117
118 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
118 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
119 //initialize
119 //initialize
120 item->handleGeometryChanged(m_rect);
120 item->handleGeometryChanged(m_rect);
121 m_chartTheme->decorate(axis,item);
121 m_chartTheme->decorate(axis,item);
122 m_axisItems.insert(axis,item);
122 m_axisItems.insert(axis,item);
123
123
124 }
124 }
125
125
126 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
126 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
127 {
127 {
128 AxisItem* item = m_axisItems.take(axis);
128 AxisItem* item = m_axisItems.take(axis);
129 Q_ASSERT(item);
129 Q_ASSERT(item);
130 if(m_animator) m_animator->removeAnimation(item);
130 if(m_animator) m_animator->removeAnimation(item);
131 delete item;
131 delete item;
132 }
132 }
133
133
134
134
135 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
135 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
136 {
136 {
137 ChartItem *item = 0 ;
137 ChartItem *item = 0 ;
138
138
139 switch(series->type())
139 switch(series->type())
140 {
140 {
141 case QSeries::SeriesTypeLine: {
141 case QSeries::SeriesTypeLine: {
142
142
143 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
143 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
144 LineChartItem* line = new LineChartItem(lineSeries,m_chart);
144 LineChartItem* line = new LineChartItem(lineSeries,m_chart);
145 if(m_options.testFlag(QChart::SeriesAnimations)) {
145 if(m_options.testFlag(QChart::SeriesAnimations)) {
146 m_animator->addAnimation(line);
146 m_animator->addAnimation(line);
147 }
147 }
148 m_chartTheme->decorate(line,lineSeries,m_dataset->seriesCount(series->type()));
148 m_chartTheme->decorate(line, lineSeries, m_dataset->seriesIndex(series));
149 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
149 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
150 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
150 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
151 item = line;
151 item = line;
152 break;
152 break;
153 }
153 }
154
154
155 case QSeries::SeriesTypeArea: {
155 case QSeries::SeriesTypeArea: {
156
156
157 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
157 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
158 AreaChartItem* area = new AreaChartItem(areaSeries,m_chart);
158 AreaChartItem* area = new AreaChartItem(areaSeries,m_chart);
159 if(m_options.testFlag(QChart::SeriesAnimations)) {
159 if(m_options.testFlag(QChart::SeriesAnimations)) {
160 // m_animator->addAnimation(area);
160 // m_animator->addAnimation(area);
161 }
161 }
162 m_chartTheme->decorate(area,areaSeries,m_dataset->seriesCount(series->type()));
162 m_chartTheme->decorate(area, areaSeries, m_dataset->seriesIndex(series));
163 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
163 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
164 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
164 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
165 item=area;
165 item=area;
166 break;
166 break;
167 }
167 }
168
168
169 case QSeries::SeriesTypeBar: {
169 case QSeries::SeriesTypeBar: {
170 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
170 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
171 BarPresenter* bar = new BarPresenter(barSeries,m_chart);
171 BarPresenter* bar = new BarPresenter(barSeries,m_chart);
172 if(m_options.testFlag(QChart::SeriesAnimations)) {
172 if(m_options.testFlag(QChart::SeriesAnimations)) {
173 // m_animator->addAnimation(bar);
173 // m_animator->addAnimation(bar);
174 }
174 }
175 m_chartTheme->decorate(bar,barSeries,m_dataset->seriesCount(series->type()));
175 m_chartTheme->decorate(bar, barSeries, m_dataset->seriesIndex(barSeries));
176 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
176 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
177 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
177 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
178 item=bar;
178 item=bar;
179 break;
179 break;
180 }
180 }
181
181
182 case QSeries::SeriesTypeStackedBar: {
182 case QSeries::SeriesTypeStackedBar: {
183 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
183 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
184 StackedBarPresenter* bar = new StackedBarPresenter(stackedBarSeries,m_chart);
184 StackedBarPresenter* bar = new StackedBarPresenter(stackedBarSeries,m_chart);
185 if(m_options.testFlag(QChart::SeriesAnimations)) {
185 if(m_options.testFlag(QChart::SeriesAnimations)) {
186 // m_animator->addAnimation(bar);
186 // m_animator->addAnimation(bar);
187 }
187 }
188 m_chartTheme->decorate(bar,stackedBarSeries,m_dataset->seriesCount(series->type()));
188 m_chartTheme->decorate(bar, stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries));
189 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
189 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
190 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
190 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
191 item=bar;
191 item=bar;
192 break;
192 break;
193 }
193 }
194
194
195 case QSeries::SeriesTypePercentBar: {
195 case QSeries::SeriesTypePercentBar: {
196 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
196 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
197 PercentBarPresenter* bar = new PercentBarPresenter(percentBarSeries,m_chart);
197 PercentBarPresenter* bar = new PercentBarPresenter(percentBarSeries,m_chart);
198 if(m_options.testFlag(QChart::SeriesAnimations)) {
198 if(m_options.testFlag(QChart::SeriesAnimations)) {
199 // m_animator->addAnimation(bar);
199 // m_animator->addAnimation(bar);
200 }
200 }
201 m_chartTheme->decorate(bar,percentBarSeries ,m_dataset->seriesCount(series->type()));
201 m_chartTheme->decorate(bar, percentBarSeries, m_dataset->seriesIndex(percentBarSeries));
202 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
202 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
203 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
203 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
204 item=bar;
204 item=bar;
205 break;
205 break;
206 }
206 }
207
207
208 case QSeries::SeriesTypeScatter: {
208 case QSeries::SeriesTypeScatter: {
209 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
209 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
210 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries, m_chart);
210 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries, m_chart);
211 if(m_options.testFlag(QChart::SeriesAnimations)) {
211 if(m_options.testFlag(QChart::SeriesAnimations)) {
212 m_animator->addAnimation(scatter);
212 m_animator->addAnimation(scatter);
213 }
213 }
214 m_chartTheme->decorate(scatter, scatterSeries, m_dataset->seriesCount(series->type()));
214 m_chartTheme->decorate(scatter, scatterSeries, m_dataset->seriesIndex(series));
215 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
215 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
216 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
216 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
217 item=scatter;
217 item = scatter;
218 break;
218 break;
219 }
219 }
220
220
221 case QSeries::SeriesTypePie: {
221 case QSeries::SeriesTypePie: {
222 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
222 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
223 PiePresenter* pie = new PiePresenter(m_chart, pieSeries);
223 PiePresenter* pie = new PiePresenter(m_chart, pieSeries);
224 if(m_options.testFlag(QChart::SeriesAnimations)) {
224 if(m_options.testFlag(QChart::SeriesAnimations)) {
225 // m_animator->addAnimation(pie);
225 // m_animator->addAnimation(pie);
226 }
226 }
227 m_chartTheme->decorate(pie, pieSeries, m_dataset->seriesCount(series->type()));
227 m_chartTheme->decorate(pie, pieSeries, m_dataset->seriesIndex(series));
228 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
228 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
229 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
229 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
230 // Hide all from background when there is only piechart
230 // Hide all from background when there is only piechart
231 // TODO: refactor this ugly code... should be one setting for this
231 // TODO: refactor this ugly code... should be one setting for this
232 if (m_chartItems.count() == 0) {
232 if (m_chartItems.count() == 0) {
233 m_chart->axisX()->hide();
233 m_chart->axisX()->hide();
234 m_chart->axisY()->hide();
234 m_chart->axisY()->hide();
235 m_chart->setChartBackgroundBrush(Qt::transparent);
235 m_chart->setChartBackgroundBrush(Qt::transparent);
236 }
236 }
237 item=pie;
237 item=pie;
238 break;
238 break;
239 }
239 }
240
240
241 case QSeries::SeriesTypeSpline: {
241 case QSeries::SeriesTypeSpline: {
242
242 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
243 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
243 SplineChartItem* spline = new SplineChartItem(splineSeries, m_chart);
244 SplineChartItem* spline = new SplineChartItem(splineSeries, m_chart);
244 if(m_options.testFlag(QChart::SeriesAnimations)) {
245 if(m_options.testFlag(QChart::SeriesAnimations)) {
245 m_animator->addAnimation(spline);
246 m_animator->addAnimation(spline);
246 }
247 }
247 m_chartTheme->decorate(spline, splineSeries, m_dataset->seriesIndex(series));
248 m_chartTheme->decorate(spline, splineSeries, m_dataset->seriesCount(series->type()));
248 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
249 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
249 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
250 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
250 item=spline;
251 item=spline;
251 break;
252 break;
252 }
253 }
254 default: {
253 default: {
255 qDebug()<< "Series type" << series->type() << "not implemented.";
254 qDebug()<< "Series type" << series->type() << "not implemented.";
256 break;
255 break;
257 }
256 }
258 }
257 }
259
258
260 //initialize
259 //initialize
261 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
260 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
262 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
261 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
263 m_chartItems.insert(series,item);
262 m_chartItems.insert(series,item);
264 zoomReset();
263 zoomReset();
265 }
264 }
266
265
267 void ChartPresenter::handleSeriesRemoved(QSeries* series)
266 void ChartPresenter::handleSeriesRemoved(QSeries* series)
268 {
267 {
269 ChartItem* item = m_chartItems.take(series);
268 ChartItem* item = m_chartItems.take(series);
270 Q_ASSERT(item);
269 Q_ASSERT(item);
271 if(m_animator) m_animator->removeAnimation(item);
270 if(m_animator) m_animator->removeAnimation(item);
272 delete item;
271 delete item;
273 }
272 }
274
273
275 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
274 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
276 {
275 {
277 if(m_chartTheme && m_chartTheme->id() == theme) return;
276 if(m_chartTheme && m_chartTheme->id() == theme) return;
278 delete m_chartTheme;
277 delete m_chartTheme;
279 m_chartTheme = ChartTheme::createTheme(theme);
278 m_chartTheme = ChartTheme::createTheme(theme);
280 m_chartTheme->decorate(m_chart);
279 m_chartTheme->decorate(m_chart);
281 resetAllElements();
280 resetAllElements();
282 }
281 }
283
282
284 QChart::ChartTheme ChartPresenter::chartTheme()
283 QChart::ChartTheme ChartPresenter::chartTheme()
285 {
284 {
286 return m_chartTheme->id();
285 return m_chartTheme->id();
287 }
286 }
288
287
289 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
288 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
290 {
289 {
291 if(m_options!=options) {
290 if(m_options!=options) {
292
291
293 m_options=options;
292 m_options=options;
294
293
295 if(m_options!=QChart::NoAnimation && !m_animator) {
294 if(m_options!=QChart::NoAnimation && !m_animator) {
296 m_animator= new ChartAnimator(this);
295 m_animator= new ChartAnimator(this);
297
296
298 }
297 }
299 resetAllElements();
298 resetAllElements();
300 }
299 }
301
300
302 }
301 }
303
302
304 void ChartPresenter::resetAllElements()
303 void ChartPresenter::resetAllElements()
305 {
304 {
306 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
305 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
307 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
306 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
308
307
309 foreach(QChartAxis* axis, axisList) {
308 foreach(QChartAxis* axis, axisList) {
310 handleAxisRemoved(axis);
309 handleAxisRemoved(axis);
311 handleAxisAdded(axis,m_dataset->domain(axis));
310 handleAxisAdded(axis,m_dataset->domain(axis));
312 }
311 }
313 foreach(QSeries* series, seriesList) {
312 foreach(QSeries* series, seriesList) {
314 handleSeriesRemoved(series);
313 handleSeriesRemoved(series);
315 handleSeriesAdded(series,m_dataset->domain(series));
314 handleSeriesAdded(series,m_dataset->domain(series));
316 }
315 }
317 }
316 }
318
317
319 void ChartPresenter::zoomIn()
318 void ChartPresenter::zoomIn()
320 {
319 {
321 QRectF rect = geometry();
320 QRectF rect = geometry();
322 rect.setWidth(rect.width()/2);
321 rect.setWidth(rect.width()/2);
323 rect.setHeight(rect.height()/2);
322 rect.setHeight(rect.height()/2);
324 rect.moveCenter(geometry().center());
323 rect.moveCenter(geometry().center());
325 zoomIn(rect);
324 zoomIn(rect);
326 }
325 }
327
326
328 void ChartPresenter::zoomIn(const QRectF& rect)
327 void ChartPresenter::zoomIn(const QRectF& rect)
329 {
328 {
330 QRectF r = rect.normalized();
329 QRectF r = rect.normalized();
331 r.translate(-m_marginSize, -m_marginSize);
330 r.translate(-m_marginSize, -m_marginSize);
332 if(m_animator) {
331 if(m_animator) {
333
332
334 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
333 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
335 m_animator->setState(ChartAnimator::ZoomInState,point);
334 m_animator->setState(ChartAnimator::ZoomInState,point);
336 }
335 }
337 m_dataset->zoomInDomain(r,geometry().size());
336 m_dataset->zoomInDomain(r,geometry().size());
338 m_zoomStack<<r;
337 m_zoomStack<<r;
339 m_zoomIndex++;
338 m_zoomIndex++;
340 if(m_animator) {
339 if(m_animator) {
341 m_animator->setState(ChartAnimator::ShowState);
340 m_animator->setState(ChartAnimator::ShowState);
342 }
341 }
343 }
342 }
344
343
345 void ChartPresenter::zoomOut()
344 void ChartPresenter::zoomOut()
346 {
345 {
347 if(m_zoomIndex==0) return;
346 if(m_zoomIndex==0) return;
348 if(m_animator)
347 if(m_animator)
349 {
348 {
350 m_animator->setState(ChartAnimator::ZoomOutState);
349 m_animator->setState(ChartAnimator::ZoomOutState);
351 }
350 }
352 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
351 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
353 m_zoomIndex--;
352 m_zoomIndex--;
354 m_zoomStack.resize(m_zoomIndex);
353 m_zoomStack.resize(m_zoomIndex);
355 if(m_animator){
354 if(m_animator){
356 m_animator->setState(ChartAnimator::ShowState);
355 m_animator->setState(ChartAnimator::ShowState);
357 }
356 }
358 }
357 }
359
358
360 void ChartPresenter::zoomReset()
359 void ChartPresenter::zoomReset()
361 {
360 {
362 m_zoomIndex=0;
361 m_zoomIndex=0;
363 m_zoomStack.resize(m_zoomIndex);
362 m_zoomStack.resize(m_zoomIndex);
364 }
363 }
365
364
366 void ChartPresenter::scroll(int dx,int dy)
365 void ChartPresenter::scroll(int dx,int dy)
367 {
366 {
368 if(m_animator){
367 if(m_animator){
369 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
368 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
370 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
369 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
371 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
370 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
372 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
371 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
373 }
372 }
374
373
375 m_dataset->scrollDomain(dx,dy,geometry().size());
374 m_dataset->scrollDomain(dx,dy,geometry().size());
376
375
377 if(m_animator){
376 if(m_animator){
378 m_animator->setState(ChartAnimator::ShowState);
377 m_animator->setState(ChartAnimator::ShowState);
379 }
378 }
380 }
379 }
381
380
382 QChart::AnimationOptions ChartPresenter::animationOptions() const
381 QChart::AnimationOptions ChartPresenter::animationOptions() const
383 {
382 {
384 return m_options;
383 return m_options;
385 }
384 }
386
385
387
386
388 #include "moc_chartpresenter_p.cpp"
387 #include "moc_chartpresenter_p.cpp"
389
388
390 QTCOMMERCIALCHART_END_NAMESPACE
389 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,304 +1,304
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartaxis.h"
3 #include "qchartaxis.h"
4 #include <QTime>
4 #include <QTime>
5
5
6 //series
6 //series
7 #include "qbarset.h"
7 #include "qbarset.h"
8 #include "qbarseries.h"
8 #include "qbarseries.h"
9 #include "qstackedbarseries.h"
9 #include "qstackedbarseries.h"
10 #include "qpercentbarseries.h"
10 #include "qpercentbarseries.h"
11 #include "qlineseries.h"
11 #include "qlineseries.h"
12 #include "qareaseries.h"
12 #include "qareaseries.h"
13 #include "qscatterseries.h"
13 #include "qscatterseries.h"
14 #include "qpieseries.h"
14 #include "qpieseries.h"
15 #include "qpieslice.h"
15 #include "qpieslice.h"
16 #include "qsplineseries.h"
16 #include "qsplineseries.h"
17
17
18 //items
18 //items
19 #include "axisitem_p.h"
19 #include "axisitem_p.h"
20 #include "barpresenter_p.h"
20 #include "barpresenter_p.h"
21 #include "stackedbarpresenter_p.h"
21 #include "stackedbarpresenter_p.h"
22 #include "percentbarpresenter_p.h"
22 #include "percentbarpresenter_p.h"
23 #include "linechartitem_p.h"
23 #include "linechartitem_p.h"
24 #include "areachartitem_p.h"
24 #include "areachartitem_p.h"
25 #include "scatterchartitem_p.h"
25 #include "scatterchartitem_p.h"
26 #include "piepresenter_p.h"
26 #include "piepresenter_p.h"
27 #include "splinechartitem_p.h"
27 #include "splinechartitem_p.h"
28
28
29 //themes
29 //themes
30 #include "chartthemedefault_p.h"
30 #include "chartthemedefault_p.h"
31 #include "chartthemevanilla_p.h"
31 #include "chartthemevanilla_p.h"
32 #include "chartthemeicy_p.h"
32 #include "chartthemeicy_p.h"
33 #include "chartthemegrayscale_p.h"
33 #include "chartthemegrayscale_p.h"
34 #include "chartthemescientific_p.h"
34 #include "chartthemescientific_p.h"
35
35
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 ChartTheme::ChartTheme(QChart::ChartTheme id)
39 ChartTheme::ChartTheme(QChart::ChartTheme id)
40 {
40 {
41 m_id = id;
41 m_id = id;
42 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
42 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
43 }
43 }
44
44
45
45
46 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
46 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
47 {
47 {
48 switch(theme) {
48 switch(theme) {
49 case QChart::ChartThemeVanilla:
49 case QChart::ChartThemeVanilla:
50 return new ChartThemeVanilla();
50 return new ChartThemeVanilla();
51 case QChart::ChartThemeIcy:
51 case QChart::ChartThemeIcy:
52 return new ChartThemeIcy();
52 return new ChartThemeIcy();
53 case QChart::ChartThemeGrayscale:
53 case QChart::ChartThemeGrayscale:
54 return new ChartThemeGrayscale();
54 return new ChartThemeGrayscale();
55 case QChart::ChartThemeScientific:
55 case QChart::ChartThemeScientific:
56 return new ChartThemeScientific();
56 return new ChartThemeScientific();
57 default:
57 default:
58 return new ChartThemeDefault();
58 return new ChartThemeDefault();
59 }
59 }
60 }
60 }
61
61
62 void ChartTheme::decorate(QChart* chart)
62 void ChartTheme::decorate(QChart* chart)
63 {
63 {
64 chart->setChartBackgroundBrush(m_backgroundGradient);
64 chart->setChartBackgroundBrush(m_backgroundGradient);
65 }
65 }
66
66
67 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
67 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series, int index)
68 {
68 {
69 QPen pen;
69 QPen pen;
70 QBrush brush;
70 QBrush brush;
71
71
72 if (pen != series->pen()){
72 if (pen != series->pen()){
73 item->setPen(series->pen());
73 item->setPen(series->pen());
74 } else {
74 } else {
75 pen.setColor(colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1.0));
75 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
76 pen.setWidthF(2);
76 pen.setWidthF(2);
77 item->setPen(pen);
77 item->setPen(pen);
78 }
78 }
79
79
80 if (brush != series->brush()) {
80 if (brush != series->brush()) {
81 item->setBrush(series->brush());
81 item->setBrush(series->brush());
82 } else {
82 } else {
83 QBrush brush(m_seriesColors.at(count % m_seriesColors.size()));
83 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
84 item->setBrush(brush);
84 item->setBrush(brush);
85 }
85 }
86 }
86 }
87
87
88
88
89 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
89 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int index)
90 {
90 {
91 QPen pen;
91 QPen pen;
92 if(pen != series->pen()){
92 if(pen != series->pen()){
93 item->setLinePen(series->pen());
93 item->setLinePen(series->pen());
94 return;
94 return;
95 }
95 }
96 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
96 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
97 pen.setWidthF(2);
97 pen.setWidthF(2);
98 item->setLinePen(pen);
98 item->setLinePen(pen);
99 }
99 }
100
100
101 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
101 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int index)
102 {
102 {
103 QList<QBarSet*> sets = series->barSets();
103 QList<QBarSet*> sets = series->barSets();
104 for (int i=0; i<sets.count(); i++) {
104 for (int i=0; i<sets.count(); i++) {
105 qreal pos = 0.5;
105 qreal pos = 0.5;
106 if (sets.count() > 1)
106 if (sets.count() > 1)
107 pos = (qreal) i / (qreal) (sets.count() - 1);
107 pos = (qreal) i / (qreal) (sets.count() - 1);
108 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
108 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
109 sets.at(i)->setBrush(QBrush(c));
109 sets.at(i)->setBrush(QBrush(c));
110
110
111 // Pick label color as far as possible from bar color (within gradient).
111 // Pick label color as far as possible from bar color (within gradient).
112 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
112 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
113 // TODO: better picking of label color?
113 // TODO: better picking of label color?
114 if (pos < 0.3) {
114 if (pos < 0.3) {
115 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1);
115 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
116 } else {
116 } else {
117 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0);
117 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
118 }
118 }
119 sets.at(i)->setFloatingValuePen(QPen(c));
119 sets.at(i)->setFloatingValuePen(QPen(c));
120 }
120 }
121 }
121 }
122
122
123 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
123 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int index)
124 {
124 {
125 QList<QBarSet*> sets = series->barSets();
125 QList<QBarSet*> sets = series->barSets();
126 for (int i=0; i<sets.count(); i++) {
126 for (int i=0; i<sets.count(); i++) {
127 qreal pos = 0.5;
127 qreal pos = 0.5;
128 if (sets.count() > 1)
128 if (sets.count() > 1)
129 pos = (qreal) i / (qreal) (sets.count() - 1);
129 pos = (qreal) i / (qreal) (sets.count() - 1);
130 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
130 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
131 sets.at(i)->setBrush(QBrush(c));
131 sets.at(i)->setBrush(QBrush(c));
132
132
133 if (pos < 0.3) {
133 if (pos < 0.3) {
134 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1);
134 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
135 } else {
135 } else {
136 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0);
136 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
137 }
137 }
138 sets.at(i)->setFloatingValuePen(QPen(c));
138 sets.at(i)->setFloatingValuePen(QPen(c));
139 }
139 }
140 }
140 }
141
141
142 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
142 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int index)
143 {
143 {
144 QList<QBarSet*> sets = series->barSets();
144 QList<QBarSet*> sets = series->barSets();
145 for (int i=0; i<sets.count(); i++) {
145 for (int i=0; i<sets.count(); i++) {
146 qreal pos = 0.5;
146 qreal pos = 0.5;
147 if (sets.count() > 1)
147 if (sets.count() > 1)
148 pos = (qreal) i / (qreal) (sets.count() - 1);
148 pos = (qreal) i / (qreal) (sets.count() - 1);
149 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
149 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
150 sets.at(i)->setBrush(QBrush(c));
150 sets.at(i)->setBrush(QBrush(c));
151
151
152 if (pos < 0.3) {
152 if (pos < 0.3) {
153 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1);
153 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
154 } else {
154 } else {
155 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0);
155 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
156 }
156 }
157 sets.at(i)->setFloatingValuePen(QPen(c));
157 sets.at(i)->setFloatingValuePen(QPen(c));
158 }
158 }
159 }
159 }
160
160
161 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int count)
161 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int index)
162 {
162 {
163 Q_ASSERT(item);
163 Q_ASSERT(item);
164 Q_ASSERT(series);
164 Q_ASSERT(series);
165
165
166 // Use a base color for brush
166 // Use a base color for brush
167 item->setBrush(m_seriesColors.at(count % m_seriesColors.size()));
167 item->setBrush(m_seriesColors.at(index % m_seriesColors.size()));
168
168
169 // Take pen near from gradient start, effectively using a lighter color for outline
169 // Take pen near from gradient start, effectively using a lighter color for outline
170 QPen pen(QBrush(Qt::SolidPattern), 3);
170 QPen pen(QBrush(Qt::SolidPattern), 3);
171 pen.setColor(colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1.0));
171 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
172 item->setPen(pen);
172 item->setPen(pen);
173 }
173 }
174
174
175 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int count)
175 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int index)
176 {
176 {
177 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
177 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
178 for (int i(0); i < series->slices().count(); i++) {
178 for (int i(0); i < series->slices().count(); i++) {
179 qreal pos = (qreal) i / (qreal) series->count();
179 qreal pos = (qreal) i / (qreal) series->count();
180 QColor penColor = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0.1);
180 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
181 series->slices().at(i)->setSlicePen(penColor);
181 series->slices().at(i)->setSlicePen(penColor);
182 QColor brushColor = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
182 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
183 series->slices().at(i)->setSliceBrush(brushColor);
183 series->slices().at(i)->setSliceBrush(brushColor);
184 }
184 }
185 }
185 }
186
186
187
187
188 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
188 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
189 {
189 {
190 //TODO: dummy defults for now
190 //TODO: dummy defults for now
191 axis->setLabelsBrush(Qt::black);
191 axis->setLabelsBrush(Qt::black);
192 axis->setLabelsPen(Qt::NoPen);
192 axis->setLabelsPen(Qt::NoPen);
193 axis->setShadesPen(Qt::NoPen);
193 axis->setShadesPen(Qt::NoPen);
194 axis->setShadesOpacity(0.5);
194 axis->setShadesOpacity(0.5);
195 }
195 }
196
196
197 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int count)
197 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int index)
198 {
198 {
199 Q_ASSERT(item);
199 Q_ASSERT(item);
200 Q_ASSERT(series);
200 Q_ASSERT(series);
201
201
202 QPen pen;
202 QPen pen;
203
203
204 if(pen != series->pen()){
204 if(pen != series->pen()){
205 item->setLinePen(series->pen());
205 item->setLinePen(series->pen());
206 }else{
206 }else{
207 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
207 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
208 pen.setWidthF(series->pen().widthF());
208 pen.setWidthF(series->pen().widthF());
209 item->setLinePen(series->pen());
209 item->setLinePen(series->pen());
210 }
210 }
211
211
212 // QColor color = m_seriesColors.at(count % m_seriesColors.size());
212 // QColor color = m_seriesColors.at(index % m_seriesColors.size());
213 // TODO: define alpha in the theme? or in the series?
213 // TODO: define alpha in the theme? or in the series?
214 //color.setAlpha(120);
214 //color.setAlpha(120);
215
215
216 // QBrush brush(color, Qt::SolidPattern);
216 // QBrush brush(color, Qt::SolidPattern);
217 // presenter->m_markerBrush = brush;
217 // presenter->m_markerBrush = brush;
218
218
219 // QPen pen(brush, 3);
219 // QPen pen(brush, 3);
220 // pen.setColor(color);
220 // pen.setColor(color);
221 // presenter->m_markerPen = pen;
221 // presenter->m_markerPen = pen;
222 }
222 }
223
223
224 void ChartTheme::generateSeriesGradients()
224 void ChartTheme::generateSeriesGradients()
225 {
225 {
226 // Generate gradients in HSV color space
226 // Generate gradients in HSV color space
227 foreach (QColor color, m_seriesColors) {
227 foreach (QColor color, m_seriesColors) {
228 QLinearGradient g;
228 QLinearGradient g;
229 qreal h = color.hsvHueF();
229 qreal h = color.hsvHueF();
230 qreal s = color.hsvSaturationF();
230 qreal s = color.hsvSaturationF();
231
231
232 // TODO: tune the algorithm to give nice results with most base colors defined in
232 // TODO: tune the algorithm to give nice results with most base colors defined in
233 // most themes. The rest of the gradients we can define manually in theme specific
233 // most themes. The rest of the gradients we can define manually in theme specific
234 // implementation.
234 // implementation.
235 QColor start = color;
235 QColor start = color;
236 start.setHsvF(h, 0.05, 0.95);
236 start.setHsvF(h, 0.05, 0.95);
237 g.setColorAt(0.0, start);
237 g.setColorAt(0.0, start);
238
238
239 g.setColorAt(0.5, color);
239 g.setColorAt(0.5, color);
240
240
241 QColor end = color;
241 QColor end = color;
242 end.setHsvF(h, s, 0.25);
242 end.setHsvF(h, s, 0.25);
243 g.setColorAt(1.0, end);
243 g.setColorAt(1.0, end);
244
244
245 m_seriesGradients << g;
245 m_seriesGradients << g;
246 }
246 }
247 }
247 }
248
248
249
249
250 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
250 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
251 {
251 {
252 Q_ASSERT(pos >=0.0 && pos <= 1.0);
252 Q_ASSERT(pos >=0.0 && pos <= 1.0);
253 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
253 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
254 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
254 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
255 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
255 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
256 QColor c;
256 QColor c;
257 c.setRgbF(r, g, b);
257 c.setRgbF(r, g, b);
258 return c;
258 return c;
259 }
259 }
260
260
261 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
261 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
262 {
262 {
263 Q_ASSERT(pos >=0 && pos <= 1.0);
263 Q_ASSERT(pos >=0 && pos <= 1.0);
264
264
265 // another possibility:
265 // another possibility:
266 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
266 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
267
267
268 QGradientStops stops = gradient.stops();
268 QGradientStops stops = gradient.stops();
269 int count = stops.count();
269 int count = stops.count();
270
270
271 // find previous stop relative to position
271 // find previous stop relative to position
272 QGradientStop prev = stops.first();
272 QGradientStop prev = stops.first();
273 for (int i=0; i<count; i++) {
273 for (int i=0; i<count; i++) {
274 QGradientStop stop = stops.at(i);
274 QGradientStop stop = stops.at(i);
275 if (pos > stop.first)
275 if (pos > stop.first)
276 prev = stop;
276 prev = stop;
277
277
278 // given position is actually a stop position?
278 // given position is actually a stop position?
279 if (pos == stop.first) {
279 if (pos == stop.first) {
280 //qDebug() << "stop color" << pos;
280 //qDebug() << "stop color" << pos;
281 return stop.second;
281 return stop.second;
282 }
282 }
283 }
283 }
284
284
285 // find next stop relative to position
285 // find next stop relative to position
286 QGradientStop next = stops.last();
286 QGradientStop next = stops.last();
287 for (int i=count-1; i>=0; i--) {
287 for (int i=count-1; i>=0; i--) {
288 QGradientStop stop = stops.at(i);
288 QGradientStop stop = stops.at(i);
289 if (pos < stop.first)
289 if (pos < stop.first)
290 next = stop;
290 next = stop;
291 }
291 }
292
292
293 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
293 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
294
294
295 qreal range = next.first - prev.first;
295 qreal range = next.first - prev.first;
296 qreal posDelta = pos - prev.first;
296 qreal posDelta = pos - prev.first;
297 qreal relativePos = posDelta / range;
297 qreal relativePos = posDelta / range;
298
298
299 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
299 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
300
300
301 return colorAt(prev.second, next.second, relativePos);
301 return colorAt(prev.second, next.second, relativePos);
302 }
302 }
303
303
304 QTCOMMERCIALCHART_END_NAMESPACE
304 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,71
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 PiePresenter;
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 protected:
32 protected:
33 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
33 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
34 public:
34 public:
35 static ChartTheme* createTheme(QChart::ChartTheme theme);
35 static ChartTheme* createTheme(QChart::ChartTheme theme);
36 QChart::ChartTheme id() const {return m_id;}
36 QChart::ChartTheme id() const {return m_id;}
37 void decorate(QChart* chart);
37 void decorate(QChart* chart);
38 //void decorate(ChartItem* item, QSeries* series,int count);
38 //void decorate(ChartItem* item, QSeries* series,int index);
39 void decorate(BarPresenter* item, QBarSeries* series,int count);
39 void decorate(BarPresenter* item, QBarSeries* series, int index);
40 void decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count);
40 void decorate(StackedBarPresenter* item, QStackedBarSeries* series, int index);
41 void decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count);
41 void decorate(PercentBarPresenter* item, QPercentBarSeries* series, int index);
42 void decorate(LineChartItem* item, QLineSeries* series,int count);
42 void decorate(LineChartItem* item, QLineSeries* series, int index);
43 void decorate(AreaChartItem* item, QAreaSeries* series,int count);
43 void decorate(AreaChartItem* item, QAreaSeries* series, int index);
44 void decorate(ScatterChartItem* presenter, QScatterSeries* series, int count);
44 void decorate(ScatterChartItem* presenter, QScatterSeries* series, int index);
45 void decorate(PiePresenter* item, QPieSeries* series, int count);
45 void decorate(PiePresenter* item, QPieSeries* series, int index);
46 void decorate(QChartAxis* axis,AxisItem* item);
46 void decorate(QChartAxis* axis,AxisItem* item);
47 void decorate(SplineChartItem* presenter, QSplineSeries* series, int count);
47 void decorate(SplineChartItem* presenter, QSplineSeries* series, int index);
48
48
49 public: // utils
49 public: // utils
50 void generateSeriesGradients();
50 void generateSeriesGradients();
51 static QColor colorAt(const QColor &start, const QColor &end, qreal pos);
51 static QColor colorAt(const QColor &start, const QColor &end, qreal pos);
52 static QColor colorAt(const QGradient &gradient, qreal pos);
52 static QColor colorAt(const QGradient &gradient, qreal pos);
53
53
54 protected:
54 protected:
55 QChart::ChartTheme m_id;
55 QChart::ChartTheme m_id;
56 QList<QColor> m_seriesColors;
56 QList<QColor> m_seriesColors;
57 QList<QGradient> m_seriesGradients;
57 QList<QGradient> m_seriesGradients;
58 QLinearGradient m_backgroundGradient;
58 QLinearGradient m_backgroundGradient;
59
59
60 // TODO: Add something like the following to themes:
60 // TODO: Add something like the following to themes:
61 // QPen axisLinePen;
61 // QPen axisLinePen;
62 // QPen backgroundHorizontalGridPen;
62 // QPen backgroundHorizontalGridPen;
63 // QPen backgroundVerticalGridPen;
63 // QPen backgroundVerticalGridPen;
64 // // FillAll, FillEverySecondRow, FillEverySecondColumn, FillEverySecondRowAndColumn, FillNone
64 // // FillAll, FillEverySecondRow, FillEverySecondColumn, FillEverySecondRowAndColumn, FillNone
65 // int backgroundType;
65 // int backgroundType;
66 // QFont masterFont;
66 // QFont masterFont;
67 };
67 };
68
68
69 QTCOMMERCIALCHART_END_NAMESPACE
69 QTCOMMERCIALCHART_END_NAMESPACE
70
70
71 #endif // CHARTTHEME_H
71 #endif // CHARTTHEME_H
General Comments 0
You need to be logged in to leave comments. Login now