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