##// END OF EJS Templates
Using new theme in barcharts
sauimone -
r509:26832e993d66
parent child
Show More
@@ -1,325 +1,331
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 //TODO helper to by removed later
66 //TODO helper to by removed later
67 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
67 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
68 {
68 {
69 switch(series->type())
69 switch(series->type())
70 {
70 {
71 case QSeries::SeriesTypeLine: {
71 case QSeries::SeriesTypeLine: {
72 QLineSeries* s = static_cast<QLineSeries*>(series);
72 QLineSeries* s = static_cast<QLineSeries*>(series);
73 LineChartItem* i = static_cast<LineChartItem*>(item);
73 LineChartItem* i = static_cast<LineChartItem*>(item);
74 decorate(i,s,count);
74 decorate(i,s,count);
75 break;
75 break;
76 }
76 }
77 case QSeries::SeriesTypeArea: {
77 case QSeries::SeriesTypeArea: {
78 QAreaSeries* s = static_cast<QAreaSeries*>(series);
78 QAreaSeries* s = static_cast<QAreaSeries*>(series);
79 AreaChartItem* i = static_cast<AreaChartItem*>(item);
79 AreaChartItem* i = static_cast<AreaChartItem*>(item);
80 decorate(i,s,count);
80 decorate(i,s,count);
81 break;
81 break;
82 }
82 }
83 case QSeries::SeriesTypeBar: {
83 case QSeries::SeriesTypeBar: {
84 QBarSeries* b = static_cast<QBarSeries*>(series);
84 QBarSeries* b = static_cast<QBarSeries*>(series);
85 BarPresenter* i = static_cast<BarPresenter*>(item);
85 BarPresenter* i = static_cast<BarPresenter*>(item);
86 decorate(i,b,count);
86 decorate(i,b,count);
87 break;
87 break;
88 }
88 }
89 case QSeries::SeriesTypeStackedBar: {
89 case QSeries::SeriesTypeStackedBar: {
90 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
90 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
91 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
91 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
92 decorate(i,s,count);
92 decorate(i,s,count);
93 break;
93 break;
94 }
94 }
95 case QSeries::SeriesTypePercentBar: {
95 case QSeries::SeriesTypePercentBar: {
96 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
96 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
97 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
97 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
98 decorate(i,s,count);
98 decorate(i,s,count);
99 break;
99 break;
100 }
100 }
101 case QSeries::SeriesTypeScatter: {
101 case QSeries::SeriesTypeScatter: {
102 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
102 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
103 Q_ASSERT(s);
103 Q_ASSERT(s);
104 ScatterChartItem* i = static_cast<ScatterChartItem*>(item);
104 ScatterChartItem* i = static_cast<ScatterChartItem*>(item);
105 Q_ASSERT(i);
105 Q_ASSERT(i);
106 decorate(i, s, count);
106 decorate(i, s, count);
107 break;
107 break;
108 }
108 }
109 case QSeries::SeriesTypePie: {
109 case QSeries::SeriesTypePie: {
110 QPieSeries* s = static_cast<QPieSeries*>(series);
110 QPieSeries* s = static_cast<QPieSeries*>(series);
111 PiePresenter* i = static_cast<PiePresenter*>(item);
111 PiePresenter* i = static_cast<PiePresenter*>(item);
112 decorate(i,s,count);
112 decorate(i,s,count);
113 break;
113 break;
114 }
114 }
115 default:
115 default:
116 qDebug()<<"Wrong item to be decorated by theme";
116 qDebug()<<"Wrong item to be decorated by theme";
117 break;
117 break;
118 }
118 }
119
119
120 }
120 }
121
121
122 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
122 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
123 {
123 {
124 QPen pen;
124 QPen pen;
125 QBrush brush;
125 QBrush brush;
126
126
127 if(pen != series->pen()){
127 if(pen != series->pen()){
128 item->setPen(series->pen());
128 item->setPen(series->pen());
129 }else{
129 }else{
130 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
130 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
131 pen.setWidthF(2);
131 pen.setWidthF(2);
132 item->setPen(pen);
132 item->setPen(pen);
133 }
133 }
134
134
135 if(brush != series->brush()){
135 if(brush != series->brush()){
136 item->setBrush(series->brush());
136 item->setBrush(series->brush());
137 }else{
137 }else{
138 QBrush brush(m_seriesColors.at(count%m_seriesColors.size()));
138 QBrush brush(m_seriesColors.at(count%m_seriesColors.size()));
139 item->setBrush(brush);
139 item->setBrush(brush);
140 }
140 }
141 }
141 }
142
142
143
143
144 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
144 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
145 {
145 {
146 QPen pen;
146 QPen pen;
147 if(pen != series->pen()){
147 if(pen != series->pen()){
148 item->setLinePen(series->pen());
148 item->setLinePen(series->pen());
149 return;
149 return;
150 }
150 }
151 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
151 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
152 pen.setWidthF(2);
152 pen.setWidthF(2);
153 item->setLinePen(pen);
153 item->setLinePen(pen);
154 }
154 }
155
155
156 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
156 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
157 {
157 {
158 QList<QBarSet*> sets = series->barSets();
158 QList<QBarSet*> sets = series->barSets();
159 for (int i=0; i<series->barsetCount(); i++) {
159 for (int i=0; i<sets.count(); i++) {
160 sets.at(i)->setBrush(QBrush(m_seriesColors.at(i%m_seriesColors.count())));
160 qreal pos = (qreal) i / (qreal) sets.count();
161 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
162 sets.at(i)->setBrush(QBrush(c));
161 }
163 }
162 }
164 }
163
165
164 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
166 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
165 {
167 {
166 QList<QBarSet*> sets = series->barSets();
168 QList<QBarSet*> sets = series->barSets();
167 for (int i=0; i<series->barsetCount(); i++) {
169 for (int i=0; i<sets.count(); i++) {
168 sets.at(i)->setBrush(QBrush(m_seriesColors.at(i%m_seriesColors.count())));
170 qreal pos = (qreal) i / (qreal) sets.count();
171 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
172 sets.at(i)->setBrush(QBrush(c));
169 }
173 }
170 }
174 }
171
175
172 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
176 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
173 {
177 {
174 QList<QBarSet*> sets = series->barSets();
178 QList<QBarSet*> sets = series->barSets();
175 for (int i=0; i<series->barsetCount(); i++) {
179 for (int i=0; i<sets.count(); i++) {
176 sets.at(i)->setBrush(QBrush(m_seriesColors.at(i%m_seriesColors.count())));
180 qreal pos = (qreal) i / (qreal) sets.count();
181 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
182 sets.at(i)->setBrush(QBrush(c));
177 }
183 }
178 }
184 }
179
185
180 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int count)
186 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int count)
181 {
187 {
182 Q_ASSERT(item);
188 Q_ASSERT(item);
183 Q_ASSERT(series);
189 Q_ASSERT(series);
184
190
185 QColor color = m_seriesColors.at(count % m_seriesColors.size());
191 QColor color = m_seriesColors.at(count % m_seriesColors.size());
186 // TODO: define alpha in the theme? or in the series?
192 // TODO: define alpha in the theme? or in the series?
187 //color.setAlpha(120);
193 //color.setAlpha(120);
188
194
189 QBrush brush(color, Qt::SolidPattern);
195 QBrush brush(color, Qt::SolidPattern);
190 item->setBrush(Qt::blue);
196 item->setBrush(Qt::blue);
191
197
192 QPen pen(brush, 3);
198 QPen pen(brush, 3);
193 pen.setColor(color);
199 pen.setColor(color);
194 item->setPen(pen);
200 item->setPen(pen);
195 }
201 }
196
202
197 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int count)
203 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int count)
198 {
204 {
199 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
205 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
200 for (int i(0); i < series->slices().count(); i++) {
206 for (int i(0); i < series->slices().count(); i++) {
201 qreal pos = (qreal) i / (qreal) series->count();
207 qreal pos = (qreal) i / (qreal) series->count();
202 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
208 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
203 series->slices().at(i)->setSlicePen(c);
209 series->slices().at(i)->setSlicePen(c);
204 series->slices().at(i)->setSliceBrush(c);
210 series->slices().at(i)->setSliceBrush(c);
205 }
211 }
206 }
212 }
207
213
208
214
209 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
215 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
210 {
216 {
211 //TODO: dummy defults for now
217 //TODO: dummy defults for now
212 axis->setLabelsBrush(Qt::black);
218 axis->setLabelsBrush(Qt::black);
213 axis->setLabelsPen(Qt::NoPen);
219 axis->setLabelsPen(Qt::NoPen);
214 axis->setShadesPen(Qt::NoPen);
220 axis->setShadesPen(Qt::NoPen);
215 axis->setShadesOpacity(0.5);
221 axis->setShadesOpacity(0.5);
216 }
222 }
217
223
218 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int count)
224 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int count)
219 {
225 {
220 Q_ASSERT(item);
226 Q_ASSERT(item);
221 Q_ASSERT(series);
227 Q_ASSERT(series);
222
228
223 QPen pen;
229 QPen pen;
224
230
225 if(pen != series->pen()){
231 if(pen != series->pen()){
226 item->setLinePen(series->pen());
232 item->setLinePen(series->pen());
227 }else{
233 }else{
228 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
234 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
229 pen.setWidthF(series->pen().widthF());
235 pen.setWidthF(series->pen().widthF());
230 item->setLinePen(series->pen());
236 item->setLinePen(series->pen());
231 }
237 }
232
238
233 // QColor color = m_seriesColors.at(count % m_seriesColors.size());
239 // QColor color = m_seriesColors.at(count % m_seriesColors.size());
234 // TODO: define alpha in the theme? or in the series?
240 // TODO: define alpha in the theme? or in the series?
235 //color.setAlpha(120);
241 //color.setAlpha(120);
236
242
237 // QBrush brush(color, Qt::SolidPattern);
243 // QBrush brush(color, Qt::SolidPattern);
238 // presenter->m_markerBrush = brush;
244 // presenter->m_markerBrush = brush;
239
245
240 // QPen pen(brush, 3);
246 // QPen pen(brush, 3);
241 // pen.setColor(color);
247 // pen.setColor(color);
242 // presenter->m_markerPen = pen;
248 // presenter->m_markerPen = pen;
243 }
249 }
244
250
245 void ChartTheme::generateSeriesGradients()
251 void ChartTheme::generateSeriesGradients()
246 {
252 {
247 // Generate gradients in HSV color space
253 // Generate gradients in HSV color space
248 foreach (QColor color, m_seriesColors) {
254 foreach (QColor color, m_seriesColors) {
249 QLinearGradient g;
255 QLinearGradient g;
250 qreal h = color.hsvHueF();
256 qreal h = color.hsvHueF();
251 qreal s = color.hsvSaturationF();
257 qreal s = color.hsvSaturationF();
252
258
253 // TODO: tune the algorithm to give nice results with most base colors defined in
259 // TODO: tune the algorithm to give nice results with most base colors defined in
254 // most themes. The rest of the gradients we can define manually in theme specific
260 // most themes. The rest of the gradients we can define manually in theme specific
255 // implementation.
261 // implementation.
256 QColor start = color;
262 QColor start = color;
257 start.setHsvF(h, 0.05, 0.95);
263 start.setHsvF(h, 0.05, 0.95);
258 g.setColorAt(0.0, start);
264 g.setColorAt(0.0, start);
259
265
260 g.setColorAt(0.5, color);
266 g.setColorAt(0.5, color);
261
267
262 QColor end = color;
268 QColor end = color;
263 end.setHsvF(h, s, 0.25);
269 end.setHsvF(h, s, 0.25);
264 g.setColorAt(1.0, end);
270 g.setColorAt(1.0, end);
265
271
266 m_seriesGradients << g;
272 m_seriesGradients << g;
267 }
273 }
268 }
274 }
269
275
270
276
271 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
277 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
272 {
278 {
273 Q_ASSERT(pos >=0.0 && pos <= 1.0);
279 Q_ASSERT(pos >=0.0 && pos <= 1.0);
274 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
280 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
275 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
281 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
276 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
282 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
277 QColor c;
283 QColor c;
278 c.setRgbF(r, g, b);
284 c.setRgbF(r, g, b);
279 return c;
285 return c;
280 }
286 }
281
287
282 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
288 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
283 {
289 {
284 Q_ASSERT(pos >=0 && pos <= 1.0);
290 Q_ASSERT(pos >=0 && pos <= 1.0);
285
291
286 // another possibility:
292 // another possibility:
287 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
293 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
288
294
289 QGradientStops stops = gradient.stops();
295 QGradientStops stops = gradient.stops();
290 int count = stops.count();
296 int count = stops.count();
291
297
292 // find previous stop relative to position
298 // find previous stop relative to position
293 QGradientStop prev = stops.first();
299 QGradientStop prev = stops.first();
294 for (int i=0; i<count; i++) {
300 for (int i=0; i<count; i++) {
295 QGradientStop stop = stops.at(i);
301 QGradientStop stop = stops.at(i);
296 if (pos > stop.first)
302 if (pos > stop.first)
297 prev = stop;
303 prev = stop;
298
304
299 // given position is actually a stop position?
305 // given position is actually a stop position?
300 if (pos == stop.first) {
306 if (pos == stop.first) {
301 //qDebug() << "stop color" << pos;
307 //qDebug() << "stop color" << pos;
302 return stop.second;
308 return stop.second;
303 }
309 }
304 }
310 }
305
311
306 // find next stop relative to position
312 // find next stop relative to position
307 QGradientStop next = stops.last();
313 QGradientStop next = stops.last();
308 for (int i=count-1; i>=0; i--) {
314 for (int i=count-1; i>=0; i--) {
309 QGradientStop stop = stops.at(i);
315 QGradientStop stop = stops.at(i);
310 if (pos < stop.first)
316 if (pos < stop.first)
311 next = stop;
317 next = stop;
312 }
318 }
313
319
314 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
320 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
315
321
316 qreal range = next.first - prev.first;
322 qreal range = next.first - prev.first;
317 qreal posDelta = pos - prev.first;
323 qreal posDelta = pos - prev.first;
318 qreal relativePos = posDelta / range;
324 qreal relativePos = posDelta / range;
319
325
320 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
326 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
321
327
322 return colorAt(prev.second, next.second, relativePos);
328 return colorAt(prev.second, next.second, relativePos);
323 }
329 }
324
330
325 QTCOMMERCIALCHART_END_NAMESPACE
331 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now