##// END OF EJS Templates
Renames header axisitem -> axis
Michal Klocek -
r959:6fbac6697666
parent child
Show More
@@ -1,46 +1,46
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef AXISANIMATIONITEM_H_
22 22 #define AXISANIMATIONITEM_H_
23 23
24 #include "axisitem_p.h"
24 #include "axis_p.h"
25 25 #include "chartanimation_p.h"
26 26
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class AxisAnimation: public ChartAnimation
31 31 {
32 32 public:
33 33 AxisAnimation(Axis *axis);
34 34 ~AxisAnimation();
35 35 protected:
36 virtual QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress ) const;
37 virtual void updateCurrentValue(const QVariant &value );
36 QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress ) const;
37 void updateCurrentValue(const QVariant &value );
38 38 private:
39 39 Axis *m_axis;
40 40 };
41 41
42 42 QTCOMMERCIALCHART_END_NAMESPACE
43 43
44 44
45 45
46 46 #endif /* AXISITEM_H_ */
@@ -1,465 +1,464
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 #include "axisitem_p.h"
21 #include "axis_p.h"
22 22 #include "qchartaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "chartanimator_p.h"
25 25 #include <QPainter>
26 #include <QDebug>
27 26 #include <cmath>
28 27
29 28 static int label_padding = 5;
30 29
31 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 31
33 32 Axis::Axis(QChartAxis *axis,ChartPresenter *presenter,AxisType type) : Chart(presenter),
34 33 m_chartAxis(axis),
35 34 m_type(type),
36 35 m_labelsAngle(0),
37 36 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
38 37 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
39 38 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
40 39 m_axis(new QGraphicsItemGroup(presenter->rootItem())),
41 40 m_min(0),
42 41 m_max(0),
43 42 m_ticksCount(0)
44 43 {
45 44 //initial initialization
46 45 m_axis->setZValue(ChartPresenter::AxisZValue);
47 46 m_axis->setHandlesChildEvents(false);
48 47
49 48 m_shades->setZValue(ChartPresenter::ShadesZValue);
50 49 m_grid->setZValue(ChartPresenter::GridZValue);
51 50
52 51 connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
53 52 connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
54 53
55 54 handleAxisUpdated();
56 55 }
57 56
58 57 Axis::~Axis()
59 58 {
60 59 }
61 60
62 61 void Axis::createItems(int count)
63 62 {
64 63
65 64 if (m_axis->children().size() == 0)
66 65 m_axis->addToGroup(new AxisItem(this));
67 66 for (int i = 0; i < count; ++i) {
68 67 m_grid->addToGroup(new QGraphicsLineItem());
69 68 m_labels->addToGroup(new QGraphicsSimpleTextItem());
70 69 m_axis->addToGroup(new QGraphicsLineItem());
71 70 if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem());
72 71 }
73 72 }
74 73
75 74 void Axis::deleteItems(int count)
76 75 {
77 76 QList<QGraphicsItem *> lines = m_grid->childItems();
78 77 QList<QGraphicsItem *> labels = m_labels->childItems();
79 78 QList<QGraphicsItem *> shades = m_shades->childItems();
80 79 QList<QGraphicsItem *> axis = m_axis->childItems();
81 80
82 81 for (int i = 0; i < count; ++i) {
83 82 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
84 83 delete(lines.takeLast());
85 84 delete(labels.takeLast());
86 85 delete(axis.takeLast());
87 86 }
88 87 }
89 88
90 89 void Axis::updateLayout(QVector<qreal> &layout)
91 90 {
92 91 if (animator()) {
93 92 animator()->updateLayout(this,layout);
94 93 } else {
95 94 setLayout(layout);
96 95 }
97 96 }
98 97
99 98 bool Axis::createLabels(QStringList &labels,qreal min, qreal max,int ticks) const
100 99 {
101 100 Q_ASSERT(max>=min);
102 101 Q_ASSERT(ticks>1);
103 102
104 103 QChartAxisCategories* categories = m_chartAxis->categories();
105 104
106 105 bool category = categories->count()>0;
107 106
108 107 if (!category) {
109 108 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
110 109 n++;
111 110 for (int i=0; i< ticks; i++) {
112 111 qreal value = min + (i * (max - min)/ (ticks-1));
113 112 labels << QString::number(value,'f',n);
114 113 }
115 114 } else {
116 115 QList<qreal> values = categories->values();
117 116 for (int i=0; i< ticks; i++) {
118 117 qreal value = (min + (i * (max - min)/ (ticks-1)));
119 118 int j=0;
120 119 for (; j<values.count(); j++) {
121 120 if (values.at(j) > value) break;
122 121 }
123 122 if (j!=0) value=values.at(j-1);
124 123
125 124 QString label = categories->label(value);
126 125 labels << label;
127 126 }
128 127 }
129 128
130 129 return category;
131 130 }
132 131
133 132 void Axis::setAxisOpacity(qreal opacity)
134 133 {
135 134 m_axis->setOpacity(opacity);
136 135 }
137 136
138 137 qreal Axis::axisOpacity() const
139 138 {
140 139 return m_axis->opacity();
141 140 }
142 141
143 142 void Axis::setGridOpacity(qreal opacity)
144 143 {
145 144 m_grid->setOpacity(opacity);
146 145 }
147 146
148 147 qreal Axis::gridOpacity() const
149 148 {
150 149 return m_grid->opacity();
151 150 }
152 151
153 152 void Axis::setLabelsOpacity(qreal opacity)
154 153 {
155 154 m_labels->setOpacity(opacity);
156 155 }
157 156
158 157 qreal Axis::labelsOpacity() const
159 158 {
160 159 return m_labels->opacity();
161 160 }
162 161
163 162 void Axis::setShadesOpacity(qreal opacity)
164 163 {
165 164 m_shades->setOpacity(opacity);
166 165 }
167 166
168 167 qreal Axis::shadesOpacity() const
169 168 {
170 169 return m_shades->opacity();
171 170 }
172 171
173 172 void Axis::setLabelsAngle(int angle)
174 173 {
175 174 foreach(QGraphicsItem* item , m_labels->childItems()) {
176 175 item->setRotation(angle);
177 176 }
178 177
179 178 m_labelsAngle=angle;
180 179 }
181 180
182 181 void Axis::setLabelsPen(const QPen &pen)
183 182 {
184 183 foreach(QGraphicsItem* item , m_labels->childItems()) {
185 184 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
186 185 }
187 186 }
188 187
189 188 void Axis::setLabelsBrush(const QBrush &brush)
190 189 {
191 190 foreach(QGraphicsItem* item , m_labels->childItems()) {
192 191 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
193 192 }
194 193 }
195 194
196 195 void Axis::setLabelsFont(const QFont &font)
197 196 {
198 197 foreach(QGraphicsItem* item , m_labels->childItems()) {
199 198 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
200 199 }
201 200 }
202 201
203 202 void Axis::setShadesBrush(const QBrush &brush)
204 203 {
205 204 foreach(QGraphicsItem* item , m_shades->childItems()) {
206 205 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
207 206 }
208 207 }
209 208
210 209 void Axis::setShadesPen(const QPen &pen)
211 210 {
212 211 foreach(QGraphicsItem* item , m_shades->childItems()) {
213 212 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
214 213 }
215 214 }
216 215
217 216 void Axis::setAxisPen(const QPen &pen)
218 217 {
219 218 foreach(QGraphicsItem* item , m_axis->childItems()) {
220 219 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
221 220 }
222 221 }
223 222
224 223 void Axis::setGridPen(const QPen &pen)
225 224 {
226 225 foreach(QGraphicsItem* item , m_grid->childItems()) {
227 226 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
228 227 }
229 228 }
230 229
231 230 QVector<qreal> Axis::calculateLayout() const
232 231 {
233 232 Q_ASSERT(m_ticksCount>=2);
234 233
235 234 QVector<qreal> points;
236 235 points.resize(m_ticksCount);
237 236
238 237 switch (m_type)
239 238 {
240 239 case X_AXIS:
241 240 {
242 241 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
243 242 for (int i = 0; i < m_ticksCount; ++i) {
244 243 int x = i * deltaX + m_rect.left();
245 244 points[i] = x;
246 245 }
247 246 }
248 247 break;
249 248 case Y_AXIS:
250 249 {
251 250 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
252 251 for (int i = 0; i < m_ticksCount; ++i) {
253 252 int y = i * -deltaY + m_rect.bottom();
254 253 points[i] = y;
255 254 }
256 255 }
257 256 break;
258 257 }
259 258 return points;
260 259 }
261 260
262 261 void Axis::setLayout(QVector<qreal> &layout)
263 262 {
264 263 int diff = m_layoutVector.size() - layout.size();
265 264
266 265 if (diff>0) {
267 266 deleteItems(diff);
268 267 } else if (diff<0) {
269 268 createItems(-diff);
270 269 }
271 270
272 271 if( diff!=0) handleAxisUpdated();
273 272
274 273 QStringList ticksList;
275 274
276 275 bool categories = createLabels(ticksList,m_min,m_max,layout.size());
277 276
278 277 QList<QGraphicsItem *> lines = m_grid->childItems();
279 278 QList<QGraphicsItem *> labels = m_labels->childItems();
280 279 QList<QGraphicsItem *> shades = m_shades->childItems();
281 280 QList<QGraphicsItem *> axis = m_axis->childItems();
282 281
283 282 Q_ASSERT(labels.size() == ticksList.size());
284 283 Q_ASSERT(layout.size() == ticksList.size());
285 284
286 285 qreal minWidth = 0;
287 286 qreal minHeight = 0;
288 287
289 288 switch (m_type)
290 289 {
291 290 case X_AXIS:
292 291 {
293 292 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
294 293 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
295 294
296 295 for (int i = 0; i < layout.size(); ++i) {
297 296 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
298 297 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
299 298 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
300 299 if (!categories || i<1) {
301 300 labelItem->setText(ticksList.at(i));
302 301 const QRectF& rect = labelItem->boundingRect();
303 302 minWidth+=rect.width();
304 303 minHeight=qMax(rect.height(),minHeight);
305 304 QPointF center = rect.center();
306 305 labelItem->setTransformOriginPoint(center.x(), center.y());
307 306 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
308 307 } else {
309 308 labelItem->setText(ticksList.at(i));
310 309 const QRectF& rect = labelItem->boundingRect();
311 310 minWidth+=rect.width();
312 311 minHeight=qMax(rect.height()+label_padding,minHeight);
313 312 QPointF center = rect.center();
314 313 labelItem->setTransformOriginPoint(center.x(), center.y());
315 314 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
316 315 }
317 316
318 317 if ((i+1)%2 && i>1) {
319 318 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
320 319 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
321 320 }
322 321 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
323 322 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
324 323 }
325 324
326 325 }
327 326 break;
328 327
329 328 case Y_AXIS:
330 329 {
331 330 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
332 331 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
333 332
334 333 for (int i = 0; i < layout.size(); ++i) {
335 334 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
336 335 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
337 336 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
338 337
339 338 if (!categories || i<1) {
340 339 labelItem->setText(ticksList.at(i));
341 340 const QRectF& rect = labelItem->boundingRect();
342 341 minWidth=qMax(rect.width()+label_padding,minWidth);
343 342 minHeight+=rect.height();
344 343 QPointF center = rect.center();
345 344 labelItem->setTransformOriginPoint(center.x(), center.y());
346 345 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
347 346 } else {
348 347 labelItem->setText(ticksList.at(i));
349 348 const QRectF& rect = labelItem->boundingRect();
350 349 minWidth=qMax(rect.width(),minWidth);
351 350 minHeight+=rect.height();
352 351 QPointF center = rect.center();
353 352 labelItem->setTransformOriginPoint(center.x(), center.y());
354 353 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
355 354 }
356 355
357 356 if ((i+1)%2 && i>1) {
358 357 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
359 358 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
360 359 }
361 360 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
362 361 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
363 362 }
364 363 }
365 364 break;
366 365 default:
367 366 qDebug()<<"Unknown axis type";
368 367 break;
369 368 }
370 369
371 370 m_layoutVector=layout;
372 371
373 372 presenter()->setMinimumMarginWidth(this,minWidth);
374 373 presenter()->setMinimumMarginHeight(this,minHeight);
375 374
376 375 }
377 376
378 377 bool Axis::isEmpty()
379 378 {
380 379 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max) || m_ticksCount==0;
381 380 }
382 381
383 382 //handlers
384 383
385 384 void Axis::handleAxisCategoriesUpdated()
386 385 {
387 386 if (isEmpty()) return;
388 387 updateLayout(m_layoutVector);
389 388 }
390 389
391 390 void Axis::handleAxisUpdated()
392 391 {
393 392
394 393 if (isEmpty()) return;
395 394
396 395 if (m_chartAxis->isAxisVisible()) {
397 396 setAxisOpacity(100);
398 397 } else {
399 398 setAxisOpacity(0);
400 399 }
401 400
402 401 if (m_chartAxis->isGridLineVisible()) {
403 402 setGridOpacity(100);
404 403 } else {
405 404 setGridOpacity(0);
406 405 }
407 406
408 407 if (m_chartAxis->labelsVisible()) {
409 408 setLabelsOpacity(100);
410 409 } else {
411 410 setLabelsOpacity(0);
412 411 }
413 412
414 413 if (m_chartAxis->shadesVisible()) {
415 414 setShadesOpacity(m_chartAxis->shadesOpacity());
416 415 } else {
417 416 setShadesOpacity(0);
418 417 }
419 418
420 419 setLabelsAngle(m_chartAxis->labelsAngle());
421 420 setAxisPen(m_chartAxis->axisPen());
422 421 setLabelsPen(m_chartAxis->labelsPen());
423 422 setLabelsBrush(m_chartAxis->labelsBrush());
424 423 setLabelsFont(m_chartAxis->labelsFont());
425 424 setGridPen(m_chartAxis->gridLinePen());
426 425 setShadesPen(m_chartAxis->shadesPen());
427 426 setShadesBrush(m_chartAxis->shadesBrush());
428 427
429 428 }
430 429
431 430 void Axis::handleRangeChanged(qreal min, qreal max,int tickCount)
432 431 {
433 432 if (qFuzzyIsNull(min - max) || tickCount < 2)
434 433 return;
435 434
436 435 m_min = min;
437 436 m_max = max;
438 437 m_ticksCount= tickCount;
439 438
440 439 if (isEmpty()) return;
441 440 QVector<qreal> layout = calculateLayout();
442 441 updateLayout(layout);
443 442
444 443 }
445 444
446 445 void Axis::handleGeometryChanged(const QRectF &rect)
447 446 {
448 447 if(m_rect != rect)
449 448 {
450 449 m_rect = rect;
451 450 if (isEmpty()) return;
452 451 QVector<qreal> layout = calculateLayout();
453 452 updateLayout(layout);
454 453 }
455 454 }
456 455
457 456 void Axis::axisSelected()
458 457 {
459 458 qDebug()<<"TODO axis clicked";
460 459 }
461 460
462 461 //TODO "nice numbers algorithm"
463 #include "moc_axisitem_p.cpp"
462 #include "moc_axis_p.cpp"
464 463
465 464 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,14 +1,14
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 $$PWD/axisitem.cpp \
5 $$PWD/axis.cpp \
6 6 $$PWD/qchartaxis.cpp \
7 7 $$PWD/qchartaxiscategories.cpp
8 8
9 9 PRIVATE_HEADERS += \
10 $$PWD/axisitem_p.h
10 $$PWD/axis_p.h
11 11
12 12 PUBLIC_HEADERS += \
13 13 $$PWD/qchartaxis.h \
14 14 $$PWD/qchartaxiscategories.h No newline at end of file
1 NO CONTENT: file renamed from src/axis/axisitem_p.h to src/axis/axis_p.h
@@ -1,402 +1,402
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "qchartaxis.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 27 #include "chartanimator_p.h"
28 28 #include "qseries_p.h"
29 29 #include "qareaseries.h"
30 #include "axisitem_p.h"
30 #include "axis_p.h"
31 31 #include "areachartitem_p.h"
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
36 36 m_chart(chart),
37 37 m_animator(0),
38 38 m_dataset(dataset),
39 39 m_chartTheme(0),
40 40 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
41 41 m_options(QChart::NoAnimation),
42 42 m_minLeftMargin(0),
43 43 m_minBottomMargin(0),
44 44 m_backgroundItem(0),
45 45 m_titleItem(0),
46 46 m_marginBig(60),
47 47 m_marginSmall(20),
48 48 m_marginTiny(10),
49 49 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
50 50 {
51 51 }
52 52
53 53 ChartPresenter::~ChartPresenter()
54 54 {
55 55 delete m_chartTheme;
56 56 }
57 57
58 58 void ChartPresenter::setGeometry(const QRectF& rect)
59 59 {
60 60 m_rect = rect;
61 61 Q_ASSERT(m_rect.isValid());
62 62 updateLayout();
63 63 }
64 64
65 65 void ChartPresenter::setMinimumMarginWidth(Axis* axis, qreal width)
66 66 {
67 67 switch(axis->axisType()){
68 68 case Axis::X_AXIS:
69 69 {
70 70 if(width>m_chartRect.width()+ m_chartMargins.left()) {
71 71 m_minLeftMargin= width - m_chartRect.width();
72 72 updateLayout();
73 73 }
74 74 break;
75 75 }
76 76 case Axis::Y_AXIS:
77 77 {
78 78
79 79 if(m_minLeftMargin!=width){
80 80 m_minLeftMargin= width;
81 81 updateLayout();
82 82 }
83 83 break;
84 84 }
85 85
86 86 }
87 87 }
88 88
89 89 void ChartPresenter::setMinimumMarginHeight(Axis* axis, qreal height)
90 90 {
91 91 switch(axis->axisType()){
92 92 case Axis::X_AXIS:
93 93 {
94 94 if(m_minBottomMargin!=height) {
95 95 m_minBottomMargin= height;
96 96 updateLayout();
97 97 }
98 98 break;
99 99 }
100 100 case Axis::Y_AXIS:
101 101 {
102 102
103 103 if(height>m_chartMargins.bottom()+m_chartRect.height()){
104 104 m_minBottomMargin= height - m_chartRect.height();
105 105 updateLayout();
106 106 }
107 107 break;
108 108 }
109 109
110 110 }
111 111 }
112 112
113 113 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
114 114 {
115 115 Axis* item = new Axis(axis,this,axis==m_dataset->axisX()?Axis::X_AXIS : Axis::Y_AXIS);
116 116
117 117 if(m_options.testFlag(QChart::GridAxisAnimations)){
118 118 m_animator->addAnimation(item);
119 119 }
120 120
121 121 if(axis==m_dataset->axisX()){
122 122 m_chartTheme->decorate(axis,true);
123 123 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
124 124 //initialize
125 125 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
126 126
127 127 }
128 128 else{
129 129 m_chartTheme->decorate(axis,false);
130 130 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
131 131 //initialize
132 132 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
133 133 }
134 134
135 135 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
136 136 //initialize
137 137 item->handleGeometryChanged(m_chartRect);
138 138 m_axisItems.insert(axis, item);
139 139 }
140 140
141 141 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
142 142 {
143 143 Axis* item = m_axisItems.take(axis);
144 144 Q_ASSERT(item);
145 145 if(m_animator) m_animator->removeAnimation(item);
146 146 delete item;
147 147 }
148 148
149 149
150 150 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
151 151 {
152 152 Chart *item = series->d_ptr->createGraphics(this);
153 153 Q_ASSERT(item);
154 154 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
155 155 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
156 156 //initialize
157 157 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
158 158 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
159 159 m_chartItems.insert(series,item);
160 160 }
161 161
162 162 void ChartPresenter::handleSeriesRemoved(QSeries* series)
163 163 {
164 164 Chart* item = m_chartItems.take(series);
165 165 Q_ASSERT(item);
166 166 if(m_animator) {
167 167 //small hack to handle area animations
168 168 if(series->type()==QSeries::SeriesTypeArea){
169 169 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
170 170 AreaChartItem* area = static_cast<AreaChartItem*>(item);
171 171 m_animator->removeAnimation(area->upperLineItem());
172 172 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
173 173 }else
174 174 m_animator->removeAnimation(item);
175 175 }
176 176 delete item;
177 177 }
178 178
179 179 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
180 180 {
181 181 if(m_chartTheme && m_chartTheme->id() == theme) return;
182 182 delete m_chartTheme;
183 183 m_chartTheme = ChartTheme::createTheme(theme);
184 184 m_chartTheme->setForced(force);
185 185 m_chartTheme->decorate(m_chart);
186 186 m_chartTheme->decorate(m_chart->legend());
187 187 resetAllElements();
188 188 }
189 189
190 190 QChart::ChartTheme ChartPresenter::theme()
191 191 {
192 192 return m_chartTheme->id();
193 193 }
194 194
195 195 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
196 196 {
197 197 if(m_options!=options) {
198 198
199 199 m_options=options;
200 200
201 201 if(m_options!=QChart::NoAnimation && !m_animator) {
202 202 m_animator= new ChartAnimator(this);
203 203 }
204 204 resetAllElements();
205 205 }
206 206
207 207 }
208 208
209 209 void ChartPresenter::resetAllElements()
210 210 {
211 211 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
212 212 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
213 213
214 214 foreach(QChartAxis* axis, axisList) {
215 215 handleAxisRemoved(axis);
216 216 handleAxisAdded(axis,m_dataset->domain(axis));
217 217 }
218 218 foreach(QSeries* series, seriesList) {
219 219 handleSeriesRemoved(series);
220 220 handleSeriesAdded(series,m_dataset->domain(series));
221 221 }
222 222 }
223 223
224 224 void ChartPresenter::zoomIn()
225 225 {
226 226 QRectF rect = chartGeometry();
227 227 rect.setWidth(rect.width()/2);
228 228 rect.setHeight(rect.height()/2);
229 229 rect.moveCenter(chartGeometry().center());
230 230 zoomIn(rect);
231 231 }
232 232
233 233 void ChartPresenter::zoomIn(const QRectF& rect)
234 234 {
235 235 QRectF r = rect.normalized();
236 236 r.translate(-m_chartMargins.topLeft());
237 237 if(m_animator) {
238 238
239 239 QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
240 240 m_animator->setState(ChartAnimator::ZoomInState,point);
241 241 }
242 242 m_dataset->zoomInDomain(r,chartGeometry().size());
243 243 if(m_animator) {
244 244 m_animator->setState(ChartAnimator::ShowState);
245 245 }
246 246 }
247 247
248 248 void ChartPresenter::zoomOut()
249 249 {
250 250 if(m_animator)
251 251 {
252 252 m_animator->setState(ChartAnimator::ZoomOutState);
253 253 }
254 254
255 255 QSizeF size = chartGeometry().size();
256 256 QRectF rect = chartGeometry();
257 257 rect.translate(-m_chartMargins.topLeft());
258 258 m_dataset->zoomOutDomain(rect.adjusted(size.width()/4,size.height()/4,-size.width()/4,-size.height()/4),size);
259 259 //m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
260 260
261 261 if(m_animator){
262 262 m_animator->setState(ChartAnimator::ShowState);
263 263 }
264 264 }
265 265
266 266 void ChartPresenter::scroll(int dx,int dy)
267 267 {
268 268 if(m_animator){
269 269 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
270 270 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
271 271 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
272 272 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
273 273 }
274 274
275 275 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
276 276
277 277 if(m_animator){
278 278 m_animator->setState(ChartAnimator::ShowState);
279 279 }
280 280 }
281 281
282 282 QChart::AnimationOptions ChartPresenter::animationOptions() const
283 283 {
284 284 return m_options;
285 285 }
286 286
287 287 void ChartPresenter::updateLayout()
288 288 {
289 289 if (!m_rect.isValid()) return;
290 290
291 291 // recalculate title size
292 292
293 293 QSize titleSize;
294 294 int titlePadding=0;
295 295
296 296 if (m_titleItem) {
297 297 titleSize= m_titleItem->boundingRect().size().toSize();
298 298 }
299 299
300 300 //defaults
301 301 m_chartMargins = QRect(QPoint(m_minLeftMargin>m_marginBig?m_minLeftMargin:m_marginBig,m_marginBig),QPoint(m_marginBig,m_minBottomMargin>m_marginBig?m_minBottomMargin:m_marginBig));
302 302 titlePadding = m_chartMargins.top()/2;
303 303
304 304 QLegend* legend = m_chart->d_ptr->m_legend;
305 305
306 306 // recalculate legend position
307 307 if (legend->isAttachedToChart() && legend->isEnabled()) {
308 308
309 309 QRect legendRect;
310 310
311 311 // Reserve some space for legend
312 312 switch (legend->alignment()) {
313 313
314 314 case QLegend::AlignmentTop: {
315 315 int ledgendSize = legend->minHeight();
316 316 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
317 317 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
318 318 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
319 319 titlePadding = m_marginTiny + m_marginTiny;
320 320 break;
321 321 }
322 322 case QLegend::AlignmentBottom: {
323 323 int ledgendSize = legend->minHeight();
324 324 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
325 325 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
326 326 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
327 327 titlePadding = m_chartMargins.top()/2;
328 328 break;
329 329 }
330 330 case QLegend::AlignmentLeft: {
331 331 int ledgendSize = legend->minWidth();
332 332 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
333 333 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
334 334 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
335 335 titlePadding = m_chartMargins.top()/2;
336 336 break;
337 337 }
338 338 case QLegend::AlignmentRight: {
339 339 int ledgendSize = legend->minWidth();
340 340 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
341 341 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
342 342 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
343 343 titlePadding = m_chartMargins.top()/2;
344 344 break;
345 345 }
346 346 default: {
347 347 break;
348 348 }
349 349 }
350 350 }
351 351
352 352 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
353 353 {
354 354 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
355 355 return;
356 356 }
357 357
358 358
359 359 // recalculate title position
360 360 if (m_titleItem) {
361 361 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
362 362 m_titleItem->setPos(center.x(),titlePadding);
363 363 }
364 364
365 365 //recalculate background gradient
366 366 if (m_backgroundItem) {
367 367 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
368 368 }
369 369
370 370
371 371 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
372 372
373 373 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
374 374
375 375 if(m_chartRect!=chartRect){
376 376 m_chartRect=chartRect;
377 377 emit geometryChanged(m_chartRect);
378 378 }
379 379
380 380
381 381 }
382 382
383 383 void ChartPresenter::createChartBackgroundItem()
384 384 {
385 385 if (!m_backgroundItem) {
386 386 m_backgroundItem = new ChartBackground(rootItem());
387 387 m_backgroundItem->setPen(Qt::NoPen);
388 388 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
389 389 }
390 390 }
391 391
392 392 void ChartPresenter::createChartTitleItem()
393 393 {
394 394 if (!m_titleItem) {
395 395 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
396 396 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
397 397 }
398 398 }
399 399
400 400 #include "moc_chartpresenter_p.cpp"
401 401
402 402 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,398 +1,398
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charttheme_p.h"
22 22 #include "qchart.h"
23 23 #include "qchartview.h"
24 24 #include "qlegend.h"
25 25 #include "qchartaxis.h"
26 26 #include <QTime>
27 27
28 28 //series
29 29 #include "qbarset.h"
30 30 #include "qbarseries.h"
31 31 #include "qstackedbarseries.h"
32 32 #include "qpercentbarseries.h"
33 33 #include "qlineseries.h"
34 34 #include "qareaseries.h"
35 35 #include "qscatterseries.h"
36 36 #include "qpieseries.h"
37 37 #include "qpieslice.h"
38 38 #include "qsplineseries.h"
39 39
40 40 //items
41 #include "axisitem_p.h"
41 #include "axis_p.h"
42 42 #include "barchartitem_p.h"
43 43 #include "stackedbarchartitem_p.h"
44 44 #include "percentbarchartitem_p.h"
45 45 #include "linechartitem_p.h"
46 46 #include "areachartitem_p.h"
47 47 #include "scatterchartitem_p.h"
48 48 #include "piechartitem_p.h"
49 49 #include "splinechartitem_p.h"
50 50
51 51 //themes
52 52 #include "chartthemesystem_p.h"
53 53 #include "chartthemelight_p.h"
54 54 #include "chartthemebluecerulean_p.h"
55 55 #include "chartthemedark_p.h"
56 56 #include "chartthemebrownsand_p.h"
57 57 #include "chartthemebluencs_p.h"
58 58 #include "chartthemehighcontrast_p.h"
59 59 #include "chartthemeblueicy_p.h"
60 60
61 61 QTCOMMERCIALCHART_BEGIN_NAMESPACE
62 62
63 63 ChartTheme::ChartTheme(QChart::ChartTheme id) :
64 64 m_masterFont(QFont("arial", 14)),
65 65 m_labelFont(QFont("arial", 10)),
66 66 m_titleBrush(QColor(QRgb(0x000000))),
67 67 m_axisLinePen(QPen(QRgb(0x000000))),
68 68 m_axisLabelBrush(QColor(QRgb(0x000000))),
69 69 m_backgroundShadesPen(Qt::NoPen),
70 70 m_backgroundShadesBrush(Qt::NoBrush),
71 71 m_backgroundShades(BackgroundShadesNone),
72 72 m_gridLinePen(QPen(QRgb(0x000000))),
73 73 m_force(false)
74 74 {
75 75 m_id = id;
76 76 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
77 77 }
78 78
79 79
80 80 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
81 81 {
82 82 switch(theme) {
83 83 case QChart::ChartThemeLight:
84 84 return new ChartThemeLight();
85 85 case QChart::ChartThemeBlueCerulean:
86 86 return new ChartThemeBlueCerulean();
87 87 case QChart::ChartThemeDark:
88 88 return new ChartThemeDark();
89 89 case QChart::ChartThemeBrownSand:
90 90 return new ChartThemeBrownSand();
91 91 case QChart::ChartThemeBlueNcs:
92 92 return new ChartThemeBlueNcs();
93 93 case QChart::ChartThemeHighContrast:
94 94 return new ChartThemeHighContrast();
95 95 case QChart::ChartThemeBlueIcy:
96 96 return new ChartThemeBlueIcy();
97 97 default:
98 98 return new ChartThemeSystem();
99 99 }
100 100 }
101 101
102 102 void ChartTheme::decorate(QChart *chart)
103 103 {
104 104 QBrush brush;
105 105
106 106 if(brush == chart->backgroundBrush() || m_force)
107 107 chart->setBackgroundBrush(m_chartBackgroundGradient);
108 108 chart->setTitleFont(m_masterFont);
109 109 chart->setTitleBrush(m_titleBrush);
110 110 }
111 111
112 112 void ChartTheme::decorate(QLegend *legend)
113 113 {
114 114 QPen pen;
115 115 QBrush brush;
116 116
117 117 if (pen == legend->pen() || m_force){
118 118 legend->setPen(Qt::NoPen);
119 119 }
120 120
121 121
122 122 if (brush == legend->brush() || m_force) {
123 123 legend->setBrush(m_chartBackgroundGradient);
124 124 }
125 125 }
126 126
127 127 void ChartTheme::decorate(QAreaSeries *series, int index)
128 128 {
129 129 QPen pen;
130 130 QBrush brush;
131 131
132 132 if (pen == series->pen() || m_force){
133 133 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
134 134 pen.setWidthF(2);
135 135 series->setPen(pen);
136 136 }
137 137
138 138 if (brush == series->brush() || m_force) {
139 139 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
140 140 series->setBrush(brush);
141 141 }
142 142 }
143 143
144 144
145 145 void ChartTheme::decorate(QLineSeries *series,int index)
146 146 {
147 147 QPen pen;
148 148 if(pen == series->pen() || m_force ){
149 149 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
150 150 pen.setWidthF(2);
151 151 series->setPen(pen);
152 152 }
153 153 }
154 154
155 155 void ChartTheme::decorate(QBarSeries *series, int index)
156 156 {
157 157 QBrush brush;
158 158 QPen pen;
159 159 QList<QBarSet *> sets = series->barSets();
160 160
161 161 qreal takeAtPos = 0.5;
162 162 qreal step = 0.2;
163 163 if (sets.count() > 1 ) {
164 164 step = 1.0 / (qreal) sets.count();
165 165 if (sets.count() % m_seriesGradients.count())
166 166 step *= m_seriesGradients.count();
167 167 else
168 168 step *= (m_seriesGradients.count() - 1);
169 169 }
170 170
171 171 for (int i(0); i < sets.count(); i++) {
172 172 int colorIndex = (index + i) % m_seriesGradients.count();
173 173 if (i > 0 && i % m_seriesGradients.count() == 0) {
174 174 // There is no dedicated base color for each sets, generate more colors
175 175 takeAtPos += step;
176 176 if (takeAtPos == 1.0)
177 177 takeAtPos += step;
178 178 takeAtPos -= (int) takeAtPos;
179 179 }
180 180 if (brush == sets.at(i)->brush() || m_force )
181 181 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
182 182
183 183 // Pick label color from the opposite end of the gradient.
184 184 // 0.3 as a boundary seems to work well.
185 185 if (takeAtPos < 0.3)
186 186 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
187 187 else
188 188 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
189 189
190 190 if (pen == sets.at(i)->pen() || m_force) {
191 191 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
192 192 sets.at(i)->setPen(c);
193 193 }
194 194 }
195 195 }
196 196
197 197 void ChartTheme::decorate(QScatterSeries *series, int index)
198 198 {
199 199 QPen pen;
200 200 QBrush brush;
201 201
202 202 if (pen == series->pen() || m_force) {
203 203 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
204 204 pen.setWidthF(2);
205 205 series->setPen(pen);
206 206 }
207 207
208 208 if (brush == series->brush() || m_force) {
209 209 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
210 210 series->setBrush(brush);
211 211 }
212 212 }
213 213
214 214 void ChartTheme::decorate(QPieSeries *series, int index)
215 215 {
216 216
217 217 for (int i(0); i < series->slices().count(); i++) {
218 218
219 219 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
220 220
221 221 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
222 222 qreal pos = (qreal) (i + 1) / (qreal) series->count();
223 223 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
224 224
225 225 QPieSlice *s = series->slices().at(i);
226 226 PieSliceData data = PieSliceData::data(s);
227 227
228 228 if (data.m_slicePen.isThemed() || m_force) {
229 229 data.m_slicePen = penColor;
230 230 data.m_slicePen.setThemed(true);
231 231 }
232 232
233 233 if (data.m_sliceBrush.isThemed() || m_force) {
234 234 data.m_sliceBrush = brushColor;
235 235 data.m_sliceBrush.setThemed(true);
236 236 }
237 237
238 238 if (data.m_labelPen.isThemed() || m_force) {
239 239 data.m_labelPen = QPen(m_titleBrush.color());
240 240 data.m_labelPen.setThemed(true);
241 241 }
242 242
243 243 if (data.m_labelFont.isThemed() || m_force) {
244 244 data.m_labelFont = m_labelFont;
245 245 data.m_labelFont.setThemed(true);
246 246 }
247 247
248 248 if (PieSliceData::data(s) != data) {
249 249 PieSliceData::data(s) = data;
250 250 emit PieSliceData::data(s).emitChangedSignal(s);
251 251 }
252 252 }
253 253 }
254 254
255 255 void ChartTheme::decorate(QSplineSeries *series, int index)
256 256 {
257 257 QPen pen;
258 258 if(pen == series->pen() || m_force){
259 259 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
260 260 pen.setWidthF(2);
261 261 series->setPen(pen);
262 262 }
263 263 }
264 264
265 265 void ChartTheme::decorate(QChartAxis *axis,bool axisX)
266 266 {
267 267 QPen pen;
268 268 QBrush brush;
269 269 QFont font;
270 270
271 271 if (axis->isAxisVisible()) {
272 272
273 273 if(brush == axis->labelsBrush() || m_force){
274 274 axis->setLabelsBrush(m_axisLabelBrush);
275 275 }
276 276 if(pen == axis->labelsPen() || m_force){
277 277 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
278 278 }
279 279
280 280
281 281 if (axis->shadesVisible() || m_force) {
282 282
283 283 if(brush == axis->shadesBrush() || m_force){
284 284 axis->setShadesBrush(m_backgroundShadesBrush);
285 285 }
286 286
287 287 if(pen == axis->shadesPen() || m_force){
288 288 axis->setShadesPen(m_backgroundShadesPen);
289 289 }
290 290
291 291 if( m_force && (m_backgroundShades == BackgroundShadesBoth
292 292 || (m_backgroundShades == BackgroundShadesVertical && axisX)
293 293 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
294 294 axis->setShadesVisible(true);
295 295
296 296 }
297 297 }
298 298
299 299 if(pen == axis->axisPen() || m_force){
300 300 axis->setAxisPen(m_axisLinePen);
301 301 }
302 302
303 303 if(pen == axis->gridLinePen() || m_force){
304 304 axis->setGridLinePen(m_gridLinePen);
305 305 }
306 306
307 307 if(font == axis->labelsFont() || m_force){
308 308 axis->setLabelsFont(m_labelFont);
309 309 }
310 310 }
311 311 }
312 312
313 313 void ChartTheme::generateSeriesGradients()
314 314 {
315 315 // Generate gradients in HSV color space
316 316 foreach (QColor color, m_seriesColors) {
317 317 QLinearGradient g;
318 318 qreal h = color.hsvHueF();
319 319 qreal s = color.hsvSaturationF();
320 320
321 321 // TODO: tune the algorithm to give nice results with most base colors defined in
322 322 // most themes. The rest of the gradients we can define manually in theme specific
323 323 // implementation.
324 324 QColor start = color;
325 325 start.setHsvF(h, 0.0, 1.0);
326 326 g.setColorAt(0.0, start);
327 327
328 328 g.setColorAt(0.5, color);
329 329
330 330 QColor end = color;
331 331 end.setHsvF(h, s, 0.25);
332 332 g.setColorAt(1.0, end);
333 333
334 334 m_seriesGradients << g;
335 335 }
336 336 }
337 337
338 338
339 339 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
340 340 {
341 341 Q_ASSERT(pos >= 0.0 && pos <= 1.0);
342 342 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
343 343 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
344 344 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
345 345 QColor c;
346 346 c.setRgbF(r, g, b);
347 347 return c;
348 348 }
349 349
350 350 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
351 351 {
352 352 Q_ASSERT(pos >= 0 && pos <= 1.0);
353 353
354 354 // another possibility:
355 355 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
356 356
357 357 QGradientStops stops = gradient.stops();
358 358 int count = stops.count();
359 359
360 360 // find previous stop relative to position
361 361 QGradientStop prev = stops.first();
362 362 for (int i = 0; i < count; i++) {
363 363 QGradientStop stop = stops.at(i);
364 364 if (pos > stop.first)
365 365 prev = stop;
366 366
367 367 // given position is actually a stop position?
368 368 if (pos == stop.first) {
369 369 //qDebug() << "stop color" << pos;
370 370 return stop.second;
371 371 }
372 372 }
373 373
374 374 // find next stop relative to position
375 375 QGradientStop next = stops.last();
376 376 for (int i = count - 1; i >= 0; i--) {
377 377 QGradientStop stop = stops.at(i);
378 378 if (pos < stop.first)
379 379 next = stop;
380 380 }
381 381
382 382 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
383 383
384 384 qreal range = next.first - prev.first;
385 385 qreal posDelta = pos - prev.first;
386 386 qreal relativePos = posDelta / range;
387 387
388 388 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
389 389
390 390 return colorAt(prev.second, next.second, relativePos);
391 391 }
392 392
393 393 void ChartTheme::setForced(bool enabled)
394 394 {
395 395 m_force=enabled;
396 396 }
397 397
398 398 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now