##// END OF EJS Templates
Revert "Theme change now affects also XY series"...
Michal Klocek -
r644:7baa2715935c
parent child
Show More
@@ -1,302 +1,323
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3 #include "qchartview.h"
4 4 #include "qlegend.h"
5 5 #include "qchartaxis.h"
6 6 #include <QTime>
7 7
8 8 //series
9 9 #include "qbarset.h"
10 10 #include "qbarseries.h"
11 11 #include "qstackedbarseries.h"
12 12 #include "qpercentbarseries.h"
13 13 #include "qlineseries.h"
14 14 #include "qareaseries.h"
15 15 #include "qscatterseries.h"
16 16 #include "qpieseries.h"
17 17 #include "qpieslice.h"
18 18 #include "qsplineseries.h"
19 19
20 20 //items
21 21 #include "axisitem_p.h"
22 22 #include "barpresenter_p.h"
23 23 #include "stackedbarpresenter_p.h"
24 24 #include "percentbarpresenter_p.h"
25 25 #include "linechartitem_p.h"
26 26 #include "areachartitem_p.h"
27 27 #include "scatterchartitem_p.h"
28 28 #include "piechartitem_p.h"
29 29 #include "splinechartitem_p.h"
30 30
31 31 //themes
32 32 #include "chartthemedefault_p.h"
33 33 #include "chartthemevanilla_p.h"
34 34 #include "chartthemeicy_p.h"
35 35 #include "chartthemegrayscale_p.h"
36 36 #include "chartthemescientific_p.h"
37 37 #include "chartthemebluecerulean_p.h"
38 38 #include "chartthemelight_p.h"
39 39
40 40
41 41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42 42
43 43 ChartTheme::ChartTheme(QChart::ChartTheme id) :
44 44 m_masterFont(QFont()),
45 45 m_titleBrush(QColor(QRgb(0x000000))),
46 46 m_axisLinePen(QPen(QRgb(0x000000))),
47 47 m_axisLabelBrush(QColor(QRgb(0x000000))),
48 48 m_backgroundShadesPen(Qt::NoPen),
49 49 m_backgroundShadesBrush(Qt::NoBrush),
50 50 m_backgroundShades(BackgroundShadesNone),
51 51 m_gridLinePen(QPen(QRgb(0x000000)))
52 52 {
53 53 m_id = id;
54 54 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
55 55 }
56 56
57 57
58 58 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
59 59 {
60 60 switch(theme) {
61 61 case QChart::ChartThemeVanilla:
62 62 return new ChartThemeVanilla();
63 63 case QChart::ChartThemeIcy:
64 64 return new ChartThemeIcy();
65 65 case QChart::ChartThemeGrayscale:
66 66 return new ChartThemeGrayscale();
67 67 case QChart::ChartThemeScientific:
68 68 return new ChartThemeScientific();
69 69 case QChart::ChartThemeBlueCerulean:
70 70 return new ChartThemeBlueCerulean();
71 71 case QChart::ChartThemeLight:
72 72 return new ChartThemeLight();
73 73 default:
74 74 return new ChartThemeDefault();
75 75 }
76 76 }
77 77
78 78 void ChartTheme::decorate(QChart* chart)
79 79 {
80 80 if (m_backgroundShades == BackgroundShadesNone) {
81 81 chart->setChartBackgroundBrush(m_chartBackgroundGradient);
82 82 } else {
83 83 chart->setChartBackgroundBrush(Qt::NoBrush);
84 84 }
85 85 chart->setChartTitleFont(m_masterFont);
86 86 chart->setChartTitleBrush(m_titleBrush);
87 87 }
88 88
89 89 void ChartTheme::decorate(QLegend* legend)
90 90 {
91 91 legend->setBackgroundBrush(m_chartBackgroundGradient);
92 92 }
93 93
94 94 void ChartTheme::decorate(QAreaSeries* series, int index)
95 95 {
96 QPen pen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
97 pen.setWidthF(2);
98 series->setPen(pen);
96 QPen pen;
97 QBrush brush;
99 98
100 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
101 series->setBrush(brush);
99 if (pen == series->pen()){
100 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
101 pen.setWidthF(2);
102 series->setPen(pen);
103 }
104
105 if (brush == series->brush()) {
106 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
107 series->setBrush(brush);
108 }
102 109 }
103 110
104 111
105 112 void ChartTheme::decorate(QLineSeries* series,int index)
106 113 {
107 QPen pen(m_seriesColors.at(index%m_seriesColors.size()));
108 pen.setWidthF(2);
109 series->setPen(pen);
114 QPen pen;
115 if(pen == series->pen()){
116 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
117 pen.setWidthF(2);
118 series->setPen(pen);
119 }
110 120 }
111 121
112 122 void ChartTheme::decorate(QBarSeries* series,int index)
113 123 {
114 124 QList<QBarSet*> sets = series->barSets();
115 125 for (int i=0; i<sets.count(); i++) {
116 126 qreal pos = 0.5;
117 127 if (sets.count() > 1)
118 128 pos = (qreal) i / (qreal) (sets.count() - 1);
119 129 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
120 130 sets.at(i)->setBrush(QBrush(c));
121 131
122 132 // Pick label color as far as possible from bar color (within gradient).
123 133 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
124 134 // TODO: better picking of label color?
125 135 if (pos < 0.3) {
126 136 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
127 137 } else {
128 138 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
129 139 }
130 140 sets.at(i)->setFloatingValuePen(QPen(c));
131 141 }
132 142 }
133 143
134 144 void ChartTheme::decorate(QStackedBarSeries* series,int index)
135 145 {
136 146 QList<QBarSet*> sets = series->barSets();
137 147 for (int i=0; i<sets.count(); i++) {
138 148 qreal pos = 0.5;
139 149 if (sets.count() > 1)
140 150 pos = (qreal) i / (qreal) (sets.count() - 1);
141 151 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
142 152 sets.at(i)->setBrush(QBrush(c));
143 153
144 154 if (pos < 0.3) {
145 155 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
146 156 } else {
147 157 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
148 158 }
149 159 sets.at(i)->setFloatingValuePen(QPen(c));
150 160 }
151 161 }
152 162
153 163 void ChartTheme::decorate(QPercentBarSeries* series,int index)
154 164 {
155 165 QList<QBarSet*> sets = series->barSets();
156 166 for (int i=0; i<sets.count(); i++) {
157 167 qreal pos = 0.5;
158 168 if (sets.count() > 1)
159 169 pos = (qreal) i / (qreal) (sets.count() - 1);
160 170 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
161 171 sets.at(i)->setBrush(QBrush(c));
162 172
163 173 if (pos < 0.3) {
164 174 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
165 175 } else {
166 176 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
167 177 }
168 178 sets.at(i)->setFloatingValuePen(QPen(c));
169 179 }
170 180 }
171 181
172 182 void ChartTheme::decorate(QScatterSeries* series, int index)
173 183 {
174 QPen pen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
175 pen.setWidthF(2);
176 series->setPen(pen);
177 184
178 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
179 series->setBrush(brush);
185 QPen pen;
186 QBrush brush;
187
188 if (pen == series->pen()) {
189 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
190 pen.setWidthF(2);
191 series->setPen(pen);
192 }
193
194 if (brush == series->brush()) {
195 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
196 series->setBrush(brush);
197 }
180 198 }
181 199
182 200 void ChartTheme::decorate(QPieSeries* series, int index)
183 201 {
184 202 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
185 203 for (int i(0); i < series->slices().count(); i++) {
186 204 qreal pos = (qreal) i / (qreal) series->count();
187 205 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
188 206 series->slices().at(i)->setSlicePen(penColor);
189 207 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
190 208 series->slices().at(i)->setSliceBrush(brushColor);
191 209 }
192 210 }
193 211
194 212 void ChartTheme::decorate(QSplineSeries* series, int index)
195 213 {
196 QPen pen(m_seriesColors.at(index%m_seriesColors.size()));
197 pen.setWidthF(2);
198 series->setPen(pen);
214 QPen pen;
215 if(pen == series->pen()){
216 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
217 pen.setWidthF(2);
218 series->setPen(pen);
219 }
199 220 }
200 221
201 222 void ChartTheme::decorate(QChartAxis* axis,bool axisX)
202 223 {
203 224 if (axis->isAxisVisible()) {
204 225 axis->setLabelsBrush(m_axisLabelBrush);
205 226 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
206 227 if (m_backgroundShades == BackgroundShadesBoth
207 228 || (m_backgroundShades == BackgroundShadesVertical && axisX)
208 229 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX)) {
209 230 axis->setShadesPen(m_backgroundShadesPen);
210 231 axis->setShadesBrush(m_backgroundShadesBrush);
211 232 } else {
212 233 // The shades not supposed to be shown for this axis, clear possible brush and pen
213 234 axis->setShadesPen(Qt::NoPen);
214 235 axis->setShadesBrush(Qt::NoBrush);
215 236 }
216 237 axis->setAxisPen(m_axisLinePen);
217 238 axis->setGridLinePen(m_gridLinePen);
218 239 axis->setLabelsFont(m_masterFont);
219 240 }
220 241 }
221 242
222 243 void ChartTheme::generateSeriesGradients()
223 244 {
224 245 // Generate gradients in HSV color space
225 246 foreach (QColor color, m_seriesColors) {
226 247 QLinearGradient g;
227 248 qreal h = color.hsvHueF();
228 249 qreal s = color.hsvSaturationF();
229 250
230 251 // TODO: tune the algorithm to give nice results with most base colors defined in
231 252 // most themes. The rest of the gradients we can define manually in theme specific
232 253 // implementation.
233 254 QColor start = color;
234 255 start.setHsvF(h, 0.05, 0.95);
235 256 g.setColorAt(0.0, start);
236 257
237 258 g.setColorAt(0.5, color);
238 259
239 260 QColor end = color;
240 261 end.setHsvF(h, s, 0.25);
241 262 g.setColorAt(1.0, end);
242 263
243 264 m_seriesGradients << g;
244 265 }
245 266 }
246 267
247 268
248 269 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
249 270 {
250 271 Q_ASSERT(pos >=0.0 && pos <= 1.0);
251 272 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
252 273 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
253 274 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
254 275 QColor c;
255 276 c.setRgbF(r, g, b);
256 277 return c;
257 278 }
258 279
259 280 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
260 281 {
261 282 Q_ASSERT(pos >=0 && pos <= 1.0);
262 283
263 284 // another possibility:
264 285 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
265 286
266 287 QGradientStops stops = gradient.stops();
267 288 int count = stops.count();
268 289
269 290 // find previous stop relative to position
270 291 QGradientStop prev = stops.first();
271 292 for (int i=0; i<count; i++) {
272 293 QGradientStop stop = stops.at(i);
273 294 if (pos > stop.first)
274 295 prev = stop;
275 296
276 297 // given position is actually a stop position?
277 298 if (pos == stop.first) {
278 299 //qDebug() << "stop color" << pos;
279 300 return stop.second;
280 301 }
281 302 }
282 303
283 304 // find next stop relative to position
284 305 QGradientStop next = stops.last();
285 306 for (int i=count-1; i>=0; i--) {
286 307 QGradientStop stop = stops.at(i);
287 308 if (pos < stop.first)
288 309 next = stop;
289 310 }
290 311
291 312 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
292 313
293 314 qreal range = next.first - prev.first;
294 315 qreal posDelta = pos - prev.first;
295 316 qreal relativePos = posDelta / range;
296 317
297 318 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
298 319
299 320 return colorAt(prev.second, next.second, relativePos);
300 321 }
301 322
302 323 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now