##// END OF EJS Templates
Fix bar series label visibility...
Titta Heikkala -
r2816:f5a7ef4ddac0
parent child
Show More
@@ -1,361 +1,361
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <private/abstractbarchartitem_p.h>
20 20 #include <private/bar_p.h>
21 21 #include <QtCharts/QBarSet>
22 22 #include <private/qbarset_p.h>
23 23 #include <QtCharts/QAbstractBarSeries>
24 24 #include <private/qabstractbarseries_p.h>
25 25 #include <QtCharts/QChart>
26 26 #include <private/chartpresenter_p.h>
27 27 #include <private/charttheme_p.h>
28 28 #include <private/baranimation_p.h>
29 29
30 30 #include <private/chartdataset_p.h>
31 31 #include <QtGui/QPainter>
32 32 #include <QtGui/QTextDocument>
33 33
34 34 QT_CHARTS_BEGIN_NAMESPACE
35 35
36 36 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
37 37 ChartItem(series->d_func(),item),
38 38 m_animation(0),
39 39 m_series(series)
40 40 {
41 41
42 42 setFlag(ItemClipsChildrenToShape);
43 43 setFlag(QGraphicsItem::ItemIsSelectable);
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 connect(series, SIGNAL(labelsAngleChanged(qreal)), this, SLOT(positionLabels()));
55 55 setZValue(ChartPresenter::BarSeriesZValue);
56 56 handleDataStructureChanged();
57 57 handleVisibleChanged();
58 58 handleUpdatedBars();
59 59 }
60 60
61 61 AbstractBarChartItem::~AbstractBarChartItem()
62 62 {
63 63 }
64 64
65 65 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
66 66 {
67 67 Q_UNUSED(painter);
68 68 Q_UNUSED(option);
69 69 Q_UNUSED(widget);
70 70 }
71 71
72 72 QRectF AbstractBarChartItem::boundingRect() const
73 73 {
74 74 return m_rect;
75 75 }
76 76
77 77 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
78 78 {
79 79 QSizeF size = geometry().size();
80 80 if (geometry().size().isValid()) {
81 81 if (m_animation) {
82 82 if (m_layout.count() == 0 || m_oldSize != size) {
83 83 initializeLayout();
84 84 m_oldSize = size;
85 85 }
86 86 m_animation->setup(m_layout, layout);
87 87 presenter()->startAnimation(m_animation);
88 88 } else {
89 89 setLayout(layout);
90 90 update();
91 91 }
92 92 }
93 93 }
94 94
95 95 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
96 96 {
97 97 m_animation = animation;
98 98 }
99 99
100 100 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
101 101 {
102 102 if (layout.count() != m_bars.count())
103 103 return;
104 104
105 105 m_layout = layout;
106 106
107 107 for (int i = 0; i < m_bars.count(); i++)
108 108 m_bars.at(i)->setRect(layout.at(i));
109 109
110 110 positionLabels();
111 111 }
112 112 //handlers
113 113
114 114 void AbstractBarChartItem::handleDomainUpdated()
115 115 {
116 116 m_domainMinX = domain()->minX();
117 117 m_domainMaxX = domain()->maxX();
118 118 m_domainMinY = domain()->minY();
119 119 m_domainMaxY = domain()->maxY();
120 120
121 121 QRectF rect(QPointF(0,0),domain()->size());
122 122
123 123 if(m_rect != rect){
124 124 prepareGeometryChange();
125 125 m_rect = rect;
126 126 }
127 127
128 128 handleLayoutChanged();
129 129 }
130 130
131 131 void AbstractBarChartItem::handleLayoutChanged()
132 132 {
133 133 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
134 134 return; // rect size zero.
135 135 QVector<QRectF> layout = calculateLayout();
136 136 applyLayout(layout);
137 137 handleUpdatedBars();
138 138 }
139 139
140 140 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
141 141 {
142 142 foreach (QGraphicsTextItem *label, m_labels)
143 143 label->setVisible(visible);
144 144 update();
145 145 }
146 146
147 147 void AbstractBarChartItem::handleDataStructureChanged()
148 148 {
149 149 foreach (QGraphicsItem *item, childItems())
150 150 delete item;
151 151
152 152 m_bars.clear();
153 153 m_labels.clear();
154 154 m_layout.clear();
155 155
156 156 // Create new graphic items for bars
157 157 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
158 158 for (int s = 0; s < m_series->count(); s++) {
159 159 QBarSet *set = m_series->d_func()->barsetAt(s);
160 160
161 161 // Bars
162 162 Bar *bar = new Bar(set, c, this);
163 163 m_bars.append(bar);
164 164 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
165 165 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), m_series, SIGNAL(hovered(bool, int, QBarSet*)));
166 166 connect(bar, SIGNAL(pressed(int, QBarSet*)), m_series, SIGNAL(pressed(int, QBarSet*)));
167 167 connect(bar, SIGNAL(released(int, QBarSet*)),
168 168 m_series, SIGNAL(released(int, QBarSet*)));
169 169 connect(bar, SIGNAL(doubleClicked(int, QBarSet*)),
170 170 m_series, SIGNAL(doubleClicked(int, QBarSet*)));
171 171 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
172 172 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
173 173 connect(bar, SIGNAL(pressed(int, QBarSet*)), set, SIGNAL(pressed(int)));
174 174 connect(bar, SIGNAL(released(int, QBarSet*)), set, SIGNAL(released(int)));
175 175 connect(bar, SIGNAL(doubleClicked(int, QBarSet*)), set, SIGNAL(doubleClicked(int)));
176 176 // m_layout.append(QRectF(0, 0, 1, 1));
177 177
178 178 // Labels
179 179 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
180 180 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
181 181 m_labels.append(newLabel);
182 182 }
183 183 }
184 184
185 185 if(themeManager()) themeManager()->updateSeries(m_series);
186 186 handleLayoutChanged();
187 187 handleVisibleChanged();
188 188 }
189 189
190 190 void AbstractBarChartItem::handleVisibleChanged()
191 191 {
192 192 bool visible = m_series->isVisible();
193 193 if (visible)
194 194 handleLabelsVisibleChanged(m_series->isLabelsVisible());
195 195 else
196 196 handleLabelsVisibleChanged(visible);
197 197
198 198 foreach (QGraphicsItem *bar, m_bars)
199 199 bar->setVisible(visible);
200 200 }
201 201
202 202 void AbstractBarChartItem::handleOpacityChanged()
203 203 {
204 204 foreach (QGraphicsItem *item, childItems())
205 205 item->setOpacity(m_series->opacity());
206 206 }
207 207
208 208 void AbstractBarChartItem::handleUpdatedBars()
209 209 {
210 210 if (!m_series->d_func()->blockBarUpdate()) {
211 211 // Handle changes in pen, brush, labels etc.
212 212 int categoryCount = m_series->d_func()->categoryCount();
213 213 int setCount = m_series->count();
214 214 int itemIndex(0);
215 215 static const QString valueTag(QLatin1String("@value"));
216 216
217 217 for (int category = 0; category < categoryCount; category++) {
218 218 for (int set = 0; set < setCount; set++) {
219 219 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
220 220 Bar *bar = m_bars.at(itemIndex);
221 221 bar->setPen(barSet->m_pen);
222 222 bar->setBrush(barSet->m_brush);
223 223 bar->update();
224 224
225 225 QGraphicsTextItem *label = m_labels.at(itemIndex);
226 226 QString valueLabel;
227 227 if (presenter()) { // At startup presenter is not yet set, yet somehow update comes
228 228 if (barSet->value(category) == 0) {
229 229 label->setVisible(false);
230 230 } else {
231 label->setVisible(true);
231 label->setVisible(m_series->isLabelsVisible());
232 232 if (m_series->labelsFormat().isEmpty()) {
233 233 valueLabel = presenter()->numberToString(barSet->value(category));
234 234 } else {
235 235 valueLabel = m_series->labelsFormat();
236 236 valueLabel.replace(valueTag,
237 237 presenter()->numberToString(barSet->value(category)));
238 238 }
239 239 }
240 240 }
241 241 label->setHtml(valueLabel);
242 242 label->setFont(barSet->m_labelFont);
243 243 label->setDefaultTextColor(barSet->m_labelBrush.color());
244 244 label->update();
245 245 itemIndex++;
246 246 }
247 247 }
248 248 }
249 249 }
250 250
251 251 void AbstractBarChartItem::handleLabelsPositionChanged()
252 252 {
253 253 positionLabels();
254 254 }
255 255
256 256 void AbstractBarChartItem::positionLabels()
257 257 {
258 258 // By default position labels on horizontal bar series
259 259 // Vertical bar series overload positionLabels() to call positionLabelsVertical()
260 260
261 261 QTransform transform;
262 262 const qreal angle = m_series->d_func()->labelsAngle();
263 263 if (angle != 0.0)
264 264 transform.rotate(angle);
265 265
266 266 for (int i = 0; i < m_layout.count(); i++) {
267 267 QGraphicsTextItem *label = m_labels.at(i);
268 268
269 269 QRectF labelRect = label->boundingRect();
270 270 QPointF center = labelRect.center();
271 271
272 272 qreal xPos = 0;
273 273 qreal yPos = m_layout.at(i).center().y() - center.y();
274 274
275 275 int xDiff = 0;
276 276 if (angle != 0.0) {
277 277 label->setTransformOriginPoint(center.x(), center.y());
278 278 label->setRotation(m_series->d_func()->labelsAngle());
279 279 qreal oldWidth = labelRect.width();
280 280 labelRect = transform.mapRect(labelRect);
281 281 xDiff = (labelRect.width() - oldWidth) / 2;
282 282 }
283 283
284 284 int offset = m_bars.at(i)->pen().width() / 2 + 2;
285 285
286 286 switch (m_series->labelsPosition()) {
287 287 case QAbstractBarSeries::LabelsCenter:
288 288 xPos = m_layout.at(i).center().x() - center.x();
289 289 break;
290 290 case QAbstractBarSeries::LabelsInsideEnd:
291 291 xPos = m_layout.at(i).right() - labelRect.width() - offset + xDiff;
292 292 break;
293 293 case QAbstractBarSeries::LabelsInsideBase:
294 294 xPos = m_layout.at(i).left() + offset + xDiff;
295 295 break;
296 296 case QAbstractBarSeries::LabelsOutsideEnd:
297 297 xPos = m_layout.at(i).right() + offset + xDiff;
298 298 break;
299 299 default:
300 300 // Invalid position, never comes here
301 301 break;
302 302 }
303 303
304 304 label->setPos(xPos, yPos);
305 305 label->setZValue(zValue() + 1);
306 306 }
307 307 }
308 308
309 309 void AbstractBarChartItem::positionLabelsVertical()
310 310 {
311 311 QTransform transform;
312 312 const qreal angle = m_series->d_func()->labelsAngle();
313 313 if (angle != 0.0)
314 314 transform.rotate(angle);
315 315
316 316 for (int i = 0; i < m_layout.count(); i++) {
317 317 QGraphicsTextItem *label = m_labels.at(i);
318 318
319 319 QRectF labelRect = label->boundingRect();
320 320 QPointF center = labelRect.center();
321 321
322 322 qreal xPos = m_layout.at(i).center().x() - center.x();
323 323 qreal yPos = 0;
324 324
325 325 int yDiff = 0;
326 326 if (angle != 0.0) {
327 327 label->setTransformOriginPoint(center.x(), center.y());
328 328 label->setRotation(m_series->d_func()->labelsAngle());
329 329 qreal oldHeight = labelRect.height();
330 330 labelRect = transform.mapRect(labelRect);
331 331 yDiff = (labelRect.height() - oldHeight) / 2;
332 332 }
333 333
334 334 int offset = m_bars.at(i)->pen().width() / 2 + 2;
335 335
336 336 switch (m_series->labelsPosition()) {
337 337 case QAbstractBarSeries::LabelsCenter:
338 338 yPos = m_layout.at(i).center().y() - center.y();
339 339 break;
340 340 case QAbstractBarSeries::LabelsInsideEnd:
341 341 yPos = m_layout.at(i).top() + offset + yDiff;
342 342 break;
343 343 case QAbstractBarSeries::LabelsInsideBase:
344 344 yPos = m_layout.at(i).bottom() - labelRect.height() - offset + yDiff;
345 345 break;
346 346 case QAbstractBarSeries::LabelsOutsideEnd:
347 347 yPos = m_layout.at(i).top() - labelRect.height() - offset + yDiff;
348 348 break;
349 349 default:
350 350 // Invalid position, never comes here
351 351 break;
352 352 }
353 353
354 354 label->setPos(xPos, yPos);
355 355 label->setZValue(zValue() + 1);
356 356 }
357 357 }
358 358
359 359 #include "moc_abstractbarchartitem_p.cpp"
360 360
361 361 QT_CHARTS_END_NAMESPACE
@@ -1,143 +1,143
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <private/horizontalpercentbarchartitem_p.h>
20 20 #include <private/qabstractbarseries_p.h>
21 21 #include <private/qbarset_p.h>
22 22 #include <private/bar_p.h>
23 23
24 24 QT_CHARTS_BEGIN_NAMESPACE
25 25
26 26 HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
27 27 : AbstractBarChartItem(series, item)
28 28 {
29 29 }
30 30
31 31 void HorizontalPercentBarChartItem::initializeLayout()
32 32 {
33 33 qreal categoryCount = m_series->d_func()->categoryCount();
34 34 qreal setCount = m_series->count();
35 35 qreal barWidth = m_series->d_func()->barWidth();
36 36
37 37 m_layout.clear();
38 38 for(int category = 0; category < categoryCount; category++) {
39 39 for (int set = 0; set < setCount; set++) {
40 40 QRectF rect;
41 41 QPointF topLeft;
42 42 QPointF bottomRight;
43 43 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
44 44 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
45 45 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
46 46 } else {
47 47 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
48 48 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
49 49 }
50 50
51 51 if (!m_validData)
52 52 return;
53 53
54 54 rect.setTopLeft(topLeft);
55 55 rect.setBottomRight(bottomRight);
56 56 m_layout.append(rect.normalized());
57 57 }
58 58 }
59 59 }
60 60
61 61 QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
62 62 {
63 63 QVector<QRectF> layout;
64 64
65 65 // Use temporary qreals for accuracy
66 66 qreal categoryCount = m_series->d_func()->categoryCount();
67 67 qreal setCount = m_series->count();
68 68 qreal barWidth = m_series->d_func()->barWidth();
69 69
70 70 for(int category = 0; category < categoryCount; category++) {
71 71 qreal sum = 0;
72 72 qreal categorySum = m_series->d_func()->categorySum(category);
73 73 for (int set = 0; set < setCount; set++) {
74 74 qreal value = m_series->barSets().at(set)->at(category);
75 75 QRectF rect;
76 76 qreal topX = 0;
77 77 if (sum > 0)
78 78 topX = 100 * sum / categorySum;
79 79 qreal bottomX = 0;
80 80 qreal newSum = value + sum;
81 81 if (newSum > 0)
82 82 bottomX = 100 * newSum / categorySum;
83 83 QPointF topLeft;
84 84 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
85 85 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : domain()->minX(), category - barWidth/2), m_validData);
86 86 else
87 87 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : 0, category - barWidth/2), m_validData);
88 88 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(bottomX, category + barWidth/2), m_validData);
89 89
90 90 rect.setTopLeft(topLeft);
91 91 rect.setBottomRight(bottomRight);
92 92 layout.append(rect.normalized());
93 93 sum = newSum;
94 94 }
95 95 }
96 96 return layout;
97 97 }
98 98
99 99 void HorizontalPercentBarChartItem::handleUpdatedBars()
100 100 {
101 101 // Handle changes in pen, brush, labels etc.
102 102 int categoryCount = m_series->d_func()->categoryCount();
103 103 int setCount = m_series->count();
104 104 int itemIndex(0);
105 105 static const QString valueTag(QLatin1String("@value"));
106 106
107 107 for (int category = 0; category < categoryCount; category++) {
108 108 for (int set = 0; set < setCount; set++) {
109 109 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
110 110 Bar *bar = m_bars.at(itemIndex);
111 111 bar->setPen(barSet->m_pen);
112 112 bar->setBrush(barSet->m_brush);
113 113 bar->update();
114 114
115 115 QGraphicsTextItem *label = m_labels.at(itemIndex);
116 116 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
117 117 QString vString(presenter()->numberToString(p, 'f', 0));
118 118 QString valueLabel;
119 119 if (p == 0) {
120 120 label->setVisible(false);
121 121 } else {
122 label->setVisible(true);
122 label->setVisible(m_series->isLabelsVisible());
123 123 if (m_series->labelsFormat().isEmpty()) {
124 124 vString.append(QStringLiteral("%"));
125 125 valueLabel = vString;
126 126 } else {
127 127 valueLabel = m_series->labelsFormat();
128 128 valueLabel.replace(valueTag, vString);
129 129 }
130 130 }
131 131 label->setHtml(valueLabel);
132 132 label->setFont(barSet->m_labelFont);
133 133 label->setDefaultTextColor(barSet->m_labelBrush.color());
134 134 label->update();
135 135 itemIndex++;
136 136 }
137 137 }
138 138 }
139 139
140 140 #include "moc_horizontalpercentbarchartitem_p.cpp"
141 141
142 142 QT_CHARTS_END_NAMESPACE
143 143
@@ -1,157 +1,157
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <private/percentbarchartitem_p.h>
20 20 #include <private/bar_p.h>
21 21 #include <private/qabstractbarseries_p.h>
22 22 #include <QtCharts/QBarSet>
23 23 #include <private/qbarset_p.h>
24 24
25 25 QT_CHARTS_BEGIN_NAMESPACE
26 26
27 27 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
28 28 AbstractBarChartItem(series, item)
29 29 {
30 30 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
31 31 this, SLOT(handleLabelsPositionChanged()));
32 32 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
33 33 }
34 34
35 35 void PercentBarChartItem::initializeLayout()
36 36 {
37 37 qreal categoryCount = m_series->d_func()->categoryCount();
38 38 qreal setCount = m_series->count();
39 39 qreal barWidth = m_series->d_func()->barWidth();
40 40
41 41 m_layout.clear();
42 42 for(int category = 0; category < categoryCount; category++) {
43 43 for (int set = 0; set < setCount; set++) {
44 44 QRectF rect;
45 45 QPointF topLeft;
46 46 QPointF bottomRight;
47 47
48 48 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
49 49 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
50 50 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
51 51 } else {
52 52 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
53 53 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
54 54 }
55 55
56 56 if (!m_validData)
57 57 return;
58 58
59 59 rect.setTopLeft(topLeft);
60 60 rect.setBottomRight(bottomRight);
61 61 m_layout.append(rect.normalized());
62 62 }
63 63 }
64 64 }
65 65
66 66 QVector<QRectF> PercentBarChartItem::calculateLayout()
67 67 {
68 68 QVector<QRectF> layout;
69 69
70 70 // Use temporary qreals for accuracy
71 71 qreal categoryCount = m_series->d_func()->categoryCount();
72 72 qreal setCount = m_series->count();
73 73 qreal barWidth = m_series->d_func()->barWidth();
74 74
75 75 for(int category = 0; category < categoryCount; category++) {
76 76 qreal sum = 0;
77 77 qreal categorySum = m_series->d_func()->categorySum(category);
78 78 for (int set = 0; set < setCount; set++) {
79 79 qreal value = m_series->barSets().at(set)->at(category);
80 80 QRectF rect;
81 81 qreal topY = 0;
82 82 qreal newSum = value + sum;
83 83 if (newSum > 0)
84 84 topY = 100 * newSum / categorySum;
85 85 qreal bottomY = 0;
86 86 if (sum > 0)
87 87 bottomY = 100 * sum / categorySum;
88 88 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
89 89 QPointF bottomRight;
90 90 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
91 91 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
92 92 else
93 93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
94 94
95 95 rect.setTopLeft(topLeft);
96 96 rect.setBottomRight(bottomRight);
97 97 layout.append(rect.normalized());
98 98 sum = newSum;
99 99 }
100 100 }
101 101 return layout;
102 102 }
103 103
104 104 void PercentBarChartItem::handleUpdatedBars()
105 105 {
106 106 // Handle changes in pen, brush, labels etc.
107 107 int categoryCount = m_series->d_func()->categoryCount();
108 108 int setCount = m_series->count();
109 109 int itemIndex(0);
110 110 static const QString valueTag(QLatin1String("@value"));
111 111
112 112 for (int category = 0; category < categoryCount; category++) {
113 113 for (int set = 0; set < setCount; set++) {
114 114 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
115 115 Bar *bar = m_bars.at(itemIndex);
116 116 bar->setPen(barSet->m_pen);
117 117 bar->setBrush(barSet->m_brush);
118 118 bar->update();
119 119
120 120 QGraphicsTextItem *label = m_labels.at(itemIndex);
121 121 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
122 122 QString vString(presenter()->numberToString(p, 'f', 0));
123 123 QString valueLabel;
124 124 if (p == 0) {
125 125 label->setVisible(false);
126 126 } else {
127 label->setVisible(true);
127 label->setVisible(m_series->isLabelsVisible());
128 128 if (m_series->labelsFormat().isEmpty()) {
129 129 vString.append(QStringLiteral("%"));
130 130 valueLabel = vString;
131 131 } else {
132 132 valueLabel = m_series->labelsFormat();
133 133 valueLabel.replace(valueTag, vString);
134 134 }
135 135 }
136 136 label->setHtml(valueLabel);
137 137 label->setFont(barSet->m_labelFont);
138 138 label->setDefaultTextColor(barSet->m_labelBrush.color());
139 139 label->update();
140 140 itemIndex++;
141 141 }
142 142 }
143 143 }
144 144
145 145 void PercentBarChartItem::handleLabelsPositionChanged()
146 146 {
147 147 positionLabels();
148 148 }
149 149
150 150 void PercentBarChartItem::positionLabels()
151 151 {
152 152 positionLabelsVertical();
153 153 }
154 154
155 155 #include "moc_percentbarchartitem_p.cpp"
156 156
157 157 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now