##// END OF EJS Templates
Barchart value layout fix
sauimone -
r817:2ecb2f756c9b
parent child
Show More
@@ -1,233 +1,222
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 "barchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barvalue_p.h"
24 24 #include "qbarset.h"
25 25 #include "qbarseries.h"
26 26 #include "qchart.h"
27 27 #include "qchartaxis.h"
28 28 #include "qchartaxiscategories.h"
29 29 #include "chartpresenter_p.h"
30 30 #include "chartanimator_p.h"
31 31 #include "chartdataset_p.h"
32 32 #include <QDebug>
33 33 #include <QToolTip>
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
38 38 ChartItem(presenter),
39 39 m_layoutSet(false),
40 40 m_series(series)
41 41 {
42 42 connect(series, SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString)));
43 43 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
44 44 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
45 45 setZValue(ChartPresenter::BarSeriesZValue);
46 46 dataChanged();
47 47 }
48 48
49 49 BarChartItem::~BarChartItem()
50 50 {
51 51 disconnect(this,SLOT(showToolTip(QPoint,QString)));
52 52 }
53 53
54 54 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
55 55 {
56 56 if (!m_layoutSet) {
57 57 qWarning() << "BarChartItem::paint called without layout set. Aborting.";
58 58 return;
59 59 }
60 60
61 61 foreach(QGraphicsItem* i, childItems())
62 62 i->paint(painter,option,widget);
63 63 }
64 64
65 65 QRectF BarChartItem::boundingRect() const
66 66 {
67 67 return m_rect;
68 68 }
69 69
70 70 void BarChartItem::dataChanged()
71 71 {
72 72 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
73 73 // Delete old bars
74 74 foreach (QGraphicsItem *item, childItems())
75 75 delete item;
76 76
77 77 m_bars.clear();
78 78 m_values.clear();
79 79 m_layout.clear();
80 80
81 81 // Create new graphic items for bars
82 82 for (int c = 0; c < m_series->categoryCount(); c++) {
83 83 QString category = m_series->categoryName(c);
84 84 for (int s = 0; s < m_series->barsetCount(); s++) {
85 85 QBarSet *set = m_series->barsetAt(s);
86 86 Bar *bar = new Bar(category,this);
87 87 childItems().append(bar);
88 88 m_bars.append(bar);
89 89 connect(bar, SIGNAL(clicked(QString,Qt::MouseButtons)), set, SIGNAL(clicked(QString,Qt::MouseButtons)));
90 90 connect(bar, SIGNAL(hoverEntered(QPoint)), set, SLOT(barHoverEnterEvent(QPoint)));
91 91 connect(bar, SIGNAL(hoverLeaved()), set, SLOT(barHoverLeaveEvent()));
92 92 m_layout.append(QRectF(0, 0, 0, 0));
93 93 }
94 94 }
95 95
96 // Create floating values
96 // Create value items
97 97 for (int category = 0; category < m_series->categoryCount(); category++) {
98 98 for (int s = 0; s < m_series->barsetCount(); s++) {
99 99 QBarSet *set = m_series->barsetAt(s);
100 100 BarValue *value = new BarValue(*set, this);
101 101 childItems().append(value);
102 102 m_values.append(value);
103 103 connect(set,SIGNAL(valuesVisibleChanged(bool)),value,SLOT(valuesVisibleChanged(bool)));
104 104 }
105 105 }
106 106 }
107 107
108 108 QVector<QRectF> BarChartItem::calculateLayout()
109 109 {
110 110 QVector<QRectF> layout;
111 111
112 112 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
113 113 qreal categoryCount = m_series->categoryCount();
114 114 qreal setCount = m_series->barsetCount();
115 115
116 116 qreal width = geometry().width();
117 117 qreal height = geometry().height();
118 118
119 119 qreal max = m_series->max();
120 120
121 121 // Domain:
122 122 if (m_domainMaxY > max) {
123 123 max = m_domainMaxY;
124 124 }
125 125
126 126 qreal scale = (height / max);
127 127 qreal categoryWidth = width / categoryCount;
128 128 qreal barWidth = categoryWidth / (setCount+1);
129 129
130 130 int itemIndex(0);
131 131 for (int category = 0; category < categoryCount; category++) {
132 132 qreal xPos = categoryWidth * category + barWidth / 2;
133 133 qreal yPos = height;
134 134 for (int set = 0; set < setCount; set++) {
135 qreal barHeight = m_series->valueAt(set, category) * scale;
135 QBarSet* barSet = m_series->barsetAt(set);
136
137 qreal barHeight = barSet->valueAt(category) * scale;
136 138 Bar* bar = m_bars.at(itemIndex);
137 139
138 140 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
139 141 layout.append(rect);
140 bar->setPen(m_series->barsetAt(set)->pen());
141 bar->setBrush(m_series->barsetAt(set)->brush());
142 itemIndex++;
143 xPos += barWidth;
144 }
145 }
142 bar->setPen(barSet->pen());
143 bar->setBrush(barSet->brush());
146 144
147 // Position floating values
148 itemIndex = 0;
149 for (int category = 0; category < m_series->categoryCount(); category++) {
150 qreal xPos = categoryWidth * category + barWidth;
151 qreal yPos = height;
152 for (int set=0; set < m_series->barsetCount(); set++) {
153 qreal barHeight = m_series->valueAt(set, category) * scale;
154 145 BarValue* value = m_values.at(itemIndex);
155 146
156 QBarSet* barSet = m_series->barsetAt(set);
157
158 if (!qFuzzyIsNull(m_series->valueAt(set,category))) {
159 value->setText(QString::number(m_series->valueAt(set, category)));
147 if (!qFuzzyIsNull(barSet->valueAt(category))) {
148 value->setText(QString::number(barSet->valueAt(category)));
160 149 } else {
161 150 value->setText(QString(""));
162 151 }
163 152
164 value->setPos(xPos, yPos-barHeight / 2);
165 value->setPen(barSet->floatingValuePen());
153 value->setPos(xPos + (rect.width()/2 - value->boundingRect().width()/2)
154 ,yPos - barHeight/2 - value->boundingRect().height()/2);
155 value->setPen(barSet->valuePen());
166 156
167 157 itemIndex++;
168 158 xPos += barWidth;
169 159 }
170 160 }
171
172 161 return layout;
173 162 }
174 163
175 164 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
176 165 {
177 166 if (animator())
178 167 animator()->updateLayout(this, m_layout, layout);
179 168 else
180 169 setLayout(layout);
181 170 }
182 171
183 172 void BarChartItem::setLayout(const QVector<QRectF> &layout)
184 173 {
185 174 m_layout = layout;
186 175
187 176 for (int i=0; i < m_bars.count(); i++)
188 177 m_bars.at(i)->setRect(layout.at(i));
189 178
190 179 update();
191 180 }
192 181
193 182 //handlers
194 183
195 184 void BarChartItem::handleModelChanged(int index)
196 185 {
197 186 Q_UNUSED(index)
198 187 dataChanged();
199 188 }
200 189
201 190 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
202 191 {
203 192 m_domainMinX = minX;
204 193 m_domainMaxX = maxX;
205 194 m_domainMinY = minY;
206 195 m_domainMaxY = maxY;
207 196 handleLayoutChanged();
208 197 }
209 198
210 199 void BarChartItem::handleGeometryChanged(const QRectF &rect)
211 200 {
212 201 m_rect = rect;
213 202 handleLayoutChanged();
214 203 m_layoutSet = true;
215 204 setPos(rect.topLeft());
216 205 }
217 206
218 207 void BarChartItem::handleLayoutChanged()
219 208 {
220 209 QVector<QRectF> layout = calculateLayout();
221 210 applyLayout(layout);
222 211 update();
223 212 }
224 213
225 214 void BarChartItem::showToolTip(QPoint pos, QString tip)
226 215 {
227 216 // TODO: cool tooltip instead of default
228 217 QToolTip::showText(pos, tip);
229 218 }
230 219
231 220 #include "moc_barchartitem_p.cpp"
232 221
233 222 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,92 +1,89
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 BARCHARTITEM_H
22 22 #define BARCHARTITEM_H
23 23
24 24 #include "chartitem_p.h"
25 25 #include "qbarseries.h"
26 26 #include <QPen>
27 27 #include <QBrush>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class Bar;
32 32 class BarValue;
33 33 class QChartAxisCategories;
34 34 class QChart;
35 35
36 36 //typedef QVector<QRectF> BarLayout;
37 37
38 38 class BarChartItem : public ChartItem
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
43 43 virtual ~BarChartItem();
44 44
45 // Common implemantation of different presenters. Not to be instantiated.
46 // TODO: combine this with BarPresenter and derive other presenters from it?
47
48 45 public:
49 46 // From QGraphicsItem
50 47 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
51 48 QRectF boundingRect() const;
52 49
53 50 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
54 51 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
55 52
56 53 virtual QVector<QRectF> calculateLayout();
57 54 void applyLayout(const QVector<QRectF> &layout);
58 55 void setLayout(const QVector<QRectF> &layout);
59 56 void updateLayout(const QVector<QRectF> &layout);
60 57
61 58 QRectF geometry() const { return m_rect;}
62 59
63 60 public Q_SLOTS:
64 61 void handleModelChanged(int index);
65 62 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
66 63 void handleGeometryChanged(const QRectF &size);
67 64 void handleLayoutChanged();
68 65
69 66 // Internal slots
70 67 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
71 68
72 69 protected:
73 70
74 71 // TODO: consider these.
75 72 qreal m_domainMinX;
76 73 qreal m_domainMaxX;
77 74 qreal m_domainMinY;
78 75 qreal m_domainMaxY;
79 76
80 77 QRectF m_rect;
81 78 bool m_layoutSet; // True, if component has been laid out.
82 79 QVector<QRectF> m_layout;
83 80
84 81 // Not owned.
85 82 QBarSeries *m_series;
86 83 QList<Bar *> m_bars;
87 84 QList<BarValue *> m_values;
88 85 };
89 86
90 87 QTCOMMERCIALCHART_END_NAMESPACE
91 88
92 89 #endif // BARCHARTITEM_H
@@ -1,89 +1,90
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 "barvalue_p.h"
22 22 #include <QPainter>
23 23 #include <QPen>
24 24 #include <QGraphicsSimpleTextItem>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 BarValue::BarValue(QBarSet &set, QGraphicsItem *parent) : QGraphicsObject(parent),
29 29 m_barSet(set),
30 30 m_textItem(new QGraphicsSimpleTextItem(this))
31 31 {
32 32 // connect(&set,SIGNAL(valuesVisibleChanged(bool)),value,SLOT(valuesVisibleChanged(bool)));
33 33 setVisible(false);
34 34 }
35 35
36 36 void BarValue::setText(QString str)
37 37 {
38 38 m_textItem->setText(str);
39 39 }
40 40
41 41 QString BarValue::text() const
42 42 {
43 43 return m_textItem->text();
44 44 }
45 45
46 46 void BarValue::setPen(const QPen &pen)
47 47 {
48 48 m_textItem->setPen(pen);
49 49 }
50 50
51 51 QPen BarValue::pen() const
52 52 {
53 53 return m_textItem->pen();
54 54 }
55 55
56 56 void BarValue::setFont(const QFont &font)
57 57 {
58 58 m_textItem->setFont(font);
59 59 }
60 60
61 61 QFont BarValue::font() const
62 62 {
63 63 return m_textItem->font();
64 64 }
65 65
66 66 void BarValue::setPos(qreal x, qreal y)
67 67 {
68 68 m_textItem->setPos(x,y);
69 69 }
70 70
71 71 void BarValue::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
72 72 {
73 73 Q_UNUSED(painter)
74 74 Q_UNUSED(option)
75 75 Q_UNUSED(widget)
76 76 }
77 77
78 78 QRectF BarValue::boundingRect() const
79 79 {
80 80 return m_textItem->boundingRect();
81 81 }
82 82
83 83 void BarValue::valuesVisibleChanged(bool visible)
84 84 {
85 qDebug() << "BarValue visiblle changed:" <<visible;
85 86 setVisible(visible);
86 87 }
87 88
88 89 #include "moc_barvalue_p.cpp"
89 90 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,67
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 BARVALUE_P_H
22 22 #define BARVALUE_P_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include <QGraphicsObject>
26 26 #include <QPen>
27 27 class QGraphicsSimpleTextItem;
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class QBarSet;
32 32
33 // Visual class for floating bar values
33 // Visual class for bar values
34 34 // By default these are not visible.
35 35 class BarValue : public QGraphicsObject
36 36 {
37 37 Q_OBJECT
38 38 public:
39 39 BarValue(QBarSet &set, QGraphicsItem *parent = 0);
40 40
41 41 void setText(QString str);
42 42 QString text() const;
43 43
44 44 void setPen(const QPen &pen);
45 45 QPen pen() const;
46 46
47 47 void setFont(const QFont &font);
48 48 QFont font() const;
49 49
50 50 void setPos(qreal x, qreal y);
51 51
52 52 // From QGraphicsItem
53 53 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
54 54 QRectF boundingRect() const;
55 55
56 56 public Q_SLOTS:
57 57 void valuesVisibleChanged(bool visible);
58 58
59 59 private:
60 60
61 61 QBarSet &m_barSet;
62 62 QGraphicsSimpleTextItem *m_textItem;
63 63 };
64 64
65 65 QTCOMMERCIALCHART_END_NAMESPACE
66 66
67 67 #endif // BARVALUE_P_H
@@ -1,101 +1,86
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 "percentbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barvalue_p.h"
24 24 #include "qbarset.h"
25 25 #include <QDebug>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
30 30 BarChartItem(series, presenter)
31 31 {
32 32 }
33 33
34 34 QVector<QRectF> PercentBarChartItem::calculateLayout()
35 35 {
36 36 QVector<QRectF> layout;
37 37
38 38 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
39 39 qreal width = geometry().width();
40 40 qreal height = geometry().height();
41 41
42 42 qreal categoryCount = m_series->categoryCount();
43 43 qreal barWidth = width / (m_series->categoryCount() * 2);
44 44 qreal xStep = width / categoryCount;
45 45 qreal xPos = xStep / 2 - barWidth / 2;
46 46
47 47 int itemIndex(0);
48 48 for (int category = 0; category < categoryCount; category++) {
49 49 qreal colSum = m_series->categorySum(category);
50 50 qreal scale = (height / colSum);
51 51 qreal yPos = height;
52 52 for (int set=0; set < m_series->barsetCount(); set++) {
53 qreal barHeight = m_series->valueAt(set, category) * scale;
53 QBarSet* barSet = m_series->barsetAt(set);
54 qreal barHeight = barSet->valueAt(category) * scale;
54 55 Bar* bar = m_bars.at(itemIndex);
55 bar->setPen(m_series->barsetAt(set)->pen());
56 bar->setBrush(m_series->barsetAt(set)->brush());
56 bar->setPen(barSet->pen());
57 bar->setBrush(barSet->brush());
57 58 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
58 59 layout.append(rect);
59 itemIndex++;
60 yPos -= barHeight;
61 }
62 xPos += xStep;
63 }
64 60
65 // Position floating values
66 itemIndex = 0;
67 xPos = (width/categoryCount);
68 for (int category=0; category < m_series->categoryCount(); category++) {
69 qreal yPos = height;
70 qreal colSum = m_series->categorySum(category);
71 qreal scale = (height / colSum);
72 for (int set=0; set < m_series->barsetCount(); set++) {
73 qreal barHeight = m_series->valueAt(set,category) * scale;
74 61 BarValue* value = m_values.at(itemIndex);
75 62
76 QBarSet* barSet = m_series->barsetAt(set);
77
78 63 if (!qFuzzyIsNull(m_series->valueAt(set,category))) {
79 64 int p = m_series->percentageAt(set,category) * 100;
80 65 QString vString(QString::number(p));
81 66 vString.truncate(3);
82 67 vString.append("%");
83 68 value->setText(vString);
84 69 } else {
85 70 value->setText(QString(""));
86 71 }
87 72
88 value->setPos(xPos, yPos-barHeight / 2);
89 value->setPen(barSet->floatingValuePen());
90
73 value->setPos(xPos + (rect.width()/2 - value->boundingRect().width()/2)
74 ,yPos - barHeight/2 - value->boundingRect().height()/2);
75 value->setPen(barSet->valuePen());
91 76 itemIndex++;
92 77 yPos -= barHeight;
93 78 }
94 79 xPos += xStep;
95 80 }
96 81 return layout;
97 82 }
98 83
99 84 #include "moc_percentbarchartitem_p.cpp"
100 85
101 86 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,229 +1,229
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 "qbarset.h"
22 22 #include <QDebug>
23 23 #include <QToolTip>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 /*!
28 28 \class QBarSet
29 29 \brief part of QtCommercial chart API.
30 30
31 31 QBarSet represents one set of bars. Set of bars contains one data value for each category.
32 32 First value of set is assumed to belong to first category, second to second category and so on.
33 33 If set has fewer values than there are categories, then the missing values are assumed to be
34 34 at the end of set. For missing values in middle of a set, numerical value of zero is used.
35 35
36 36 \mainclass
37 37
38 38 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
39 39 */
40 40
41 41 /*!
42 42 \fn void QBarSet::clicked(QString category, Qt::MouseButtons button)
43 43 \brief signals that set has been clicked
44 44 Parameter \a category describes on which category was clicked
45 45 Parameter \a button mouse button
46 46 */
47 47
48 48 /*!
49 49 \fn void QBarSet::hoverEnter(QPoint pos)
50 50 \brief signals that mouse has entered over the set at position \a pos.
51 51 */
52 52
53 53 /*!
54 54 \fn void QBarSet::hoverLeave()
55 55 \brief signals that mouse has left from the set.
56 56 */
57 57
58 58 /*!
59 \fn void QBarSet::toggleFloatingValues()
60 \brief \internal
59 \fn void QBarSet::setValuesVisible(bool visible = true)
60 \brief Sets visibility of bar values. Values are visible, if parameter \a visible is true
61 61 */
62 62
63 63 /*!
64 64 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
65 65 \brief \internal \a pos \a tip
66 66 */
67 67
68 68
69 69 /*!
70 70 Constructs QBarSet with a name of \a name and with parent of \a parent
71 71 */
72 72 QBarSet::QBarSet(QString name, QObject *parent)
73 73 : QObject(parent)
74 74 ,m_name(name)
75 75 {
76 76 }
77 77
78 78 /*!
79 79 Sets new \a name for set.
80 80 */
81 81 void QBarSet::setName(QString name)
82 82 {
83 83 m_name = name;
84 84 }
85 85
86 86 /*!
87 87 Returns name of the set.
88 88 */
89 89 QString QBarSet::name() const
90 90 {
91 91 return m_name;
92 92 }
93 93
94 94 /*!
95 95 Appends new value \a value to the end of set.
96 96 */
97 97 QBarSet& QBarSet::operator << (const qreal &value)
98 98 {
99 99 m_values.append(value);
100 100 emit structureChanged();
101 101 return *this;
102 102 }
103 103
104 104 void QBarSet::insertValue(int i, qreal value)
105 105 {
106 106 m_values.insert(i, value);
107 107 }
108 108
109 109 void QBarSet::removeValue(int i)
110 110 {
111 111 m_values.removeAt(i);
112 112 }
113 113
114 114 /*!
115 115 Returns count of values in set.
116 116 */
117 117 int QBarSet::count() const
118 118 {
119 119 return m_values.count();
120 120 }
121 121
122 122 /*!
123 123 Returns value of set indexed by \a index
124 124 */
125 125 qreal QBarSet::valueAt(int index) const
126 126 {
127 127 return m_values.at(index);
128 128 }
129 129
130 130 /*!
131 131 Sets a new value \a value to set, indexed by \a index
132 132 */
133 133 void QBarSet::setValue(int index, qreal value)
134 134 {
135 135 m_values.replace(index,value);
136 136 emit valueChanged();
137 137 }
138 138
139 139 /*!
140 140 Returns total sum of all values in barset.
141 141 */
142 142 qreal QBarSet::total() const
143 143 {
144 144 qreal total(0);
145 145 for (int i=0; i < m_values.count(); i++) {
146 146 total += m_values.at(i);
147 147 }
148 148 return total;
149 149 }
150 150
151 151 /*!
152 152 Sets pen for set. Bars of this set are drawn using \a pen
153 153 */
154 154 void QBarSet::setPen(const QPen &pen)
155 155 {
156 156 m_pen = pen;
157 157 emit valueChanged();
158 158 }
159 159
160 160 /*!
161 161 Returns pen of the set.
162 162 */
163 163 QPen QBarSet::pen() const
164 164 {
165 165 return m_pen;
166 166 }
167 167
168 168 /*!
169 169 Sets brush for the set. Bars of this set are drawn using \a brush
170 170 */
171 171 void QBarSet::setBrush(const QBrush &brush)
172 172 {
173 173 m_brush = brush;
174 174 emit valueChanged();
175 175 }
176 176
177 177 /*!
178 178 Returns brush of the set.
179 179 */
180 180 QBrush QBarSet::brush() const
181 181 {
182 182 return m_brush;
183 183 }
184 184
185 185 /*!
186 Sets the pen for floating values that are drawn on top of this set
186 Sets the pen for values that are drawn on top of this set
187 187 */
188 void QBarSet::setFloatingValuePen(const QPen &pen)
188 void QBarSet::setValuePen(const QPen &pen)
189 189 {
190 m_floatingValuePen = pen;
190 m_valuePen = pen;
191 191 }
192 192
193 193 /*!
194 Returns the pen for floating values that are drawn on top of this set
194 Returns the pen for values that are drawn on top of this set
195 195 */
196 QPen QBarSet::floatingValuePen() const
196 QPen QBarSet::valuePen() const
197 197 {
198 return m_floatingValuePen;
198 return m_valuePen;
199 199 }
200 200
201 201 /*!
202 202 Sets the visibility of barset values to \a visible
203 203 */
204 204 void QBarSet::setValuesVisible(bool visible)
205 205 {
206 206 emit valuesVisibleChanged(visible);
207 207 }
208 208
209 209 /*!
210 210 \internal \a pos
211 211 */
212 212 void QBarSet::barHoverEnterEvent(QPoint pos)
213 213 {
214 214 emit showToolTip(pos, m_name);
215 215 emit hoverEnter(pos);
216 216 }
217 217
218 218 /*!
219 219 \internal
220 220 */
221 221 void QBarSet::barHoverLeaveEvent()
222 222 {
223 223 // Emit signal to user of charts
224 224 emit hoverLeave();
225 225 }
226 226
227 227 #include "moc_qbarset.cpp"
228 228
229 229 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,94 +1,94
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 QBARSET_H
22 22 #define QBARSET_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QPen>
26 26 #include <QBrush>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
31 31 {
32 32 Q_OBJECT
33 33 public:
34 34 QBarSet(QString name, QObject *parent = 0);
35 35
36 36 void setName(QString name);
37 37 QString name() const;
38 38 QBarSet& operator << (const qreal &value); // appends new value to set
39 39 void insertValue(int i, qreal value);
40 40 void removeValue(int i);
41 41
42 42 // TODO: remove indices eventually. Use as internal?
43 43 int count() const; // count of values in set
44 44 qreal valueAt(int index) const; // for modifying individual values
45 45 void setValue(int index, qreal value); // setter for individual value
46 46 qreal total() const; // total values in the set
47 47
48 48 // TODO:
49 49 //qreal value(QString category);
50 50 //void setValue(QString category, qreal value);
51 51
52 52 void setPen(const QPen &pen);
53 53 QPen pen() const;
54 54
55 55 void setBrush(const QBrush &brush);
56 56 QBrush brush() const;
57 57
58 void setFloatingValuePen(const QPen &pen);
59 QPen floatingValuePen() const;
58 void setValuePen(const QPen &pen);
59 QPen valuePen() const;
60 60
61 61 void setValuesVisible(bool visible = true);
62 62
63 63 Q_SIGNALS:
64 64 void clicked(QString category, Qt::MouseButtons button); // Clicked and hover signals exposed to user
65 65
66 66 // TODO: TO PIMPL --->
67 67 void structureChanged();
68 68 void valueChanged();
69 69 void hoverEnter(QPoint pos);
70 70 void hoverLeave();
71 71 void showToolTip(QPoint pos, QString tip); // Private signal
72 72 void valuesVisibleChanged(bool visible);
73 73 // <--- TO PIMPL
74 74
75 75 public Q_SLOTS:
76 76 // These are for internal communication
77 77 // TODO: TO PIMPL --->
78 78 void barHoverEnterEvent(QPoint pos);
79 79 void barHoverLeaveEvent();
80 80 // <--- TO PIMPL
81 81
82 82 private:
83 83
84 84 QString m_name;
85 85 QList<qreal> m_values; // TODO: replace with map (category, value)
86 86 QMap<QString, qreal> m_mappedValues;
87 87 QPen m_pen;
88 88 QBrush m_brush;
89 QPen m_floatingValuePen;
89 QPen m_valuePen;
90 90 };
91 91
92 92 QTCOMMERCIALCHART_END_NAMESPACE
93 93
94 94 #endif // QBARSET_H
@@ -1,103 +1,93
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 "stackedbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barvalue_p.h"
24 24 #include "qbarset.h"
25 25 #include <QDebug>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
30 30 BarChartItem(series, presenter)
31 31 {
32 32 }
33 33
34 34 StackedBarChartItem::~StackedBarChartItem()
35 35 {
36 36 }
37 37
38 38 QVector<QRectF> StackedBarChartItem::calculateLayout()
39 39 {
40 40 QVector<QRectF> layout;
41 41 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
42 42
43 43 qreal maxSum = m_series->maxCategorySum();
44 44 // Domain:
45 45 if (m_domainMaxY > maxSum) {
46 46 maxSum = m_domainMaxY;
47 47 }
48 48
49 49 qreal height = geometry().height();
50 50 qreal width = geometry().width();
51 51 qreal scale = (height / m_series->maxCategorySum());
52 52 qreal categotyCount = m_series->categoryCount();
53 53 qreal barWidth = width / (categotyCount * 2);
54 54 qreal xStep = width / categotyCount;
55 55 qreal xPos = xStep / 2 - barWidth / 2;
56 56
57 57 int itemIndex(0);
58 58 for (int category = 0; category < categotyCount; category++) {
59 59 qreal yPos = height;
60 60 for (int set=0; set < m_series->barsetCount(); set++) {
61 qreal barHeight = m_series->valueAt(set, category) * scale;
61 QBarSet* barSet = m_series->barsetAt(set);
62
63 qreal barHeight = barSet->valueAt(category) * scale; //m_series->valueAt(set, category) * scale;
62 64 Bar* bar = m_bars.at(itemIndex);
63 bar->setPen(m_series->barsetAt(set)->pen());
64 bar->setBrush(m_series->barsetAt(set)->brush());
65 bar->setPen(barSet->pen());
66 bar->setBrush(barSet->brush());
65 67 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
66 68 layout.append(rect);
67 itemIndex++;
68 yPos -= barHeight;
69 }
70 xPos += xStep;
71 }
72 69
73 // Position floating values
74 itemIndex = 0;
75 xPos = (width/categotyCount);
76 for (int category=0; category < m_series->categoryCount(); category++) {
77 qreal yPos = height;
78 for (int set=0; set < m_series->barsetCount(); set++) {
79 qreal barHeight = m_series->valueAt(set, category) * scale;
80 70 BarValue* value = m_values.at(itemIndex);
81 71
82 QBarSet* barSet = m_series->barsetAt(set);
83
84 if (!qFuzzyIsNull(m_series->valueAt(set, category))) {
85 value->setText(QString::number(m_series->valueAt(set,category)));
72 if (!qFuzzyIsNull(barSet->valueAt(category))) {
73 value->setText(QString::number(barSet->valueAt(category)));
86 74 } else {
87 75 value->setText(QString(""));
88 76 }
89 77
90 value->setPos(xPos, yPos-barHeight / 2);
91 value->setPen(barSet->floatingValuePen());
78 value->setPos(xPos + (rect.width()/2 - value->boundingRect().width()/2)
79 ,yPos - barHeight/2 - value->boundingRect().height()/2);
80 value->setPen(barSet->valuePen());
92 81
93 82 itemIndex++;
94 83 yPos -= barHeight;
95 84 }
96 85 xPos += xStep;
97 86 }
87
98 88 return layout;
99 89 }
100 90
101 91 #include "moc_stackedbarchartitem_p.cpp"
102 92
103 93 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,392 +1,392
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 41 #include "axisitem_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 "chartthemedefault_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", 12)),
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 {
74 74 m_id = id;
75 75 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
76 76 }
77 77
78 78
79 79 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
80 80 {
81 81 switch(theme) {
82 82 case QChart::ChartThemeLight:
83 83 return new ChartThemeLight();
84 84 case QChart::ChartThemeBlueCerulean:
85 85 return new ChartThemeBlueCerulean();
86 86 case QChart::ChartThemeDark:
87 87 return new ChartThemeDark();
88 88 case QChart::ChartThemeBrownSand:
89 89 return new ChartThemeBrownSand();
90 90 case QChart::ChartThemeBlueNcs:
91 91 return new ChartThemeBlueNcs();
92 92 case QChart::ChartThemeHighContrast:
93 93 return new ChartThemeHighContrast();
94 94 case QChart::ChartThemeBlueIcy:
95 95 return new ChartThemeBlueIcy();
96 96 default:
97 97 return new ChartThemeDefault();
98 98 }
99 99 }
100 100
101 101 void ChartTheme::decorate(QChart* chart,bool force)
102 102 {
103 103 QBrush brush;
104 104
105 105 if(brush == chart->backgroundBrush() || force)
106 106 chart->setBackgroundBrush(m_chartBackgroundGradient);
107 107 chart->setTitleFont(m_masterFont);
108 108 chart->setTitleBrush(m_titleBrush);
109 109 }
110 110
111 111 void ChartTheme::decorate(QLegend* legend,bool force)
112 112 {
113 113 QPen pen;
114 114 QBrush brush;
115 115
116 116 if (pen == legend->pen() || force){
117 117 legend->setPen(Qt::NoPen);
118 118 }
119 119
120 120
121 121 if (brush == legend->brush() || force) {
122 122 legend->setBrush(m_chartBackgroundGradient);
123 123 }
124 124 }
125 125
126 126 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
127 127 {
128 128 QPen pen;
129 129 QBrush brush;
130 130
131 131 if (pen == series->pen() || force){
132 132 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
133 133 pen.setWidthF(2);
134 134 series->setPen(pen);
135 135 }
136 136
137 137 if (brush == series->brush() || force) {
138 138 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
139 139 series->setBrush(brush);
140 140 }
141 141 }
142 142
143 143
144 144 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
145 145 {
146 146 QPen pen;
147 147 if(pen == series->pen() || force ){
148 148 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
149 149 pen.setWidthF(2);
150 150 series->setPen(pen);
151 151 }
152 152 }
153 153
154 154 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
155 155 {
156 156 QBrush brush;
157 157 QPen pen;
158 158 QList<QBarSet*> sets = series->barSets();
159 159
160 160 qreal takeAtPos = 0.5;
161 161 qreal step = 0.2;
162 162 if (sets.count() > 1 ) {
163 163 step = 1.0 / (qreal) sets.count();
164 164 if (sets.count() % m_seriesGradients.count())
165 165 step *= m_seriesGradients.count();
166 166 else
167 167 step *= (m_seriesGradients.count() - 1);
168 168 }
169 169
170 170 for (int i(0); i < sets.count(); i++) {
171 171 int colorIndex = (index + i) % m_seriesGradients.count();
172 172 if (i > 0 && i % m_seriesGradients.count() == 0) {
173 173 // There is no dedicated base color for each sets, generate more colors
174 174 takeAtPos += step;
175 175 if (takeAtPos == 1.0)
176 176 takeAtPos += step;
177 177 takeAtPos -= (int) takeAtPos;
178 178 }
179 179 qDebug() << "pos:" << takeAtPos;
180 180 if (brush == sets.at(i)->brush() || 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 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
186 sets.at(i)->setValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
187 187 else
188 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
188 sets.at(i)->setValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
189 189
190 190 if (pen == sets.at(i)->pen() || 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,bool force)
198 198 {
199 199 QPen pen;
200 200 QBrush brush;
201 201
202 202 if (pen == series->pen() || 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() || 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, bool force)
215 215 {
216 216 for (int i(0); i < series->slices().count(); i++) {
217 217
218 218 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
219 219
220 220 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
221 221 qreal pos = (qreal) (i + 1) / (qreal) series->count();
222 222 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
223 223
224 224 QPieSlice::DataPtr s = series->slices().at(i)->data_ptr();
225 225 PieSliceData data = s->m_data;
226 226
227 227 if (data.m_slicePen.isThemed() || force) {
228 228 data.m_slicePen = penColor;
229 229 data.m_slicePen.setThemed(true);
230 230 }
231 231
232 232 if (data.m_sliceBrush.isThemed() || force) {
233 233 data.m_sliceBrush = brushColor;
234 234 data.m_sliceBrush.setThemed(true);
235 235 }
236 236
237 237 if (data.m_labelPen.isThemed() || force) {
238 238 data.m_labelPen = QPen(m_titleBrush.color());
239 239 data.m_labelPen.setThemed(true);
240 240 }
241 241
242 242 if (data.m_labelFont.isThemed() || force) {
243 243 data.m_labelFont = m_labelFont;
244 244 data.m_labelFont.setThemed(true);
245 245 }
246 246
247 247 if (s->m_data != data) {
248 248 s->m_data = data;
249 249 emit s->changed();
250 250 }
251 251 }
252 252 }
253 253
254 254 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
255 255 {
256 256 QPen pen;
257 257 if(pen == series->pen() || force){
258 258 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
259 259 pen.setWidthF(2);
260 260 series->setPen(pen);
261 261 }
262 262 }
263 263
264 264 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
265 265 {
266 266 QPen pen;
267 267 QBrush brush;
268 268 QFont font;
269 269
270 270 if (axis->isAxisVisible()) {
271 271
272 272 if(brush == axis->labelsBrush() || force){
273 273 axis->setLabelsBrush(m_axisLabelBrush);
274 274 }
275 275 if(pen == axis->labelsPen() || force){
276 276 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
277 277 }
278 278
279 279
280 280 if (axis->shadesVisible() || force) {
281 281
282 282 if(brush == axis->shadesBrush() || force){
283 283 axis->setShadesBrush(m_backgroundShadesBrush);
284 284 }
285 285
286 286 if(pen == axis->shadesPen() || force){
287 287 axis->setShadesPen(m_backgroundShadesPen);
288 288 }
289 289
290 290 if(force && (m_backgroundShades == BackgroundShadesBoth
291 291 || (m_backgroundShades == BackgroundShadesVertical && axisX)
292 292 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
293 293 axis->setShadesVisible(true);
294 294
295 295 }
296 296 }
297 297
298 298 if(pen == axis->axisPen() || force){
299 299 axis->setAxisPen(m_axisLinePen);
300 300 }
301 301
302 302 if(pen == axis->gridLinePen() || force){
303 303 axis->setGridLinePen(m_gridLinePen);
304 304 }
305 305
306 306 if(font == axis->labelsFont() || force){
307 307 axis->setLabelsFont(m_labelFont);
308 308 }
309 309 }
310 310 }
311 311
312 312 void ChartTheme::generateSeriesGradients()
313 313 {
314 314 // Generate gradients in HSV color space
315 315 foreach (QColor color, m_seriesColors) {
316 316 QLinearGradient g;
317 317 qreal h = color.hsvHueF();
318 318 qreal s = color.hsvSaturationF();
319 319
320 320 // TODO: tune the algorithm to give nice results with most base colors defined in
321 321 // most themes. The rest of the gradients we can define manually in theme specific
322 322 // implementation.
323 323 QColor start = color;
324 324 start.setHsvF(h, 0.0, 1.0);
325 325 g.setColorAt(0.0, start);
326 326
327 327 g.setColorAt(0.5, color);
328 328
329 329 QColor end = color;
330 330 end.setHsvF(h, s, 0.25);
331 331 g.setColorAt(1.0, end);
332 332
333 333 m_seriesGradients << g;
334 334 }
335 335 }
336 336
337 337
338 338 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
339 339 {
340 340 Q_ASSERT(pos >=0.0 && pos <= 1.0);
341 341 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
342 342 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
343 343 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
344 344 QColor c;
345 345 c.setRgbF(r, g, b);
346 346 return c;
347 347 }
348 348
349 349 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
350 350 {
351 351 Q_ASSERT(pos >=0 && pos <= 1.0);
352 352
353 353 // another possibility:
354 354 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
355 355
356 356 QGradientStops stops = gradient.stops();
357 357 int count = stops.count();
358 358
359 359 // find previous stop relative to position
360 360 QGradientStop prev = stops.first();
361 361 for (int i=0; i<count; i++) {
362 362 QGradientStop stop = stops.at(i);
363 363 if (pos > stop.first)
364 364 prev = stop;
365 365
366 366 // given position is actually a stop position?
367 367 if (pos == stop.first) {
368 368 //qDebug() << "stop color" << pos;
369 369 return stop.second;
370 370 }
371 371 }
372 372
373 373 // find next stop relative to position
374 374 QGradientStop next = stops.last();
375 375 for (int i=count-1; i>=0; i--) {
376 376 QGradientStop stop = stops.at(i);
377 377 if (pos < stop.first)
378 378 next = stop;
379 379 }
380 380
381 381 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
382 382
383 383 qreal range = next.first - prev.first;
384 384 qreal posDelta = pos - prev.first;
385 385 qreal relativePos = posDelta / range;
386 386
387 387 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
388 388
389 389 return colorAt(prev.second, next.second, relativePos);
390 390 }
391 391
392 392 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now