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