##// END OF EJS Templates
Fix bar value label position...
Titta Heikkala -
r2697:899dd6266dee
parent child
Show More
@@ -1,264 +1,265
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise 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 "abstractbarchartitem_p.h"
21 #include "abstractbarchartitem_p.h"
22 #include "bar_p.h"
22 #include "bar_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "qabstractbarseries.h"
25 #include "qabstractbarseries.h"
26 #include "qabstractbarseries_p.h"
26 #include "qabstractbarseries_p.h"
27 #include "qchart.h"
27 #include "qchart.h"
28 #include "chartpresenter_p.h"
28 #include "chartpresenter_p.h"
29 #include "charttheme_p.h"
29 #include "charttheme_p.h"
30 #include "baranimation_p.h"
30 #include "baranimation_p.h"
31 #include "chartdataset_p.h"
31 #include "chartdataset_p.h"
32 #include <QPainter>
32 #include <QPainter>
33 #include <QTextDocument>
33 #include <QTextDocument>
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
37 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
38 ChartItem(series->d_func(),item),
38 ChartItem(series->d_func(),item),
39 m_animation(0),
39 m_animation(0),
40 m_series(series)
40 m_series(series)
41 {
41 {
42
42
43 setFlag(ItemClipsChildrenToShape);
43 setFlag(ItemClipsChildrenToShape);
44 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
44 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
45 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleUpdatedBars()));
45 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleUpdatedBars()));
46 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
46 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
47 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
47 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
48 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
48 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
49 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
49 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
50 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(handleUpdatedBars()));
50 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(handleUpdatedBars()));
51 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
51 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
52 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
52 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
53 this, SLOT(handleLabelsPositionChanged()));
53 this, SLOT(handleLabelsPositionChanged()));
54 setZValue(ChartPresenter::BarSeriesZValue);
54 setZValue(ChartPresenter::BarSeriesZValue);
55 handleDataStructureChanged();
55 handleDataStructureChanged();
56 handleVisibleChanged();
56 handleVisibleChanged();
57 handleUpdatedBars();
57 handleUpdatedBars();
58 }
58 }
59
59
60 AbstractBarChartItem::~AbstractBarChartItem()
60 AbstractBarChartItem::~AbstractBarChartItem()
61 {
61 {
62 }
62 }
63
63
64 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
64 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
65 {
65 {
66 Q_UNUSED(painter);
66 Q_UNUSED(painter);
67 Q_UNUSED(option);
67 Q_UNUSED(option);
68 Q_UNUSED(widget);
68 Q_UNUSED(widget);
69 }
69 }
70
70
71 QRectF AbstractBarChartItem::boundingRect() const
71 QRectF AbstractBarChartItem::boundingRect() const
72 {
72 {
73 return m_rect;
73 return m_rect;
74 }
74 }
75
75
76 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
76 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
77 {
77 {
78 QSizeF size = geometry().size();
78 QSizeF size = geometry().size();
79 if (geometry().size().isValid()) {
79 if (geometry().size().isValid()) {
80 if (m_animation) {
80 if (m_animation) {
81 if (m_layout.count() == 0 || m_oldSize != size) {
81 if (m_layout.count() == 0 || m_oldSize != size) {
82 initializeLayout();
82 initializeLayout();
83 m_oldSize = size;
83 m_oldSize = size;
84 }
84 }
85 m_animation->setup(m_layout, layout);
85 m_animation->setup(m_layout, layout);
86 presenter()->startAnimation(m_animation);
86 presenter()->startAnimation(m_animation);
87 } else {
87 } else {
88 setLayout(layout);
88 setLayout(layout);
89 update();
89 update();
90 }
90 }
91 }
91 }
92 }
92 }
93
93
94 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
94 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
95 {
95 {
96 m_animation = animation;
96 m_animation = animation;
97 }
97 }
98
98
99 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
99 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
100 {
100 {
101 if (layout.count() != m_bars.count())
101 if (layout.count() != m_bars.count())
102 return;
102 return;
103
103
104 m_layout = layout;
104 m_layout = layout;
105
105
106 for (int i = 0; i < m_bars.count(); i++)
106 for (int i = 0; i < m_bars.count(); i++)
107 m_bars.at(i)->setRect(layout.at(i));
107 m_bars.at(i)->setRect(layout.at(i));
108
108
109 positionLabels();
109 positionLabels();
110 }
110 }
111 //handlers
111 //handlers
112
112
113 void AbstractBarChartItem::handleDomainUpdated()
113 void AbstractBarChartItem::handleDomainUpdated()
114 {
114 {
115 m_domainMinX = domain()->minX();
115 m_domainMinX = domain()->minX();
116 m_domainMaxX = domain()->maxX();
116 m_domainMaxX = domain()->maxX();
117 m_domainMinY = domain()->minY();
117 m_domainMinY = domain()->minY();
118 m_domainMaxY = domain()->maxY();
118 m_domainMaxY = domain()->maxY();
119
119
120 QRectF rect(QPointF(0,0),domain()->size());
120 QRectF rect(QPointF(0,0),domain()->size());
121
121
122 if(m_rect != rect){
122 if(m_rect != rect){
123 prepareGeometryChange();
123 prepareGeometryChange();
124 m_rect = rect;
124 m_rect = rect;
125 }
125 }
126
126
127 handleLayoutChanged();
127 handleLayoutChanged();
128 }
128 }
129
129
130 void AbstractBarChartItem::handleLayoutChanged()
130 void AbstractBarChartItem::handleLayoutChanged()
131 {
131 {
132 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
132 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
133 return; // rect size zero.
133 return; // rect size zero.
134 QVector<QRectF> layout = calculateLayout();
134 QVector<QRectF> layout = calculateLayout();
135 applyLayout(layout);
135 applyLayout(layout);
136 handleUpdatedBars();
136 handleUpdatedBars();
137 }
137 }
138
138
139 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
139 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
140 {
140 {
141 foreach (QGraphicsTextItem *label, m_labels)
141 foreach (QGraphicsTextItem *label, m_labels)
142 label->setVisible(visible);
142 label->setVisible(visible);
143 update();
143 update();
144 }
144 }
145
145
146 void AbstractBarChartItem::handleDataStructureChanged()
146 void AbstractBarChartItem::handleDataStructureChanged()
147 {
147 {
148 foreach (QGraphicsItem *item, childItems())
148 foreach (QGraphicsItem *item, childItems())
149 delete item;
149 delete item;
150
150
151 m_bars.clear();
151 m_bars.clear();
152 m_labels.clear();
152 m_labels.clear();
153 m_layout.clear();
153 m_layout.clear();
154
154
155 // Create new graphic items for bars
155 // Create new graphic items for bars
156 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
156 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
157 for (int s = 0; s < m_series->count(); s++) {
157 for (int s = 0; s < m_series->count(); s++) {
158 QBarSet *set = m_series->d_func()->barsetAt(s);
158 QBarSet *set = m_series->d_func()->barsetAt(s);
159
159
160 // Bars
160 // Bars
161 Bar *bar = new Bar(set, c, this);
161 Bar *bar = new Bar(set, c, this);
162 m_bars.append(bar);
162 m_bars.append(bar);
163 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
163 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
164 connect(bar, SIGNAL(hovered(bool,QBarSet*)), m_series, SIGNAL(hovered(bool,QBarSet*)));
164 connect(bar, SIGNAL(hovered(bool,QBarSet*)), m_series, SIGNAL(hovered(bool,QBarSet*)));
165 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), m_series, SIGNAL(hovered(bool, int, QBarSet*)));
165 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), m_series, SIGNAL(hovered(bool, int, QBarSet*)));
166 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
166 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
167 connect(bar, SIGNAL(hovered(bool,QBarSet*)), set, SIGNAL(hovered(bool)));
167 connect(bar, SIGNAL(hovered(bool,QBarSet*)), set, SIGNAL(hovered(bool)));
168 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
168 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
169 // m_layout.append(QRectF(0, 0, 1, 1));
169 // m_layout.append(QRectF(0, 0, 1, 1));
170
170
171 // Labels
171 // Labels
172 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
172 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
173 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
173 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
174 m_labels.append(newLabel);
174 m_labels.append(newLabel);
175 }
175 }
176 }
176 }
177
177
178 if(themeManager()) themeManager()->updateSeries(m_series);
178 if(themeManager()) themeManager()->updateSeries(m_series);
179 handleLayoutChanged();
179 handleLayoutChanged();
180 handleVisibleChanged();
180 handleVisibleChanged();
181 }
181 }
182
182
183 void AbstractBarChartItem::handleVisibleChanged()
183 void AbstractBarChartItem::handleVisibleChanged()
184 {
184 {
185 bool visible = m_series->isVisible();
185 bool visible = m_series->isVisible();
186 if (visible)
186 if (visible)
187 handleLabelsVisibleChanged(m_series->isLabelsVisible());
187 handleLabelsVisibleChanged(m_series->isLabelsVisible());
188 else
188 else
189 handleLabelsVisibleChanged(visible);
189 handleLabelsVisibleChanged(visible);
190
190
191 foreach (QGraphicsItem *bar, m_bars)
191 foreach (QGraphicsItem *bar, m_bars)
192 bar->setVisible(visible);
192 bar->setVisible(visible);
193 }
193 }
194
194
195 void AbstractBarChartItem::handleOpacityChanged()
195 void AbstractBarChartItem::handleOpacityChanged()
196 {
196 {
197 foreach (QGraphicsItem *item, childItems())
197 foreach (QGraphicsItem *item, childItems())
198 item->setOpacity(m_series->opacity());
198 item->setOpacity(m_series->opacity());
199 }
199 }
200
200
201 void AbstractBarChartItem::handleUpdatedBars()
201 void AbstractBarChartItem::handleUpdatedBars()
202 {
202 {
203 if (!m_series->d_func()->blockBarUpdate()) {
203 if (!m_series->d_func()->blockBarUpdate()) {
204 // Handle changes in pen, brush, labels etc.
204 // Handle changes in pen, brush, labels etc.
205 int categoryCount = m_series->d_func()->categoryCount();
205 int categoryCount = m_series->d_func()->categoryCount();
206 int setCount = m_series->count();
206 int setCount = m_series->count();
207 int itemIndex(0);
207 int itemIndex(0);
208 static const QString valueTag(QLatin1String("@value"));
208 static const QString valueTag(QLatin1String("@value"));
209
209
210 for (int category = 0; category < categoryCount; category++) {
210 for (int category = 0; category < categoryCount; category++) {
211 for (int set = 0; set < setCount; set++) {
211 for (int set = 0; set < setCount; set++) {
212 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
212 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
213 Bar *bar = m_bars.at(itemIndex);
213 Bar *bar = m_bars.at(itemIndex);
214 bar->setPen(barSet->m_pen);
214 bar->setPen(barSet->m_pen);
215 bar->setBrush(barSet->m_brush);
215 bar->setBrush(barSet->m_brush);
216 bar->update();
216 bar->update();
217
217
218 QGraphicsTextItem *label = m_labels.at(itemIndex);
218 QGraphicsTextItem *label = m_labels.at(itemIndex);
219 QString valueLabel;
219 QString valueLabel;
220 if (m_series->labelsFormat().isEmpty()) {
220 if (m_series->labelsFormat().isEmpty()) {
221 valueLabel = QString("%1").arg(barSet->value(category));
221 valueLabel = QString("%1").arg(barSet->value(category));
222 } else {
222 } else {
223 valueLabel = m_series->labelsFormat();
223 valueLabel = m_series->labelsFormat();
224 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
224 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
225 }
225 }
226 label->setHtml(valueLabel);
226 label->setHtml(valueLabel);
227 label->setFont(barSet->m_labelFont);
227 label->setFont(barSet->m_labelFont);
228 label->setDefaultTextColor(barSet->m_labelBrush.color());
228 label->setDefaultTextColor(barSet->m_labelBrush.color());
229 label->update();
229 label->update();
230 itemIndex++;
230 itemIndex++;
231 }
231 }
232 }
232 }
233 }
233 }
234 }
234 }
235
235
236 void AbstractBarChartItem::handleLabelsPositionChanged()
236 void AbstractBarChartItem::handleLabelsPositionChanged()
237 {
237 {
238 positionLabels();
238 positionLabels();
239 }
239 }
240
240
241 void AbstractBarChartItem::positionLabels()
241 void AbstractBarChartItem::positionLabels()
242 {
242 {
243 for (int i = 0; i < m_layout.count(); i++) {
243 for (int i = 0; i < m_layout.count(); i++) {
244 QGraphicsTextItem *label = m_labels.at(i);
244 QGraphicsTextItem *label = m_labels.at(i);
245 qreal xPos = 0;
245 qreal xPos = 0;
246 qreal yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
246 qreal yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
247
247
248 int offset = m_bars.at(i)->pen().width() / 2 + 2;
248 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
249 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
249 xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
250 xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
250 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
251 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
251 xPos = m_layout.at(i).right() - label->boundingRect().width();
252 xPos = m_layout.at(i).right() - label->boundingRect().width() - offset;
252 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
253 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
253 xPos = m_layout.at(i).left();
254 xPos = m_layout.at(i).left() + offset;
254 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
255 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
255 xPos = m_layout.at(i).right();
256 xPos = m_layout.at(i).right() + offset;
256
257
257 label->setPos(xPos, yPos);
258 label->setPos(xPos, yPos);
258 label->setZValue(zValue() + 1);
259 label->setZValue(zValue() + 1);
259 }
260 }
260 }
261 }
261
262
262 #include "moc_abstractbarchartitem_p.cpp"
263 #include "moc_abstractbarchartitem_p.cpp"
263
264
264 QTCOMMERCIALCHART_END_NAMESPACE
265 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,124 +1,125
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise 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 "qabstractbarseries_p.h"
23 #include "qabstractbarseries_p.h"
24 #include "qbarset.h"
24 #include "qbarset.h"
25 #include "qbarset_p.h"
25 #include "qbarset_p.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 BarChartItem::BarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
29 BarChartItem::BarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 AbstractBarChartItem(series, item)
30 AbstractBarChartItem(series, item)
31 {
31 {
32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
33 this, SLOT(handleLabelsPositionChanged()));
33 this, SLOT(handleLabelsPositionChanged()));
34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
35 }
35 }
36
36
37 void BarChartItem::initializeLayout()
37 void BarChartItem::initializeLayout()
38 {
38 {
39 qreal categoryCount = m_series->d_func()->categoryCount();
39 qreal categoryCount = m_series->d_func()->categoryCount();
40 qreal setCount = m_series->count();
40 qreal setCount = m_series->count();
41 qreal barWidth = m_series->d_func()->barWidth();
41 qreal barWidth = m_series->d_func()->barWidth();
42
42
43 m_layout.clear();
43 m_layout.clear();
44 for(int category = 0; category < categoryCount; category++) {
44 for(int category = 0; category < categoryCount; category++) {
45 for (int set = 0; set < setCount; set++) {
45 for (int set = 0; set < setCount; set++) {
46 QRectF rect;
46 QRectF rect;
47 QPointF topLeft;
47 QPointF topLeft;
48 QPointF bottomRight;
48 QPointF bottomRight;
49
49
50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, domain()->minY()), m_validData);
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, domain()->minY()), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, domain()->minY()), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, domain()->minY()), m_validData);
53 } else {
53 } else {
54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, 0), m_validData);
54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, 0), m_validData);
55 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, 0), m_validData);
55 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, 0), m_validData);
56 }
56 }
57
57
58 if (!m_validData)
58 if (!m_validData)
59 return;
59 return;
60 rect.setTopLeft(topLeft);
60 rect.setTopLeft(topLeft);
61 rect.setBottomRight(bottomRight);
61 rect.setBottomRight(bottomRight);
62 m_layout.append(rect.normalized());
62 m_layout.append(rect.normalized());
63 }
63 }
64 }
64 }
65 }
65 }
66
66
67 QVector<QRectF> BarChartItem::calculateLayout()
67 QVector<QRectF> BarChartItem::calculateLayout()
68 {
68 {
69 QVector<QRectF> layout;
69 QVector<QRectF> layout;
70
70
71 // Use temporary qreals for accuracy
71 // Use temporary qreals for accuracy
72 qreal categoryCount = m_series->d_func()->categoryCount();
72 qreal categoryCount = m_series->d_func()->categoryCount();
73 qreal setCount = m_series->count();
73 qreal setCount = m_series->count();
74 qreal barWidth = m_series->d_func()->barWidth();
74 qreal barWidth = m_series->d_func()->barWidth();
75
75
76 for(int category = 0; category < categoryCount; category++) {
76 for(int category = 0; category < categoryCount; category++) {
77 for (int set = 0; set < setCount; set++) {
77 for (int set = 0; set < setCount; set++) {
78 qreal value = m_series->barSets().at(set)->at(category);
78 qreal value = m_series->barSets().at(set)->at(category);
79 QRectF rect;
79 QRectF rect;
80 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set)/(setCount) * barWidth, value), m_validData);
80 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set)/(setCount) * barWidth, value), m_validData);
81 QPointF bottomRight;
81 QPointF bottomRight;
82 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
82 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
83 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, domain()->minY()), m_validData);
83 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, domain()->minY()), m_validData);
84 else
84 else
85 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, 0), m_validData);
85 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, 0), m_validData);
86
86
87 rect.setTopLeft(topLeft);
87 rect.setTopLeft(topLeft);
88 rect.setBottomRight(bottomRight);
88 rect.setBottomRight(bottomRight);
89 layout.append(rect.normalized());
89 layout.append(rect.normalized());
90 }
90 }
91 }
91 }
92
92
93 return layout;
93 return layout;
94 }
94 }
95
95
96 void BarChartItem::handleLabelsPositionChanged()
96 void BarChartItem::handleLabelsPositionChanged()
97 {
97 {
98 positionLabels();
98 positionLabels();
99 }
99 }
100
100
101 void BarChartItem::positionLabels()
101 void BarChartItem::positionLabels()
102 {
102 {
103 for (int i = 0; i < m_layout.count(); i++) {
103 for (int i = 0; i < m_layout.count(); i++) {
104 QGraphicsTextItem *label = m_labels.at(i);
104 QGraphicsTextItem *label = m_labels.at(i);
105 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
105 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
106 qreal yPos = 0;
106 qreal yPos = 0;
107
107
108 int offset = m_bars.at(i)->pen().width() / 2 + 2;
108 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
109 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
109 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
110 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
110 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
111 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
111 yPos = m_layout.at(i).top();
112 yPos = m_layout.at(i).top() - offset;
112 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
113 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
113 yPos = m_layout.at(i).bottom() - label->boundingRect().height();
114 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
114 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
115 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
115 yPos = m_layout.at(i).top() - label->boundingRect().height();
116 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
116
117
117 label->setPos(xPos, yPos);
118 label->setPos(xPos, yPos);
118 label->setZValue(zValue() + 1);
119 label->setZValue(zValue() + 1);
119 }
120 }
120 }
121 }
121
122
122 #include "moc_barchartitem_p.cpp"
123 #include "moc_barchartitem_p.cpp"
123
124
124 QTCOMMERCIALCHART_END_NAMESPACE
125 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,171 +1,172
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise 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 "qabstractbarseries_p.h"
23 #include "qabstractbarseries_p.h"
24 #include "qbarset.h"
24 #include "qbarset.h"
25 #include "qbarset_p.h"
25 #include "qbarset_p.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
29 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 AbstractBarChartItem(series, item)
30 AbstractBarChartItem(series, item)
31 {
31 {
32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
33 this, SLOT(handleLabelsPositionChanged()));
33 this, SLOT(handleLabelsPositionChanged()));
34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
35 }
35 }
36
36
37 void PercentBarChartItem::initializeLayout()
37 void PercentBarChartItem::initializeLayout()
38 {
38 {
39 qreal categoryCount = m_series->d_func()->categoryCount();
39 qreal categoryCount = m_series->d_func()->categoryCount();
40 qreal setCount = m_series->count();
40 qreal setCount = m_series->count();
41 qreal barWidth = m_series->d_func()->barWidth();
41 qreal barWidth = m_series->d_func()->barWidth();
42
42
43 m_layout.clear();
43 m_layout.clear();
44 for(int category = 0; category < categoryCount; category++) {
44 for(int category = 0; category < categoryCount; category++) {
45 for (int set = 0; set < setCount; set++) {
45 for (int set = 0; set < setCount; set++) {
46 QRectF rect;
46 QRectF rect;
47 QPointF topLeft;
47 QPointF topLeft;
48 QPointF bottomRight;
48 QPointF bottomRight;
49
49
50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
53 } else {
53 } else {
54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
55 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
55 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
56 }
56 }
57
57
58 if (!m_validData)
58 if (!m_validData)
59 return;
59 return;
60
60
61 rect.setTopLeft(topLeft);
61 rect.setTopLeft(topLeft);
62 rect.setBottomRight(bottomRight);
62 rect.setBottomRight(bottomRight);
63 m_layout.append(rect.normalized());
63 m_layout.append(rect.normalized());
64 }
64 }
65 }
65 }
66 }
66 }
67
67
68 QVector<QRectF> PercentBarChartItem::calculateLayout()
68 QVector<QRectF> PercentBarChartItem::calculateLayout()
69 {
69 {
70 QVector<QRectF> layout;
70 QVector<QRectF> layout;
71
71
72 // Use temporary qreals for accuracy
72 // Use temporary qreals for accuracy
73 qreal categoryCount = m_series->d_func()->categoryCount();
73 qreal categoryCount = m_series->d_func()->categoryCount();
74 qreal setCount = m_series->count();
74 qreal setCount = m_series->count();
75 qreal barWidth = m_series->d_func()->barWidth();
75 qreal barWidth = m_series->d_func()->barWidth();
76
76
77 for(int category = 0; category < categoryCount; category++) {
77 for(int category = 0; category < categoryCount; category++) {
78 qreal sum = 0;
78 qreal sum = 0;
79 qreal categorySum = m_series->d_func()->categorySum(category);
79 qreal categorySum = m_series->d_func()->categorySum(category);
80 for (int set = 0; set < setCount; set++) {
80 for (int set = 0; set < setCount; set++) {
81 qreal value = m_series->barSets().at(set)->at(category);
81 qreal value = m_series->barSets().at(set)->at(category);
82 QRectF rect;
82 QRectF rect;
83 qreal topY = 0;
83 qreal topY = 0;
84 qreal newSum = value + sum;
84 qreal newSum = value + sum;
85 if (newSum > 0)
85 if (newSum > 0)
86 topY = 100 * newSum / categorySum;
86 topY = 100 * newSum / categorySum;
87 qreal bottomY = 0;
87 qreal bottomY = 0;
88 if (sum > 0)
88 if (sum > 0)
89 bottomY = 100 * sum / categorySum;
89 bottomY = 100 * sum / categorySum;
90 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
90 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
91 QPointF bottomRight;
91 QPointF bottomRight;
92 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
92 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
94 else
94 else
95 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
95 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
96
96
97 rect.setTopLeft(topLeft);
97 rect.setTopLeft(topLeft);
98 rect.setBottomRight(bottomRight);
98 rect.setBottomRight(bottomRight);
99 layout.append(rect.normalized());
99 layout.append(rect.normalized());
100 sum = newSum;
100 sum = newSum;
101 }
101 }
102 }
102 }
103 return layout;
103 return layout;
104 }
104 }
105
105
106 void PercentBarChartItem::handleUpdatedBars()
106 void PercentBarChartItem::handleUpdatedBars()
107 {
107 {
108 // Handle changes in pen, brush, labels etc.
108 // Handle changes in pen, brush, labels etc.
109 int categoryCount = m_series->d_func()->categoryCount();
109 int categoryCount = m_series->d_func()->categoryCount();
110 int setCount = m_series->count();
110 int setCount = m_series->count();
111 int itemIndex(0);
111 int itemIndex(0);
112 static const QString valueTag(QLatin1String("@value"));
112 static const QString valueTag(QLatin1String("@value"));
113
113
114 for (int category = 0; category < categoryCount; category++) {
114 for (int category = 0; category < categoryCount; category++) {
115 for (int set = 0; set < setCount; set++) {
115 for (int set = 0; set < setCount; set++) {
116 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
116 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
117 Bar *bar = m_bars.at(itemIndex);
117 Bar *bar = m_bars.at(itemIndex);
118 bar->setPen(barSet->m_pen);
118 bar->setPen(barSet->m_pen);
119 bar->setBrush(barSet->m_brush);
119 bar->setBrush(barSet->m_brush);
120 bar->update();
120 bar->update();
121
121
122 QGraphicsTextItem *label = m_labels.at(itemIndex);
122 QGraphicsTextItem *label = m_labels.at(itemIndex);
123 int p = m_series->d_func()->percentageAt(set, category) * 100;
123 int p = m_series->d_func()->percentageAt(set, category) * 100;
124 QString vString(QString::number(p));
124 QString vString(QString::number(p));
125 vString.truncate(3);
125 vString.truncate(3);
126 vString.append("%");
126 vString.append("%");
127 QString valueLabel;
127 QString valueLabel;
128 if (m_series->labelsFormat().isEmpty()) {
128 if (m_series->labelsFormat().isEmpty()) {
129 valueLabel = vString;
129 valueLabel = vString;
130 } else {
130 } else {
131 valueLabel = m_series->labelsFormat();
131 valueLabel = m_series->labelsFormat();
132 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
132 valueLabel.replace(valueTag, QString::number(barSet->value(category)));
133 }
133 }
134 label->setHtml(valueLabel);
134 label->setHtml(valueLabel);
135 label->setFont(barSet->m_labelFont);
135 label->setFont(barSet->m_labelFont);
136 label->setDefaultTextColor(barSet->m_labelBrush.color());
136 label->setDefaultTextColor(barSet->m_labelBrush.color());
137 label->update();
137 label->update();
138 itemIndex++;
138 itemIndex++;
139 }
139 }
140 }
140 }
141 }
141 }
142
142
143 void PercentBarChartItem::handleLabelsPositionChanged()
143 void PercentBarChartItem::handleLabelsPositionChanged()
144 {
144 {
145 positionLabels();
145 positionLabels();
146 }
146 }
147
147
148 void PercentBarChartItem::positionLabels()
148 void PercentBarChartItem::positionLabels()
149 {
149 {
150 for (int i = 0; i < m_layout.count(); i++) {
150 for (int i = 0; i < m_layout.count(); i++) {
151 QGraphicsTextItem *label = m_labels.at(i);
151 QGraphicsTextItem *label = m_labels.at(i);
152 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
152 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
153 qreal yPos = 0;
153 qreal yPos = 0;
154
154
155 int offset = m_bars.at(i)->pen().width() / 2 + 2;
155 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
156 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
156 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
157 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
157 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
158 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
158 yPos = m_layout.at(i).top();
159 yPos = m_layout.at(i).top() - offset;
159 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
160 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
160 yPos = m_layout.at(i).bottom() - label->boundingRect().height();
161 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
161 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
162 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
162 yPos = m_layout.at(i).top() - label->boundingRect().height();
163 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
163
164
164 label->setPos(xPos, yPos);
165 label->setPos(xPos, yPos);
165 label->setZValue(zValue() + 1);
166 label->setZValue(zValue() + 1);
166 }
167 }
167 }
168 }
168
169
169 #include "moc_percentbarchartitem_p.cpp"
170 #include "moc_percentbarchartitem_p.cpp"
170
171
171 QTCOMMERCIALCHART_END_NAMESPACE
172 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,136 +1,137
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 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 Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise 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 "qbarset_p.h"
23 #include "qbarset_p.h"
24 #include "qabstractbarseries_p.h"
24 #include "qabstractbarseries_p.h"
25 #include "qbarset.h"
25 #include "qbarset.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
29 StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 AbstractBarChartItem(series, item)
30 AbstractBarChartItem(series, item)
31 {
31 {
32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
32 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
33 this, SLOT(handleLabelsPositionChanged()));
33 this, SLOT(handleLabelsPositionChanged()));
34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
34 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
35 }
35 }
36
36
37 void StackedBarChartItem::initializeLayout()
37 void StackedBarChartItem::initializeLayout()
38 {
38 {
39 qreal categoryCount = m_series->d_func()->categoryCount();
39 qreal categoryCount = m_series->d_func()->categoryCount();
40 qreal setCount = m_series->count();
40 qreal setCount = m_series->count();
41 qreal barWidth = m_series->d_func()->barWidth();
41 qreal barWidth = m_series->d_func()->barWidth();
42
42
43 m_layout.clear();
43 m_layout.clear();
44 for(int category = 0; category < categoryCount; category++) {
44 for(int category = 0; category < categoryCount; category++) {
45 for (int set = 0; set < setCount; set++) {
45 for (int set = 0; set < setCount; set++) {
46 QRectF rect;
46 QRectF rect;
47 QPointF topLeft;
47 QPointF topLeft;
48 QPointF bottomRight;
48 QPointF bottomRight;
49
49
50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
50 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
53 } else {
53 } else {
54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
54 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
55 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
55 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
56 }
56 }
57
57
58 if (!m_validData)
58 if (!m_validData)
59 return;
59 return;
60
60
61 rect.setTopLeft(topLeft);
61 rect.setTopLeft(topLeft);
62 rect.setBottomRight(bottomRight);
62 rect.setBottomRight(bottomRight);
63 m_layout.append(rect.normalized());
63 m_layout.append(rect.normalized());
64 }
64 }
65 }
65 }
66 }
66 }
67
67
68 QVector<QRectF> StackedBarChartItem::calculateLayout()
68 QVector<QRectF> StackedBarChartItem::calculateLayout()
69 {
69 {
70 QVector<QRectF> layout;
70 QVector<QRectF> layout;
71 // Use temporary qreals for accuracy
71 // Use temporary qreals for accuracy
72 qreal categoryCount = m_series->d_func()->categoryCount();
72 qreal categoryCount = m_series->d_func()->categoryCount();
73 qreal setCount = m_series->count();
73 qreal setCount = m_series->count();
74 qreal barWidth = m_series->d_func()->barWidth();
74 qreal barWidth = m_series->d_func()->barWidth();
75
75
76 for(int category = 0; category < categoryCount; category++) {
76 for(int category = 0; category < categoryCount; category++) {
77 qreal positiveSum = 0;
77 qreal positiveSum = 0;
78 qreal negativeSum = 0;
78 qreal negativeSum = 0;
79 for (int set = 0; set < setCount; set++) {
79 for (int set = 0; set < setCount; set++) {
80 qreal value = m_series->barSets().at(set)->at(category);
80 qreal value = m_series->barSets().at(set)->at(category);
81 QRectF rect;
81 QRectF rect;
82 QPointF topLeft;
82 QPointF topLeft;
83 QPointF bottomRight;
83 QPointF bottomRight;
84 if (value < 0) {
84 if (value < 0) {
85 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + negativeSum), m_validData);
85 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + negativeSum), m_validData);
86 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
86 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
87 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : domain()->minY()), m_validData);
87 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : domain()->minY()), m_validData);
88 else
88 else
89 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : 0), m_validData);
89 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : 0), m_validData);
90 negativeSum += value;
90 negativeSum += value;
91 } else {
91 } else {
92 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + positiveSum), m_validData);
92 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + positiveSum), m_validData);
93 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
93 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
94 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : domain()->minY()), m_validData);
94 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : domain()->minY()), m_validData);
95 else
95 else
96 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : 0), m_validData);
96 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : 0), m_validData);
97 positiveSum += value;
97 positiveSum += value;
98 }
98 }
99
99
100 rect.setTopLeft(topLeft);
100 rect.setTopLeft(topLeft);
101 rect.setBottomRight(bottomRight);
101 rect.setBottomRight(bottomRight);
102 layout.append(rect.normalized());
102 layout.append(rect.normalized());
103 }
103 }
104 }
104 }
105 return layout;
105 return layout;
106 }
106 }
107
107
108 void StackedBarChartItem::handleLabelsPositionChanged()
108 void StackedBarChartItem::handleLabelsPositionChanged()
109 {
109 {
110 positionLabels();
110 positionLabels();
111 }
111 }
112
112
113 void StackedBarChartItem::positionLabels()
113 void StackedBarChartItem::positionLabels()
114 {
114 {
115 for (int i = 0; i < m_layout.count(); i++) {
115 for (int i = 0; i < m_layout.count(); i++) {
116 QGraphicsTextItem *label = m_labels.at(i);
116 QGraphicsTextItem *label = m_labels.at(i);
117 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
117 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
118 qreal yPos = 0;
118 qreal yPos = 0;
119
119
120 int offset = m_bars.at(i)->pen().width() / 2 + 2;
120 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
121 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
121 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
122 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
122 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
123 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
123 yPos = m_layout.at(i).top();
124 yPos = m_layout.at(i).top() - offset;
124 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
125 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
125 yPos = m_layout.at(i).bottom() - label->boundingRect().height();
126 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
126 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
127 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
127 yPos = m_layout.at(i).top() - label->boundingRect().height();
128 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
128
129
129 label->setPos(xPos, yPos);
130 label->setPos(xPos, yPos);
130 label->setZValue(zValue() + 1);
131 label->setZValue(zValue() + 1);
131 }
132 }
132 }
133 }
133
134
134 #include "moc_stackedbarchartitem_p.cpp"
135 #include "moc_stackedbarchartitem_p.cpp"
135
136
136 QTCOMMERCIALCHART_END_NAMESPACE
137 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now