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