##// END OF EJS Templates
Fixed bar label visibility...
Titta Heikkala -
r2814:79dc9c599f41
parent child
Show More
@@ -1,356 +1,361
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd
3 ** Copyright (C) 2015 The Qt Company Ltd
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 **
6 **
7 ** This file is part of the Qt Charts module.
7 ** This file is part of the Qt Charts module.
8 **
8 **
9 ** Licensees holding valid commercial license for Qt may use this file in
9 ** Licensees holding valid commercial license for Qt may use this file in
10 ** accordance with the Qt License Agreement provided with the Software
10 ** accordance with the Qt License Agreement provided with the Software
11 ** or, alternatively, in accordance with the terms contained in a written
11 ** or, alternatively, in accordance with the terms contained in a written
12 ** agreement between you and The Qt Company.
12 ** agreement between you and The Qt Company.
13 **
13 **
14 ** If you have questions regarding the use of this file, please use
14 ** If you have questions regarding the use of this file, please use
15 ** contact form at http://qt.io
15 ** contact form at http://qt.io
16 **
16 **
17 ****************************************************************************/
17 ****************************************************************************/
18
18
19 #include <private/abstractbarchartitem_p.h>
19 #include <private/abstractbarchartitem_p.h>
20 #include <private/bar_p.h>
20 #include <private/bar_p.h>
21 #include <QtCharts/QBarSet>
21 #include <QtCharts/QBarSet>
22 #include <private/qbarset_p.h>
22 #include <private/qbarset_p.h>
23 #include <QtCharts/QAbstractBarSeries>
23 #include <QtCharts/QAbstractBarSeries>
24 #include <private/qabstractbarseries_p.h>
24 #include <private/qabstractbarseries_p.h>
25 #include <QtCharts/QChart>
25 #include <QtCharts/QChart>
26 #include <private/chartpresenter_p.h>
26 #include <private/chartpresenter_p.h>
27 #include <private/charttheme_p.h>
27 #include <private/charttheme_p.h>
28 #include <private/baranimation_p.h>
28 #include <private/baranimation_p.h>
29
29
30 #include <private/chartdataset_p.h>
30 #include <private/chartdataset_p.h>
31 #include <QtGui/QPainter>
31 #include <QtGui/QPainter>
32 #include <QtGui/QTextDocument>
32 #include <QtGui/QTextDocument>
33
33
34 QT_CHARTS_BEGIN_NAMESPACE
34 QT_CHARTS_BEGIN_NAMESPACE
35
35
36 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
36 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
37 ChartItem(series->d_func(),item),
37 ChartItem(series->d_func(),item),
38 m_animation(0),
38 m_animation(0),
39 m_series(series)
39 m_series(series)
40 {
40 {
41
41
42 setFlag(ItemClipsChildrenToShape);
42 setFlag(ItemClipsChildrenToShape);
43 setFlag(QGraphicsItem::ItemIsSelectable);
43 setFlag(QGraphicsItem::ItemIsSelectable);
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 connect(series, SIGNAL(labelsAngleChanged(qreal)), this, SLOT(positionLabels()));
54 connect(series, SIGNAL(labelsAngleChanged(qreal)), this, SLOT(positionLabels()));
55 setZValue(ChartPresenter::BarSeriesZValue);
55 setZValue(ChartPresenter::BarSeriesZValue);
56 handleDataStructureChanged();
56 handleDataStructureChanged();
57 handleVisibleChanged();
57 handleVisibleChanged();
58 handleUpdatedBars();
58 handleUpdatedBars();
59 }
59 }
60
60
61 AbstractBarChartItem::~AbstractBarChartItem()
61 AbstractBarChartItem::~AbstractBarChartItem()
62 {
62 {
63 }
63 }
64
64
65 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
65 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
66 {
66 {
67 Q_UNUSED(painter);
67 Q_UNUSED(painter);
68 Q_UNUSED(option);
68 Q_UNUSED(option);
69 Q_UNUSED(widget);
69 Q_UNUSED(widget);
70 }
70 }
71
71
72 QRectF AbstractBarChartItem::boundingRect() const
72 QRectF AbstractBarChartItem::boundingRect() const
73 {
73 {
74 return m_rect;
74 return m_rect;
75 }
75 }
76
76
77 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
77 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
78 {
78 {
79 QSizeF size = geometry().size();
79 QSizeF size = geometry().size();
80 if (geometry().size().isValid()) {
80 if (geometry().size().isValid()) {
81 if (m_animation) {
81 if (m_animation) {
82 if (m_layout.count() == 0 || m_oldSize != size) {
82 if (m_layout.count() == 0 || m_oldSize != size) {
83 initializeLayout();
83 initializeLayout();
84 m_oldSize = size;
84 m_oldSize = size;
85 }
85 }
86 m_animation->setup(m_layout, layout);
86 m_animation->setup(m_layout, layout);
87 presenter()->startAnimation(m_animation);
87 presenter()->startAnimation(m_animation);
88 } else {
88 } else {
89 setLayout(layout);
89 setLayout(layout);
90 update();
90 update();
91 }
91 }
92 }
92 }
93 }
93 }
94
94
95 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
95 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
96 {
96 {
97 m_animation = animation;
97 m_animation = animation;
98 }
98 }
99
99
100 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
100 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
101 {
101 {
102 if (layout.count() != m_bars.count())
102 if (layout.count() != m_bars.count())
103 return;
103 return;
104
104
105 m_layout = layout;
105 m_layout = layout;
106
106
107 for (int i = 0; i < m_bars.count(); i++)
107 for (int i = 0; i < m_bars.count(); i++)
108 m_bars.at(i)->setRect(layout.at(i));
108 m_bars.at(i)->setRect(layout.at(i));
109
109
110 positionLabels();
110 positionLabels();
111 }
111 }
112 //handlers
112 //handlers
113
113
114 void AbstractBarChartItem::handleDomainUpdated()
114 void AbstractBarChartItem::handleDomainUpdated()
115 {
115 {
116 m_domainMinX = domain()->minX();
116 m_domainMinX = domain()->minX();
117 m_domainMaxX = domain()->maxX();
117 m_domainMaxX = domain()->maxX();
118 m_domainMinY = domain()->minY();
118 m_domainMinY = domain()->minY();
119 m_domainMaxY = domain()->maxY();
119 m_domainMaxY = domain()->maxY();
120
120
121 QRectF rect(QPointF(0,0),domain()->size());
121 QRectF rect(QPointF(0,0),domain()->size());
122
122
123 if(m_rect != rect){
123 if(m_rect != rect){
124 prepareGeometryChange();
124 prepareGeometryChange();
125 m_rect = rect;
125 m_rect = rect;
126 }
126 }
127
127
128 handleLayoutChanged();
128 handleLayoutChanged();
129 }
129 }
130
130
131 void AbstractBarChartItem::handleLayoutChanged()
131 void AbstractBarChartItem::handleLayoutChanged()
132 {
132 {
133 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
133 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
134 return; // rect size zero.
134 return; // rect size zero.
135 QVector<QRectF> layout = calculateLayout();
135 QVector<QRectF> layout = calculateLayout();
136 applyLayout(layout);
136 applyLayout(layout);
137 handleUpdatedBars();
137 handleUpdatedBars();
138 }
138 }
139
139
140 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
140 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
141 {
141 {
142 foreach (QGraphicsTextItem *label, m_labels)
142 foreach (QGraphicsTextItem *label, m_labels)
143 label->setVisible(visible);
143 label->setVisible(visible);
144 update();
144 update();
145 }
145 }
146
146
147 void AbstractBarChartItem::handleDataStructureChanged()
147 void AbstractBarChartItem::handleDataStructureChanged()
148 {
148 {
149 foreach (QGraphicsItem *item, childItems())
149 foreach (QGraphicsItem *item, childItems())
150 delete item;
150 delete item;
151
151
152 m_bars.clear();
152 m_bars.clear();
153 m_labels.clear();
153 m_labels.clear();
154 m_layout.clear();
154 m_layout.clear();
155
155
156 // Create new graphic items for bars
156 // Create new graphic items for bars
157 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
157 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
158 for (int s = 0; s < m_series->count(); s++) {
158 for (int s = 0; s < m_series->count(); s++) {
159 QBarSet *set = m_series->d_func()->barsetAt(s);
159 QBarSet *set = m_series->d_func()->barsetAt(s);
160
160
161 // Bars
161 // Bars
162 Bar *bar = new Bar(set, c, this);
162 Bar *bar = new Bar(set, c, this);
163 m_bars.append(bar);
163 m_bars.append(bar);
164 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
164 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,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(pressed(int, QBarSet*)), m_series, SIGNAL(pressed(int, QBarSet*)));
166 connect(bar, SIGNAL(pressed(int, QBarSet*)), m_series, SIGNAL(pressed(int, QBarSet*)));
167 connect(bar, SIGNAL(released(int, QBarSet*)),
167 connect(bar, SIGNAL(released(int, QBarSet*)),
168 m_series, SIGNAL(released(int, QBarSet*)));
168 m_series, SIGNAL(released(int, QBarSet*)));
169 connect(bar, SIGNAL(doubleClicked(int, QBarSet*)),
169 connect(bar, SIGNAL(doubleClicked(int, QBarSet*)),
170 m_series, SIGNAL(doubleClicked(int, QBarSet*)));
170 m_series, SIGNAL(doubleClicked(int, QBarSet*)));
171 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
171 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
172 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
172 connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
173 connect(bar, SIGNAL(pressed(int, QBarSet*)), set, SIGNAL(pressed(int)));
173 connect(bar, SIGNAL(pressed(int, QBarSet*)), set, SIGNAL(pressed(int)));
174 connect(bar, SIGNAL(released(int, QBarSet*)), set, SIGNAL(released(int)));
174 connect(bar, SIGNAL(released(int, QBarSet*)), set, SIGNAL(released(int)));
175 connect(bar, SIGNAL(doubleClicked(int, QBarSet*)), set, SIGNAL(doubleClicked(int)));
175 connect(bar, SIGNAL(doubleClicked(int, QBarSet*)), set, SIGNAL(doubleClicked(int)));
176 // m_layout.append(QRectF(0, 0, 1, 1));
176 // m_layout.append(QRectF(0, 0, 1, 1));
177
177
178 // Labels
178 // Labels
179 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
179 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
180 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
180 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
181 m_labels.append(newLabel);
181 m_labels.append(newLabel);
182 }
182 }
183 }
183 }
184
184
185 if(themeManager()) themeManager()->updateSeries(m_series);
185 if(themeManager()) themeManager()->updateSeries(m_series);
186 handleLayoutChanged();
186 handleLayoutChanged();
187 handleVisibleChanged();
187 handleVisibleChanged();
188 }
188 }
189
189
190 void AbstractBarChartItem::handleVisibleChanged()
190 void AbstractBarChartItem::handleVisibleChanged()
191 {
191 {
192 bool visible = m_series->isVisible();
192 bool visible = m_series->isVisible();
193 if (visible)
193 if (visible)
194 handleLabelsVisibleChanged(m_series->isLabelsVisible());
194 handleLabelsVisibleChanged(m_series->isLabelsVisible());
195 else
195 else
196 handleLabelsVisibleChanged(visible);
196 handleLabelsVisibleChanged(visible);
197
197
198 foreach (QGraphicsItem *bar, m_bars)
198 foreach (QGraphicsItem *bar, m_bars)
199 bar->setVisible(visible);
199 bar->setVisible(visible);
200 }
200 }
201
201
202 void AbstractBarChartItem::handleOpacityChanged()
202 void AbstractBarChartItem::handleOpacityChanged()
203 {
203 {
204 foreach (QGraphicsItem *item, childItems())
204 foreach (QGraphicsItem *item, childItems())
205 item->setOpacity(m_series->opacity());
205 item->setOpacity(m_series->opacity());
206 }
206 }
207
207
208 void AbstractBarChartItem::handleUpdatedBars()
208 void AbstractBarChartItem::handleUpdatedBars()
209 {
209 {
210 if (!m_series->d_func()->blockBarUpdate()) {
210 if (!m_series->d_func()->blockBarUpdate()) {
211 // Handle changes in pen, brush, labels etc.
211 // Handle changes in pen, brush, labels etc.
212 int categoryCount = m_series->d_func()->categoryCount();
212 int categoryCount = m_series->d_func()->categoryCount();
213 int setCount = m_series->count();
213 int setCount = m_series->count();
214 int itemIndex(0);
214 int itemIndex(0);
215 static const QString valueTag(QLatin1String("@value"));
215 static const QString valueTag(QLatin1String("@value"));
216
216
217 for (int category = 0; category < categoryCount; category++) {
217 for (int category = 0; category < categoryCount; category++) {
218 for (int set = 0; set < setCount; set++) {
218 for (int set = 0; set < setCount; set++) {
219 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
219 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
220 Bar *bar = m_bars.at(itemIndex);
220 Bar *bar = m_bars.at(itemIndex);
221 bar->setPen(barSet->m_pen);
221 bar->setPen(barSet->m_pen);
222 bar->setBrush(barSet->m_brush);
222 bar->setBrush(barSet->m_brush);
223 bar->update();
223 bar->update();
224
224
225 QGraphicsTextItem *label = m_labels.at(itemIndex);
225 QGraphicsTextItem *label = m_labels.at(itemIndex);
226 QString valueLabel;
226 QString valueLabel;
227 if (presenter()) { // At startup presenter is not yet set, yet somehow update comes
227 if (presenter()) { // At startup presenter is not yet set, yet somehow update comes
228 if (m_series->labelsFormat().isEmpty()) {
228 if (barSet->value(category) == 0) {
229 valueLabel = presenter()->numberToString(barSet->value(category));
229 label->setVisible(false);
230 } else {
230 } else {
231 valueLabel = m_series->labelsFormat();
231 label->setVisible(true);
232 valueLabel.replace(valueTag,
232 if (m_series->labelsFormat().isEmpty()) {
233 valueLabel = presenter()->numberToString(barSet->value(category));
234 } else {
235 valueLabel = m_series->labelsFormat();
236 valueLabel.replace(valueTag,
233 presenter()->numberToString(barSet->value(category)));
237 presenter()->numberToString(barSet->value(category)));
238 }
234 }
239 }
235 }
240 }
236 label->setHtml(valueLabel);
241 label->setHtml(valueLabel);
237 label->setFont(barSet->m_labelFont);
242 label->setFont(barSet->m_labelFont);
238 label->setDefaultTextColor(barSet->m_labelBrush.color());
243 label->setDefaultTextColor(barSet->m_labelBrush.color());
239 label->update();
244 label->update();
240 itemIndex++;
245 itemIndex++;
241 }
246 }
242 }
247 }
243 }
248 }
244 }
249 }
245
250
246 void AbstractBarChartItem::handleLabelsPositionChanged()
251 void AbstractBarChartItem::handleLabelsPositionChanged()
247 {
252 {
248 positionLabels();
253 positionLabels();
249 }
254 }
250
255
251 void AbstractBarChartItem::positionLabels()
256 void AbstractBarChartItem::positionLabels()
252 {
257 {
253 // By default position labels on horizontal bar series
258 // By default position labels on horizontal bar series
254 // Vertical bar series overload positionLabels() to call positionLabelsVertical()
259 // Vertical bar series overload positionLabels() to call positionLabelsVertical()
255
260
256 QTransform transform;
261 QTransform transform;
257 const qreal angle = m_series->d_func()->labelsAngle();
262 const qreal angle = m_series->d_func()->labelsAngle();
258 if (angle != 0.0)
263 if (angle != 0.0)
259 transform.rotate(angle);
264 transform.rotate(angle);
260
265
261 for (int i = 0; i < m_layout.count(); i++) {
266 for (int i = 0; i < m_layout.count(); i++) {
262 QGraphicsTextItem *label = m_labels.at(i);
267 QGraphicsTextItem *label = m_labels.at(i);
263
268
264 QRectF labelRect = label->boundingRect();
269 QRectF labelRect = label->boundingRect();
265 QPointF center = labelRect.center();
270 QPointF center = labelRect.center();
266
271
267 qreal xPos = 0;
272 qreal xPos = 0;
268 qreal yPos = m_layout.at(i).center().y() - center.y();
273 qreal yPos = m_layout.at(i).center().y() - center.y();
269
274
270 int xDiff = 0;
275 int xDiff = 0;
271 if (angle != 0.0) {
276 if (angle != 0.0) {
272 label->setTransformOriginPoint(center.x(), center.y());
277 label->setTransformOriginPoint(center.x(), center.y());
273 label->setRotation(m_series->d_func()->labelsAngle());
278 label->setRotation(m_series->d_func()->labelsAngle());
274 qreal oldWidth = labelRect.width();
279 qreal oldWidth = labelRect.width();
275 labelRect = transform.mapRect(labelRect);
280 labelRect = transform.mapRect(labelRect);
276 xDiff = (labelRect.width() - oldWidth) / 2;
281 xDiff = (labelRect.width() - oldWidth) / 2;
277 }
282 }
278
283
279 int offset = m_bars.at(i)->pen().width() / 2 + 2;
284 int offset = m_bars.at(i)->pen().width() / 2 + 2;
280
285
281 switch (m_series->labelsPosition()) {
286 switch (m_series->labelsPosition()) {
282 case QAbstractBarSeries::LabelsCenter:
287 case QAbstractBarSeries::LabelsCenter:
283 xPos = m_layout.at(i).center().x() - center.x();
288 xPos = m_layout.at(i).center().x() - center.x();
284 break;
289 break;
285 case QAbstractBarSeries::LabelsInsideEnd:
290 case QAbstractBarSeries::LabelsInsideEnd:
286 xPos = m_layout.at(i).right() - labelRect.width() - offset + xDiff;
291 xPos = m_layout.at(i).right() - labelRect.width() - offset + xDiff;
287 break;
292 break;
288 case QAbstractBarSeries::LabelsInsideBase:
293 case QAbstractBarSeries::LabelsInsideBase:
289 xPos = m_layout.at(i).left() + offset + xDiff;
294 xPos = m_layout.at(i).left() + offset + xDiff;
290 break;
295 break;
291 case QAbstractBarSeries::LabelsOutsideEnd:
296 case QAbstractBarSeries::LabelsOutsideEnd:
292 xPos = m_layout.at(i).right() + offset + xDiff;
297 xPos = m_layout.at(i).right() + offset + xDiff;
293 break;
298 break;
294 default:
299 default:
295 // Invalid position, never comes here
300 // Invalid position, never comes here
296 break;
301 break;
297 }
302 }
298
303
299 label->setPos(xPos, yPos);
304 label->setPos(xPos, yPos);
300 label->setZValue(zValue() + 1);
305 label->setZValue(zValue() + 1);
301 }
306 }
302 }
307 }
303
308
304 void AbstractBarChartItem::positionLabelsVertical()
309 void AbstractBarChartItem::positionLabelsVertical()
305 {
310 {
306 QTransform transform;
311 QTransform transform;
307 const qreal angle = m_series->d_func()->labelsAngle();
312 const qreal angle = m_series->d_func()->labelsAngle();
308 if (angle != 0.0)
313 if (angle != 0.0)
309 transform.rotate(angle);
314 transform.rotate(angle);
310
315
311 for (int i = 0; i < m_layout.count(); i++) {
316 for (int i = 0; i < m_layout.count(); i++) {
312 QGraphicsTextItem *label = m_labels.at(i);
317 QGraphicsTextItem *label = m_labels.at(i);
313
318
314 QRectF labelRect = label->boundingRect();
319 QRectF labelRect = label->boundingRect();
315 QPointF center = labelRect.center();
320 QPointF center = labelRect.center();
316
321
317 qreal xPos = m_layout.at(i).center().x() - center.x();
322 qreal xPos = m_layout.at(i).center().x() - center.x();
318 qreal yPos = 0;
323 qreal yPos = 0;
319
324
320 int yDiff = 0;
325 int yDiff = 0;
321 if (angle != 0.0) {
326 if (angle != 0.0) {
322 label->setTransformOriginPoint(center.x(), center.y());
327 label->setTransformOriginPoint(center.x(), center.y());
323 label->setRotation(m_series->d_func()->labelsAngle());
328 label->setRotation(m_series->d_func()->labelsAngle());
324 qreal oldHeight = labelRect.height();
329 qreal oldHeight = labelRect.height();
325 labelRect = transform.mapRect(labelRect);
330 labelRect = transform.mapRect(labelRect);
326 yDiff = (labelRect.height() - oldHeight) / 2;
331 yDiff = (labelRect.height() - oldHeight) / 2;
327 }
332 }
328
333
329 int offset = m_bars.at(i)->pen().width() / 2 + 2;
334 int offset = m_bars.at(i)->pen().width() / 2 + 2;
330
335
331 switch (m_series->labelsPosition()) {
336 switch (m_series->labelsPosition()) {
332 case QAbstractBarSeries::LabelsCenter:
337 case QAbstractBarSeries::LabelsCenter:
333 yPos = m_layout.at(i).center().y() - center.y();
338 yPos = m_layout.at(i).center().y() - center.y();
334 break;
339 break;
335 case QAbstractBarSeries::LabelsInsideEnd:
340 case QAbstractBarSeries::LabelsInsideEnd:
336 yPos = m_layout.at(i).top() + offset + yDiff;
341 yPos = m_layout.at(i).top() + offset + yDiff;
337 break;
342 break;
338 case QAbstractBarSeries::LabelsInsideBase:
343 case QAbstractBarSeries::LabelsInsideBase:
339 yPos = m_layout.at(i).bottom() - labelRect.height() - offset + yDiff;
344 yPos = m_layout.at(i).bottom() - labelRect.height() - offset + yDiff;
340 break;
345 break;
341 case QAbstractBarSeries::LabelsOutsideEnd:
346 case QAbstractBarSeries::LabelsOutsideEnd:
342 yPos = m_layout.at(i).top() - labelRect.height() - offset + yDiff;
347 yPos = m_layout.at(i).top() - labelRect.height() - offset + yDiff;
343 break;
348 break;
344 default:
349 default:
345 // Invalid position, never comes here
350 // Invalid position, never comes here
346 break;
351 break;
347 }
352 }
348
353
349 label->setPos(xPos, yPos);
354 label->setPos(xPos, yPos);
350 label->setZValue(zValue() + 1);
355 label->setZValue(zValue() + 1);
351 }
356 }
352 }
357 }
353
358
354 #include "moc_abstractbarchartitem_p.cpp"
359 #include "moc_abstractbarchartitem_p.cpp"
355
360
356 QT_CHARTS_END_NAMESPACE
361 QT_CHARTS_END_NAMESPACE
@@ -1,138 +1,143
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd
3 ** Copyright (C) 2015 The Qt Company Ltd
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 **
6 **
7 ** This file is part of the Qt Charts module.
7 ** This file is part of the Qt Charts module.
8 **
8 **
9 ** Licensees holding valid commercial license for Qt may use this file in
9 ** Licensees holding valid commercial license for Qt may use this file in
10 ** accordance with the Qt License Agreement provided with the Software
10 ** accordance with the Qt License Agreement provided with the Software
11 ** or, alternatively, in accordance with the terms contained in a written
11 ** or, alternatively, in accordance with the terms contained in a written
12 ** agreement between you and The Qt Company.
12 ** agreement between you and The Qt Company.
13 **
13 **
14 ** If you have questions regarding the use of this file, please use
14 ** If you have questions regarding the use of this file, please use
15 ** contact form at http://qt.io
15 ** contact form at http://qt.io
16 **
16 **
17 ****************************************************************************/
17 ****************************************************************************/
18
18
19 #include <private/horizontalpercentbarchartitem_p.h>
19 #include <private/horizontalpercentbarchartitem_p.h>
20 #include <private/qabstractbarseries_p.h>
20 #include <private/qabstractbarseries_p.h>
21 #include <private/qbarset_p.h>
21 #include <private/qbarset_p.h>
22 #include <private/bar_p.h>
22 #include <private/bar_p.h>
23
23
24 QT_CHARTS_BEGIN_NAMESPACE
24 QT_CHARTS_BEGIN_NAMESPACE
25
25
26 HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
26 HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
27 : AbstractBarChartItem(series, item)
27 : AbstractBarChartItem(series, item)
28 {
28 {
29 }
29 }
30
30
31 void HorizontalPercentBarChartItem::initializeLayout()
31 void HorizontalPercentBarChartItem::initializeLayout()
32 {
32 {
33 qreal categoryCount = m_series->d_func()->categoryCount();
33 qreal categoryCount = m_series->d_func()->categoryCount();
34 qreal setCount = m_series->count();
34 qreal setCount = m_series->count();
35 qreal barWidth = m_series->d_func()->barWidth();
35 qreal barWidth = m_series->d_func()->barWidth();
36
36
37 m_layout.clear();
37 m_layout.clear();
38 for(int category = 0; category < categoryCount; category++) {
38 for(int category = 0; category < categoryCount; category++) {
39 for (int set = 0; set < setCount; set++) {
39 for (int set = 0; set < setCount; set++) {
40 QRectF rect;
40 QRectF rect;
41 QPointF topLeft;
41 QPointF topLeft;
42 QPointF bottomRight;
42 QPointF bottomRight;
43 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
43 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
44 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
44 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
45 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
45 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
46 } else {
46 } else {
47 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
47 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
48 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
48 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
49 }
49 }
50
50
51 if (!m_validData)
51 if (!m_validData)
52 return;
52 return;
53
53
54 rect.setTopLeft(topLeft);
54 rect.setTopLeft(topLeft);
55 rect.setBottomRight(bottomRight);
55 rect.setBottomRight(bottomRight);
56 m_layout.append(rect.normalized());
56 m_layout.append(rect.normalized());
57 }
57 }
58 }
58 }
59 }
59 }
60
60
61 QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
61 QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
62 {
62 {
63 QVector<QRectF> layout;
63 QVector<QRectF> layout;
64
64
65 // Use temporary qreals for accuracy
65 // Use temporary qreals for accuracy
66 qreal categoryCount = m_series->d_func()->categoryCount();
66 qreal categoryCount = m_series->d_func()->categoryCount();
67 qreal setCount = m_series->count();
67 qreal setCount = m_series->count();
68 qreal barWidth = m_series->d_func()->barWidth();
68 qreal barWidth = m_series->d_func()->barWidth();
69
69
70 for(int category = 0; category < categoryCount; category++) {
70 for(int category = 0; category < categoryCount; category++) {
71 qreal sum = 0;
71 qreal sum = 0;
72 qreal categorySum = m_series->d_func()->categorySum(category);
72 qreal categorySum = m_series->d_func()->categorySum(category);
73 for (int set = 0; set < setCount; set++) {
73 for (int set = 0; set < setCount; set++) {
74 qreal value = m_series->barSets().at(set)->at(category);
74 qreal value = m_series->barSets().at(set)->at(category);
75 QRectF rect;
75 QRectF rect;
76 qreal topX = 0;
76 qreal topX = 0;
77 if (sum > 0)
77 if (sum > 0)
78 topX = 100 * sum / categorySum;
78 topX = 100 * sum / categorySum;
79 qreal bottomX = 0;
79 qreal bottomX = 0;
80 qreal newSum = value + sum;
80 qreal newSum = value + sum;
81 if (newSum > 0)
81 if (newSum > 0)
82 bottomX = 100 * newSum / categorySum;
82 bottomX = 100 * newSum / categorySum;
83 QPointF topLeft;
83 QPointF topLeft;
84 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
84 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
85 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : domain()->minX(), category - barWidth/2), m_validData);
85 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : domain()->minX(), category - barWidth/2), m_validData);
86 else
86 else
87 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : 0, category - barWidth/2), m_validData);
87 topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : 0, category - barWidth/2), m_validData);
88 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(bottomX, category + barWidth/2), m_validData);
88 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(bottomX, category + barWidth/2), m_validData);
89
89
90 rect.setTopLeft(topLeft);
90 rect.setTopLeft(topLeft);
91 rect.setBottomRight(bottomRight);
91 rect.setBottomRight(bottomRight);
92 layout.append(rect.normalized());
92 layout.append(rect.normalized());
93 sum = newSum;
93 sum = newSum;
94 }
94 }
95 }
95 }
96 return layout;
96 return layout;
97 }
97 }
98
98
99 void HorizontalPercentBarChartItem::handleUpdatedBars()
99 void HorizontalPercentBarChartItem::handleUpdatedBars()
100 {
100 {
101 // Handle changes in pen, brush, labels etc.
101 // Handle changes in pen, brush, labels etc.
102 int categoryCount = m_series->d_func()->categoryCount();
102 int categoryCount = m_series->d_func()->categoryCount();
103 int setCount = m_series->count();
103 int setCount = m_series->count();
104 int itemIndex(0);
104 int itemIndex(0);
105 static const QString valueTag(QLatin1String("@value"));
105 static const QString valueTag(QLatin1String("@value"));
106
106
107 for (int category = 0; category < categoryCount; category++) {
107 for (int category = 0; category < categoryCount; category++) {
108 for (int set = 0; set < setCount; set++) {
108 for (int set = 0; set < setCount; set++) {
109 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
109 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
110 Bar *bar = m_bars.at(itemIndex);
110 Bar *bar = m_bars.at(itemIndex);
111 bar->setPen(barSet->m_pen);
111 bar->setPen(barSet->m_pen);
112 bar->setBrush(barSet->m_brush);
112 bar->setBrush(barSet->m_brush);
113 bar->update();
113 bar->update();
114
114
115 QGraphicsTextItem *label = m_labels.at(itemIndex);
115 QGraphicsTextItem *label = m_labels.at(itemIndex);
116 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
116 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
117 QString vString(presenter()->numberToString(p, 'f', 0));
117 QString vString(presenter()->numberToString(p, 'f', 0));
118 QString valueLabel;
118 QString valueLabel;
119 if (m_series->labelsFormat().isEmpty()) {
119 if (p == 0) {
120 vString.append(QStringLiteral("%"));
120 label->setVisible(false);
121 valueLabel = vString;
122 } else {
121 } else {
123 valueLabel = m_series->labelsFormat();
122 label->setVisible(true);
124 valueLabel.replace(valueTag, vString);
123 if (m_series->labelsFormat().isEmpty()) {
124 vString.append(QStringLiteral("%"));
125 valueLabel = vString;
126 } else {
127 valueLabel = m_series->labelsFormat();
128 valueLabel.replace(valueTag, vString);
129 }
125 }
130 }
126 label->setHtml(valueLabel);
131 label->setHtml(valueLabel);
127 label->setFont(barSet->m_labelFont);
132 label->setFont(barSet->m_labelFont);
128 label->setDefaultTextColor(barSet->m_labelBrush.color());
133 label->setDefaultTextColor(barSet->m_labelBrush.color());
129 label->update();
134 label->update();
130 itemIndex++;
135 itemIndex++;
131 }
136 }
132 }
137 }
133 }
138 }
134
139
135 #include "moc_horizontalpercentbarchartitem_p.cpp"
140 #include "moc_horizontalpercentbarchartitem_p.cpp"
136
141
137 QT_CHARTS_END_NAMESPACE
142 QT_CHARTS_END_NAMESPACE
138
143
@@ -1,686 +1,688
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd
3 ** Copyright (C) 2015 The Qt Company Ltd
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 **
6 **
7 ** This file is part of the Qt Charts module.
7 ** This file is part of the Qt Charts module.
8 **
8 **
9 ** Licensees holding valid commercial license for Qt may use this file in
9 ** Licensees holding valid commercial license for Qt may use this file in
10 ** accordance with the Qt License Agreement provided with the Software
10 ** accordance with the Qt License Agreement provided with the Software
11 ** or, alternatively, in accordance with the terms contained in a written
11 ** or, alternatively, in accordance with the terms contained in a written
12 ** agreement between you and The Qt Company.
12 ** agreement between you and The Qt Company.
13 **
13 **
14 ** If you have questions regarding the use of this file, please use
14 ** If you have questions regarding the use of this file, please use
15 ** contact form at http://qt.io
15 ** contact form at http://qt.io
16 **
16 **
17 ****************************************************************************/
17 ****************************************************************************/
18
18
19 #include <QtCharts/QBarSet>
19 #include <QtCharts/QBarSet>
20 #include <private/qbarset_p.h>
20 #include <private/qbarset_p.h>
21 #include <private/charthelpers_p.h>
21 #include <private/charthelpers_p.h>
22 #include <private/qchart_p.h>
22 #include <private/qchart_p.h>
23
23
24 QT_CHARTS_BEGIN_NAMESPACE
24 QT_CHARTS_BEGIN_NAMESPACE
25
25
26 /*!
26 /*!
27 \class QBarSet
27 \class QBarSet
28 \inmodule Qt Charts
28 \inmodule Qt Charts
29 \brief Building block for different bar charts.
29 \brief Building block for different bar charts.
30
30
31 QBarSet represents one set of bars. Set of bars contains one data value for each category.
31 QBarSet represents one set of bars. Set of bars contains one data value for each category.
32 First value of set is assumed to belong to first category, second to second category and so on.
32 First value of set is assumed to belong to first category, second to second category and so on.
33 If set has fewer values than there are categories, then the missing values are assumed to be
33 If set has fewer values than there are categories, then the missing values are assumed to be
34 at the end of set. For missing values in middle of a set, numerical value of zero is used.
34 at the end of set. For missing values in middle of a set, numerical value of zero is used.
35 Labels for zero value sets are not shown.
35
36
36 \sa QAbstractBarSeries, QBarSeries, QStackedBarSeries, QPercentBarSeries
37 \sa QAbstractBarSeries, QBarSeries, QStackedBarSeries, QPercentBarSeries
37 */
38 */
38 /*!
39 /*!
39 \qmltype BarSet
40 \qmltype BarSet
40 \instantiates QBarSet
41 \instantiates QBarSet
41 \inqmlmodule QtCharts
42 \inqmlmodule QtCharts
42
43
43 \brief Building block for different bar charts.
44 \brief Building block for different bar charts.
44
45
45 BarSet represents one set of bars. Set of bars contains one data value for each category.
46 BarSet represents one set of bars. Set of bars contains one data value for each category.
46 First value of set is assumed to belong to first category, second to second category and so on.
47 First value of set is assumed to belong to first category, second to second category and so on.
47 If set has fewer values than there are categories, then the missing values are assumed to be
48 If set has fewer values than there are categories, then the missing values are assumed to be
48 at the end of set. For missing values in middle of a set, numerical value of zero is used.
49 at the end of set. For missing values in middle of a set, numerical value of zero is used.
50 Labels for zero value sets are not shown.
49 \sa AbstractBarSeries, BarSeries, StackedBarSeries, PercentBarSeries
51 \sa AbstractBarSeries, BarSeries, StackedBarSeries, PercentBarSeries
50 */
52 */
51
53
52 /*!
54 /*!
53 \property QBarSet::label
55 \property QBarSet::label
54 Defines the label of the bar set.
56 Defines the label of the bar set.
55 */
57 */
56 /*!
58 /*!
57 \qmlproperty string BarSet::label
59 \qmlproperty string BarSet::label
58 Defines the label of the bar set.
60 Defines the label of the bar set.
59 */
61 */
60
62
61 /*!
63 /*!
62 \property QBarSet::pen
64 \property QBarSet::pen
63 \brief Defines the pen used by the bar set.
65 \brief Defines the pen used by the bar set.
64 */
66 */
65
67
66 /*!
68 /*!
67 \property QBarSet::brush
69 \property QBarSet::brush
68 \brief Defines the brush used by the bar set.
70 \brief Defines the brush used by the bar set.
69 */
71 */
70
72
71 /*!
73 /*!
72 \qmlproperty QString BarSet::brushFilename
74 \qmlproperty QString BarSet::brushFilename
73 The name of the file used as a brush for the set.
75 The name of the file used as a brush for the set.
74 */
76 */
75
77
76 /*!
78 /*!
77 \property QBarSet::labelBrush
79 \property QBarSet::labelBrush
78 \brief Defines the brush used by the bar set's label.
80 \brief Defines the brush used by the bar set's label.
79 */
81 */
80
82
81 /*!
83 /*!
82 \property QBarSet::labelFont
84 \property QBarSet::labelFont
83 \brief Defines the font used by the bar set's label.
85 \brief Defines the font used by the bar set's label.
84 */
86 */
85
87
86 /*!
88 /*!
87 \qmlproperty Font BarSet::labelFont
89 \qmlproperty Font BarSet::labelFont
88 Defines the font used by the bar set's label.
90 Defines the font used by the bar set's label.
89
91
90 See the Qt documentation for more details of Font.
92 See the Qt documentation for more details of Font.
91 */
93 */
92
94
93 /*!
95 /*!
94 \property QBarSet::color
96 \property QBarSet::color
95 The fill (brush) color of the bar set.
97 The fill (brush) color of the bar set.
96 */
98 */
97 /*!
99 /*!
98 \qmlproperty color BarSet::color
100 \qmlproperty color BarSet::color
99 The fill (brush) color of the bar set.
101 The fill (brush) color of the bar set.
100 */
102 */
101
103
102 /*!
104 /*!
103 \property QBarSet::borderColor
105 \property QBarSet::borderColor
104 The line (pen) color of the bar set.
106 The line (pen) color of the bar set.
105 */
107 */
106 /*!
108 /*!
107 \qmlproperty color BarSet::borderColor
109 \qmlproperty color BarSet::borderColor
108 The line (pen) color of the bar set.
110 The line (pen) color of the bar set.
109 */
111 */
110
112
111 /*!
113 /*!
112 \qmlproperty real BarSet::borderWidth
114 \qmlproperty real BarSet::borderWidth
113 The width of the border line. By default the width is 2.0.
115 The width of the border line. By default the width is 2.0.
114 */
116 */
115
117
116 /*!
118 /*!
117 \property QBarSet::labelColor
119 \property QBarSet::labelColor
118 The text (label) color of the bar set.
120 The text (label) color of the bar set.
119 */
121 */
120 /*!
122 /*!
121 \qmlproperty color BarSet::labelColor
123 \qmlproperty color BarSet::labelColor
122 The text (label) color of the bar set.
124 The text (label) color of the bar set.
123 */
125 */
124
126
125 /*!
127 /*!
126 \fn void QBarSet::clicked(int index)
128 \fn void QBarSet::clicked(int index)
127
129
128 The signal is emitted if the user clicks with a mouse on top of bar set.
130 The signal is emitted if the user clicks with a mouse on top of bar set.
129 Clicked bar inside set is indexed by \a index
131 Clicked bar inside set is indexed by \a index
130 */
132 */
131
133
132 /*!
134 /*!
133 \fn void QBarSet::pressed(int index)
135 \fn void QBarSet::pressed(int index)
134
136
135 The signal is emitted if the user presses with a mouse on top of bar set.
137 The signal is emitted if the user presses with a mouse on top of bar set.
136 Pressed bar inside set is indexed by \a index
138 Pressed bar inside set is indexed by \a index
137 */
139 */
138
140
139 /*!
141 /*!
140 \fn void QBarSet::released(int index)
142 \fn void QBarSet::released(int index)
141
143
142 The signal is emitted if the user releases with a mouse on top of bar set.
144 The signal is emitted if the user releases with a mouse on top of bar set.
143 Released bar inside set is indexed by \a index
145 Released bar inside set is indexed by \a index
144 */
146 */
145
147
146 /*!
148 /*!
147 \fn void QBarSet::doubleClicked(int index)
149 \fn void QBarSet::doubleClicked(int index)
148
150
149 The signal is emitted if the user doubleclicks with a mouse on top of bar set.
151 The signal is emitted if the user doubleclicks with a mouse on top of bar set.
150 Doubleclicked bar inside set is indexed by \a index
152 Doubleclicked bar inside set is indexed by \a index
151 */
153 */
152
154
153 /*!
155 /*!
154 \fn void QBarSet::hovered(bool status, int index)
156 \fn void QBarSet::hovered(bool status, int index)
155
157
156 The signal is emitted if mouse is hovered on top of bar set.
158 The signal is emitted if mouse is hovered on top of bar set.
157 Parameter \a status is true, if mouse entered on top of bar set, false if mouse left from top of bar set.
159 Parameter \a status is true, if mouse entered on top of bar set, false if mouse left from top of bar set.
158 Hovered bar inside the set is indexed by \a index.
160 Hovered bar inside the set is indexed by \a index.
159 */
161 */
160
162
161
163
162 /*!
164 /*!
163 \fn void QBarSet::labelChanged()
165 \fn void QBarSet::labelChanged()
164 This signal is emitted when the label of the bar set has changed.
166 This signal is emitted when the label of the bar set has changed.
165 \sa label
167 \sa label
166 */
168 */
167 /*!
169 /*!
168 \qmlsignal BarSet::onLabelChanged()
170 \qmlsignal BarSet::onLabelChanged()
169 This signal is emitted when the label of the bar set has changed.
171 This signal is emitted when the label of the bar set has changed.
170 */
172 */
171
173
172 /*!
174 /*!
173 \fn void QBarSet::penChanged()
175 \fn void QBarSet::penChanged()
174 This signal is emitted when the pen of the bar set has changed.
176 This signal is emitted when the pen of the bar set has changed.
175 \sa pen
177 \sa pen
176 */
178 */
177
179
178 /*!
180 /*!
179 \fn void QBarSet::brushChanged()
181 \fn void QBarSet::brushChanged()
180 This signal is emitted when the brush of the bar set has changed.
182 This signal is emitted when the brush of the bar set has changed.
181 \sa brush
183 \sa brush
182 */
184 */
183
185
184 /*!
186 /*!
185 \fn void QBarSet::labelBrushChanged()
187 \fn void QBarSet::labelBrushChanged()
186 This signal is emitted when the brush of the bar set's label has changed.
188 This signal is emitted when the brush of the bar set's label has changed.
187 \sa labelBrush
189 \sa labelBrush
188 */
190 */
189
191
190 /*!
192 /*!
191 \fn void QBarSet::labelFontChanged()
193 \fn void QBarSet::labelFontChanged()
192 This signal is emitted when the font of the bar set's label has changed.
194 This signal is emitted when the font of the bar set's label has changed.
193 \sa labelBrush
195 \sa labelBrush
194 */
196 */
195
197
196 /*!
198 /*!
197 \fn void QBarSet::colorChanged(QColor)
199 \fn void QBarSet::colorChanged(QColor)
198 This signal is emitted when the fill (brush) color of the set has changed to \a color.
200 This signal is emitted when the fill (brush) color of the set has changed to \a color.
199 */
201 */
200 /*!
202 /*!
201 \qmlsignal BarSet::onColorChanged(color color)
203 \qmlsignal BarSet::onColorChanged(color color)
202 This signal is emitted when the fill (brush) color of the set has changed to \a color.
204 This signal is emitted when the fill (brush) color of the set has changed to \a color.
203 */
205 */
204
206
205 /*!
207 /*!
206 \fn void QBarSet::borderColorChanged(QColor)
208 \fn void QBarSet::borderColorChanged(QColor)
207 This signal is emitted when the line (pen) color of the set has changed to \a color.
209 This signal is emitted when the line (pen) color of the set has changed to \a color.
208 */
210 */
209 /*!
211 /*!
210 \qmlsignal BarSet::onBorderColorChanged(color color)
212 \qmlsignal BarSet::onBorderColorChanged(color color)
211 This signal is emitted when the line (pen) color of the set has changed to \a color.
213 This signal is emitted when the line (pen) color of the set has changed to \a color.
212 */
214 */
213
215
214 /*!
216 /*!
215 \fn void QBarSet::labelColorChanged(QColor)
217 \fn void QBarSet::labelColorChanged(QColor)
216 This signal is emitted when the text (label) color of the set has changed to \a color.
218 This signal is emitted when the text (label) color of the set has changed to \a color.
217 */
219 */
218 /*!
220 /*!
219 \qmlsignal BarSet::onLabelColorChanged(color color)
221 \qmlsignal BarSet::onLabelColorChanged(color color)
220 This signal is emitted when the text (label) color of the set has changed to \a color.
222 This signal is emitted when the text (label) color of the set has changed to \a color.
221 */
223 */
222
224
223 /*!
225 /*!
224 \fn void QBarSet::valuesAdded(int index, int count)
226 \fn void QBarSet::valuesAdded(int index, int count)
225 This signal is emitted when new values have been added to the set.
227 This signal is emitted when new values have been added to the set.
226 Parameter \a index indicates the position of the first inserted value.
228 Parameter \a index indicates the position of the first inserted value.
227 Parameter \a count is the number of inserted values.
229 Parameter \a count is the number of inserted values.
228 \sa append(), insert()
230 \sa append(), insert()
229 */
231 */
230 /*!
232 /*!
231 \qmlsignal BarSet::onValuesAdded(int index, int count)
233 \qmlsignal BarSet::onValuesAdded(int index, int count)
232 This signal is emitted when new values have been added to the set.
234 This signal is emitted when new values have been added to the set.
233 Parameter \a index indicates the position of the first inserted value.
235 Parameter \a index indicates the position of the first inserted value.
234 Parameter \a count is the number of inserted values.
236 Parameter \a count is the number of inserted values.
235 */
237 */
236
238
237 /*!
239 /*!
238 \fn void QBarSet::valuesRemoved(int index, int count)
240 \fn void QBarSet::valuesRemoved(int index, int count)
239 This signal is emitted values have been removed from the set.
241 This signal is emitted values have been removed from the set.
240 Parameter \a index indicates the position of the first removed value.
242 Parameter \a index indicates the position of the first removed value.
241 Parameter \a count is the number of removed values.
243 Parameter \a count is the number of removed values.
242 \sa remove()
244 \sa remove()
243 */
245 */
244 /*!
246 /*!
245 \qmlsignal BarSet::onValuesRemoved(int index, int count)
247 \qmlsignal BarSet::onValuesRemoved(int index, int count)
246 This signal is emitted values have been removed from the set.
248 This signal is emitted values have been removed from the set.
247 Parameter \a index indicates the position of the first removed value.
249 Parameter \a index indicates the position of the first removed value.
248 Parameter \a count is the number of removed values.
250 Parameter \a count is the number of removed values.
249 */
251 */
250
252
251 /*!
253 /*!
252 \fn void QBarSet::valueChanged(int index)
254 \fn void QBarSet::valueChanged(int index)
253 This signal is emitted values the value in the set has been modified.
255 This signal is emitted values the value in the set has been modified.
254 Parameter \a index indicates the position of the modified value.
256 Parameter \a index indicates the position of the modified value.
255 \sa at()
257 \sa at()
256 */
258 */
257 /*!
259 /*!
258 \qmlsignal BarSet::onValueChanged(int index)
260 \qmlsignal BarSet::onValueChanged(int index)
259 This signal is emitted values the value in the set has been modified.
261 This signal is emitted values the value in the set has been modified.
260 Parameter \a index indicates the position of the modified value.
262 Parameter \a index indicates the position of the modified value.
261 */
263 */
262
264
263 /*!
265 /*!
264 \qmlproperty int BarSet::count
266 \qmlproperty int BarSet::count
265 The count of values on the bar set
267 The count of values on the bar set
266 */
268 */
267
269
268 /*!
270 /*!
269 \qmlproperty QVariantList BarSet::values
271 \qmlproperty QVariantList BarSet::values
270 The values of the bar set. You can set either a list of reals or a list of points as values. If you set a list of
272 The values of the bar set. You can set either a list of reals or a list of points as values. If you set a list of
271 reals as values, the values are automatically completed to points by using the index of a value as it's
273 reals as values, the values are automatically completed to points by using the index of a value as it's
272 x-coordinate. For example the following sets have equal values:
274 x-coordinate. For example the following sets have equal values:
273 \code
275 \code
274 myBarSet1.values = [0, 5, 1, 5];
276 myBarSet1.values = [0, 5, 1, 5];
275 myBarSet2.values = [Qt.point(0, 0), Qt.point(1, 5), Qt.point(2, 1), Qt.point(3, 5)];
277 myBarSet2.values = [Qt.point(0, 0), Qt.point(1, 5), Qt.point(2, 1), Qt.point(3, 5)];
276 \endcode
278 \endcode
277 */
279 */
278
280
279 /*!
281 /*!
280 Constructs QBarSet with a label of \a label and with parent of \a parent.
282 Constructs QBarSet with a label of \a label and with parent of \a parent.
281 */
283 */
282 QBarSet::QBarSet(const QString label, QObject *parent)
284 QBarSet::QBarSet(const QString label, QObject *parent)
283 : QObject(parent),
285 : QObject(parent),
284 d_ptr(new QBarSetPrivate(label, this))
286 d_ptr(new QBarSetPrivate(label, this))
285 {
287 {
286 }
288 }
287
289
288 /*!
290 /*!
289 Destroys the bar set.
291 Destroys the bar set.
290 */
292 */
291 QBarSet::~QBarSet()
293 QBarSet::~QBarSet()
292 {
294 {
293 // NOTE: d_ptr destroyed by QObject
295 // NOTE: d_ptr destroyed by QObject
294 }
296 }
295
297
296 /*!
298 /*!
297 Sets new \a label for set.
299 Sets new \a label for set.
298 */
300 */
299 void QBarSet::setLabel(const QString label)
301 void QBarSet::setLabel(const QString label)
300 {
302 {
301 d_ptr->m_label = label;
303 d_ptr->m_label = label;
302 emit labelChanged();
304 emit labelChanged();
303 }
305 }
304
306
305 /*!
307 /*!
306 Returns label of the set.
308 Returns label of the set.
307 */
309 */
308 QString QBarSet::label() const
310 QString QBarSet::label() const
309 {
311 {
310 return d_ptr->m_label;
312 return d_ptr->m_label;
311 }
313 }
312
314
313 /*!
315 /*!
314 Appends new value \a value to the end of set.
316 Appends new value \a value to the end of set.
315 */
317 */
316 void QBarSet::append(const qreal value)
318 void QBarSet::append(const qreal value)
317 {
319 {
318 // Convert to QPointF
320 // Convert to QPointF
319 int index = d_ptr->m_values.count();
321 int index = d_ptr->m_values.count();
320 d_ptr->append(QPointF(d_ptr->m_values.count(), value));
322 d_ptr->append(QPointF(d_ptr->m_values.count(), value));
321 emit valuesAdded(index, 1);
323 emit valuesAdded(index, 1);
322 }
324 }
323
325
324 /*!
326 /*!
325 Appends a list of reals to set. Works like append with single real value. The \a values in list
327 Appends a list of reals to set. Works like append with single real value. The \a values in list
326 are appended to end of bar set.
328 are appended to end of bar set.
327 \sa append()
329 \sa append()
328 */
330 */
329 void QBarSet::append(const QList<qreal> &values)
331 void QBarSet::append(const QList<qreal> &values)
330 {
332 {
331 int index = d_ptr->m_values.count();
333 int index = d_ptr->m_values.count();
332 d_ptr->append(values);
334 d_ptr->append(values);
333 emit valuesAdded(index, values.count());
335 emit valuesAdded(index, values.count());
334 }
336 }
335
337
336 /*!
338 /*!
337 Convenience operator. Same as append, with real \a value.
339 Convenience operator. Same as append, with real \a value.
338 \sa append()
340 \sa append()
339 */
341 */
340 QBarSet &QBarSet::operator << (const qreal &value)
342 QBarSet &QBarSet::operator << (const qreal &value)
341 {
343 {
342 append(value);
344 append(value);
343 return *this;
345 return *this;
344 }
346 }
345
347
346 /*!
348 /*!
347 Inserts new \a value on the \a index position.
349 Inserts new \a value on the \a index position.
348 The value that is currently at this postion is moved to position index + 1
350 The value that is currently at this postion is moved to position index + 1
349 \sa remove()
351 \sa remove()
350 */
352 */
351 void QBarSet::insert(const int index, const qreal value)
353 void QBarSet::insert(const int index, const qreal value)
352 {
354 {
353 d_ptr->insert(index, value);
355 d_ptr->insert(index, value);
354 emit valuesAdded(index, 1);
356 emit valuesAdded(index, 1);
355 }
357 }
356
358
357 /*!
359 /*!
358 Removes \a count number of values from the set starting at \a index.
360 Removes \a count number of values from the set starting at \a index.
359 \sa insert()
361 \sa insert()
360 */
362 */
361 void QBarSet::remove(const int index, const int count)
363 void QBarSet::remove(const int index, const int count)
362 {
364 {
363 int removedCount = d_ptr->remove(index, count);
365 int removedCount = d_ptr->remove(index, count);
364 if (removedCount > 0)
366 if (removedCount > 0)
365 emit valuesRemoved(index, removedCount);
367 emit valuesRemoved(index, removedCount);
366 return;
368 return;
367 }
369 }
368
370
369 /*!
371 /*!
370 Sets a new value \a value to set, indexed by \a index.
372 Sets a new value \a value to set, indexed by \a index.
371 */
373 */
372 void QBarSet::replace(const int index, const qreal value)
374 void QBarSet::replace(const int index, const qreal value)
373 {
375 {
374 if (index >= 0 && index < d_ptr->m_values.count()) {
376 if (index >= 0 && index < d_ptr->m_values.count()) {
375 d_ptr->replace(index, value);
377 d_ptr->replace(index, value);
376 emit valueChanged(index);
378 emit valueChanged(index);
377 }
379 }
378 }
380 }
379
381
380
382
381 /*!
383 /*!
382 Returns value of set indexed by \a index.
384 Returns value of set indexed by \a index.
383 If the index is out of bounds 0.0 is returned.
385 If the index is out of bounds 0.0 is returned.
384 */
386 */
385 qreal QBarSet::at(const int index) const
387 qreal QBarSet::at(const int index) const
386 {
388 {
387 if (index < 0 || index >= d_ptr->m_values.count())
389 if (index < 0 || index >= d_ptr->m_values.count())
388 return 0;
390 return 0;
389 return d_ptr->m_values.at(index).y();
391 return d_ptr->m_values.at(index).y();
390 }
392 }
391
393
392 /*!
394 /*!
393 Returns value of set indexed by \a index.
395 Returns value of set indexed by \a index.
394 If the index is out of bounds 0.0 is returned.
396 If the index is out of bounds 0.0 is returned.
395 */
397 */
396 qreal QBarSet::operator [](const int index) const
398 qreal QBarSet::operator [](const int index) const
397 {
399 {
398 return at(index);
400 return at(index);
399 }
401 }
400
402
401 /*!
403 /*!
402 Returns count of values in set.
404 Returns count of values in set.
403 */
405 */
404 int QBarSet::count() const
406 int QBarSet::count() const
405 {
407 {
406 return d_ptr->m_values.count();
408 return d_ptr->m_values.count();
407 }
409 }
408
410
409 /*!
411 /*!
410 Returns sum of all values in the bar set.
412 Returns sum of all values in the bar set.
411 */
413 */
412 qreal QBarSet::sum() const
414 qreal QBarSet::sum() const
413 {
415 {
414 qreal total(0);
416 qreal total(0);
415 for (int i = 0; i < d_ptr->m_values.count(); i++)
417 for (int i = 0; i < d_ptr->m_values.count(); i++)
416 total += d_ptr->m_values.at(i).y();
418 total += d_ptr->m_values.at(i).y();
417 return total;
419 return total;
418 }
420 }
419
421
420 /*!
422 /*!
421 Sets pen for set. Bars of this set are drawn using \a pen
423 Sets pen for set. Bars of this set are drawn using \a pen
422 */
424 */
423 void QBarSet::setPen(const QPen &pen)
425 void QBarSet::setPen(const QPen &pen)
424 {
426 {
425 if (d_ptr->m_pen != pen) {
427 if (d_ptr->m_pen != pen) {
426 d_ptr->m_pen = pen;
428 d_ptr->m_pen = pen;
427 emit d_ptr->updatedBars();
429 emit d_ptr->updatedBars();
428 emit penChanged();
430 emit penChanged();
429 }
431 }
430 }
432 }
431
433
432 /*!
434 /*!
433 Returns pen of the set.
435 Returns pen of the set.
434 */
436 */
435 QPen QBarSet::pen() const
437 QPen QBarSet::pen() const
436 {
438 {
437 if (d_ptr->m_pen == QChartPrivate::defaultPen())
439 if (d_ptr->m_pen == QChartPrivate::defaultPen())
438 return QPen();
440 return QPen();
439 else
441 else
440 return d_ptr->m_pen;
442 return d_ptr->m_pen;
441 }
443 }
442
444
443 /*!
445 /*!
444 Sets brush for the set. Bars of this set are drawn using \a brush.
446 Sets brush for the set. Bars of this set are drawn using \a brush.
445 */
447 */
446 void QBarSet::setBrush(const QBrush &brush)
448 void QBarSet::setBrush(const QBrush &brush)
447 {
449 {
448 if (d_ptr->m_brush != brush) {
450 if (d_ptr->m_brush != brush) {
449 d_ptr->m_brush = brush;
451 d_ptr->m_brush = brush;
450 emit d_ptr->updatedBars();
452 emit d_ptr->updatedBars();
451 emit brushChanged();
453 emit brushChanged();
452 }
454 }
453 }
455 }
454
456
455 /*!
457 /*!
456 Returns brush of the set.
458 Returns brush of the set.
457 */
459 */
458 QBrush QBarSet::brush() const
460 QBrush QBarSet::brush() const
459 {
461 {
460 if (d_ptr->m_brush == QChartPrivate::defaultBrush())
462 if (d_ptr->m_brush == QChartPrivate::defaultBrush())
461 return QBrush();
463 return QBrush();
462 else
464 else
463 return d_ptr->m_brush;
465 return d_ptr->m_brush;
464 }
466 }
465
467
466 /*!
468 /*!
467 Sets \a brush of the values that are drawn on top of this bar set.
469 Sets \a brush of the values that are drawn on top of this bar set.
468 */
470 */
469 void QBarSet::setLabelBrush(const QBrush &brush)
471 void QBarSet::setLabelBrush(const QBrush &brush)
470 {
472 {
471 if (d_ptr->m_labelBrush != brush) {
473 if (d_ptr->m_labelBrush != brush) {
472 d_ptr->m_labelBrush = brush;
474 d_ptr->m_labelBrush = brush;
473 emit d_ptr->updatedBars();
475 emit d_ptr->updatedBars();
474 emit labelBrushChanged();
476 emit labelBrushChanged();
475 }
477 }
476 }
478 }
477
479
478 /*!
480 /*!
479 Returns brush of the values that are drawn on top of this bar set.
481 Returns brush of the values that are drawn on top of this bar set.
480 */
482 */
481 QBrush QBarSet::labelBrush() const
483 QBrush QBarSet::labelBrush() const
482 {
484 {
483 if (d_ptr->m_labelBrush == QChartPrivate::defaultBrush())
485 if (d_ptr->m_labelBrush == QChartPrivate::defaultBrush())
484 return QBrush();
486 return QBrush();
485 else
487 else
486 return d_ptr->m_labelBrush;
488 return d_ptr->m_labelBrush;
487 }
489 }
488
490
489 /*!
491 /*!
490 Sets the \a font for values that are drawn on top of this bar set.
492 Sets the \a font for values that are drawn on top of this bar set.
491 */
493 */
492 void QBarSet::setLabelFont(const QFont &font)
494 void QBarSet::setLabelFont(const QFont &font)
493 {
495 {
494 if (d_ptr->m_labelFont != font) {
496 if (d_ptr->m_labelFont != font) {
495 d_ptr->m_labelFont = font;
497 d_ptr->m_labelFont = font;
496 emit d_ptr->updatedBars();
498 emit d_ptr->updatedBars();
497 emit labelFontChanged();
499 emit labelFontChanged();
498 }
500 }
499
501
500 }
502 }
501
503
502 /*!
504 /*!
503 Returns the pen for values that are drawn on top of this bar set.
505 Returns the pen for values that are drawn on top of this bar set.
504 */
506 */
505 QFont QBarSet::labelFont() const
507 QFont QBarSet::labelFont() const
506 {
508 {
507 return d_ptr->m_labelFont;
509 return d_ptr->m_labelFont;
508 }
510 }
509
511
510 /*!
512 /*!
511 Returns the color of the brush of bar set.
513 Returns the color of the brush of bar set.
512 */
514 */
513 QColor QBarSet::color()
515 QColor QBarSet::color()
514 {
516 {
515 return brush().color();
517 return brush().color();
516 }
518 }
517
519
518 /*!
520 /*!
519 Sets the \a color of brush for this bar set.
521 Sets the \a color of brush for this bar set.
520 */
522 */
521 void QBarSet::setColor(QColor color)
523 void QBarSet::setColor(QColor color)
522 {
524 {
523 QBrush b = brush();
525 QBrush b = brush();
524 if ((b.color() != color) || (b.style() == Qt::NoBrush)) {
526 if ((b.color() != color) || (b.style() == Qt::NoBrush)) {
525 b.setColor(color);
527 b.setColor(color);
526 if (b.style() == Qt::NoBrush) {
528 if (b.style() == Qt::NoBrush) {
527 // Set tyle to Qt::SolidPattern. (Default is Qt::NoBrush)
529 // Set tyle to Qt::SolidPattern. (Default is Qt::NoBrush)
528 // This prevents theme to override color defined in QML side:
530 // This prevents theme to override color defined in QML side:
529 // BarSet { label: "Bob"; color:"red"; values: [1,2,3] }
531 // BarSet { label: "Bob"; color:"red"; values: [1,2,3] }
530 // The color must be obeyed, since user wanted it.
532 // The color must be obeyed, since user wanted it.
531 b.setStyle(Qt::SolidPattern);
533 b.setStyle(Qt::SolidPattern);
532 }
534 }
533 setBrush(b);
535 setBrush(b);
534 emit colorChanged(color);
536 emit colorChanged(color);
535 }
537 }
536 }
538 }
537
539
538 /*!
540 /*!
539 Returns the color of pen of this bar set.
541 Returns the color of pen of this bar set.
540 */
542 */
541 QColor QBarSet::borderColor()
543 QColor QBarSet::borderColor()
542 {
544 {
543 return pen().color();
545 return pen().color();
544 }
546 }
545
547
546 /*!
548 /*!
547 Sets the color of pen for this bar set.
549 Sets the color of pen for this bar set.
548 */
550 */
549 void QBarSet::setBorderColor(QColor color)
551 void QBarSet::setBorderColor(QColor color)
550 {
552 {
551 QPen p = pen();
553 QPen p = pen();
552 if (p.color() != color) {
554 if (p.color() != color) {
553 p.setColor(color);
555 p.setColor(color);
554 setPen(p);
556 setPen(p);
555 emit borderColorChanged(color);
557 emit borderColorChanged(color);
556 }
558 }
557 }
559 }
558
560
559 /*!
561 /*!
560 Returns the color of labels of this bar set.
562 Returns the color of labels of this bar set.
561 */
563 */
562 QColor QBarSet::labelColor()
564 QColor QBarSet::labelColor()
563 {
565 {
564 return labelBrush().color();
566 return labelBrush().color();
565 }
567 }
566
568
567 /*!
569 /*!
568 Sets the color of labels for this bar set.
570 Sets the color of labels for this bar set.
569 */
571 */
570 void QBarSet::setLabelColor(QColor color)
572 void QBarSet::setLabelColor(QColor color)
571 {
573 {
572 QBrush b = labelBrush();
574 QBrush b = labelBrush();
573 if (b == QBrush())
575 if (b == QBrush())
574 b.setStyle(Qt::SolidPattern);
576 b.setStyle(Qt::SolidPattern);
575
577
576 if (d_ptr->m_labelBrush.color() != color) {
578 if (d_ptr->m_labelBrush.color() != color) {
577 b.setColor(color);
579 b.setColor(color);
578 setLabelBrush(b);
580 setLabelBrush(b);
579 emit labelColorChanged(color);
581 emit labelColorChanged(color);
580 }
582 }
581 }
583 }
582
584
583 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
585 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
584
586
585 QBarSetPrivate::QBarSetPrivate(const QString label, QBarSet *parent) : QObject(parent),
587 QBarSetPrivate::QBarSetPrivate(const QString label, QBarSet *parent) : QObject(parent),
586 q_ptr(parent),
588 q_ptr(parent),
587 m_label(label),
589 m_label(label),
588 m_pen(QChartPrivate::defaultPen()),
590 m_pen(QChartPrivate::defaultPen()),
589 m_brush(QChartPrivate::defaultBrush()),
591 m_brush(QChartPrivate::defaultBrush()),
590 m_labelBrush(QChartPrivate::defaultBrush())
592 m_labelBrush(QChartPrivate::defaultBrush())
591 {
593 {
592 }
594 }
593
595
594 QBarSetPrivate::~QBarSetPrivate()
596 QBarSetPrivate::~QBarSetPrivate()
595 {
597 {
596 }
598 }
597
599
598 void QBarSetPrivate::append(QPointF value)
600 void QBarSetPrivate::append(QPointF value)
599 {
601 {
600 if (isValidValue(value)) {
602 if (isValidValue(value)) {
601 m_values.append(value);
603 m_values.append(value);
602 emit restructuredBars();
604 emit restructuredBars();
603 }
605 }
604 }
606 }
605
607
606 void QBarSetPrivate::append(QList<QPointF> values)
608 void QBarSetPrivate::append(QList<QPointF> values)
607 {
609 {
608 for (int i = 0; i < values.count(); i++) {
610 for (int i = 0; i < values.count(); i++) {
609 if (isValidValue(values.at(i)))
611 if (isValidValue(values.at(i)))
610 m_values.append(values.at(i));
612 m_values.append(values.at(i));
611 }
613 }
612 emit restructuredBars();
614 emit restructuredBars();
613 }
615 }
614
616
615 void QBarSetPrivate::append(QList<qreal> values)
617 void QBarSetPrivate::append(QList<qreal> values)
616 {
618 {
617 int index = m_values.count();
619 int index = m_values.count();
618 for (int i = 0; i < values.count(); i++) {
620 for (int i = 0; i < values.count(); i++) {
619 if (isValidValue(values.at(i))) {
621 if (isValidValue(values.at(i))) {
620 m_values.append(QPointF(index, values.at(i)));
622 m_values.append(QPointF(index, values.at(i)));
621 index++;
623 index++;
622 }
624 }
623 }
625 }
624 emit restructuredBars();
626 emit restructuredBars();
625 }
627 }
626
628
627 void QBarSetPrivate::insert(const int index, const qreal value)
629 void QBarSetPrivate::insert(const int index, const qreal value)
628 {
630 {
629 m_values.insert(index, QPointF(index, value));
631 m_values.insert(index, QPointF(index, value));
630 emit restructuredBars();
632 emit restructuredBars();
631 }
633 }
632
634
633 void QBarSetPrivate::insert(const int index, const QPointF value)
635 void QBarSetPrivate::insert(const int index, const QPointF value)
634 {
636 {
635 m_values.insert(index, value);
637 m_values.insert(index, value);
636 emit restructuredBars();
638 emit restructuredBars();
637 }
639 }
638
640
639 int QBarSetPrivate::remove(const int index, const int count)
641 int QBarSetPrivate::remove(const int index, const int count)
640 {
642 {
641 int removeCount = count;
643 int removeCount = count;
642
644
643 if ((index < 0) || (m_values.count() == 0))
645 if ((index < 0) || (m_values.count() == 0))
644 return 0; // Invalid index or not values in list, remove nothing.
646 return 0; // Invalid index or not values in list, remove nothing.
645 else if ((index + count) > m_values.count())
647 else if ((index + count) > m_values.count())
646 removeCount = m_values.count() - index; // Trying to remove more items than list has. Limit amount to be removed.
648 removeCount = m_values.count() - index; // Trying to remove more items than list has. Limit amount to be removed.
647
649
648 int c = 0;
650 int c = 0;
649 while (c < removeCount) {
651 while (c < removeCount) {
650 m_values.removeAt(index);
652 m_values.removeAt(index);
651 c++;
653 c++;
652 }
654 }
653 emit restructuredBars();
655 emit restructuredBars();
654 return removeCount;
656 return removeCount;
655 }
657 }
656
658
657 void QBarSetPrivate::replace(const int index, const qreal value)
659 void QBarSetPrivate::replace(const int index, const qreal value)
658 {
660 {
659 m_values.replace(index, QPointF(index, value));
661 m_values.replace(index, QPointF(index, value));
660 emit updatedLayout();
662 emit updatedLayout();
661 }
663 }
662
664
663 void QBarSetPrivate::replace(const int index, const QPointF value)
665 void QBarSetPrivate::replace(const int index, const QPointF value)
664 {
666 {
665 m_values.replace(index, value);
667 m_values.replace(index, value);
666 emit updatedLayout();
668 emit updatedLayout();
667 }
669 }
668
670
669 qreal QBarSetPrivate::pos(const int index)
671 qreal QBarSetPrivate::pos(const int index)
670 {
672 {
671 if (index < 0 || index >= m_values.count())
673 if (index < 0 || index >= m_values.count())
672 return 0;
674 return 0;
673 return m_values.at(index).x();
675 return m_values.at(index).x();
674 }
676 }
675
677
676 qreal QBarSetPrivate::value(const int index)
678 qreal QBarSetPrivate::value(const int index)
677 {
679 {
678 if (index < 0 || index >= m_values.count())
680 if (index < 0 || index >= m_values.count())
679 return 0;
681 return 0;
680 return m_values.at(index).y();
682 return m_values.at(index).y();
681 }
683 }
682
684
683 #include "moc_qbarset.cpp"
685 #include "moc_qbarset.cpp"
684 #include "moc_qbarset_p.cpp"
686 #include "moc_qbarset_p.cpp"
685
687
686 QT_CHARTS_END_NAMESPACE
688 QT_CHARTS_END_NAMESPACE
@@ -1,152 +1,157
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd
3 ** Copyright (C) 2015 The Qt Company Ltd
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 **
6 **
7 ** This file is part of the Qt Charts module.
7 ** This file is part of the Qt Charts module.
8 **
8 **
9 ** Licensees holding valid commercial license for Qt may use this file in
9 ** Licensees holding valid commercial license for Qt may use this file in
10 ** accordance with the Qt License Agreement provided with the Software
10 ** accordance with the Qt License Agreement provided with the Software
11 ** or, alternatively, in accordance with the terms contained in a written
11 ** or, alternatively, in accordance with the terms contained in a written
12 ** agreement between you and The Qt Company.
12 ** agreement between you and The Qt Company.
13 **
13 **
14 ** If you have questions regarding the use of this file, please use
14 ** If you have questions regarding the use of this file, please use
15 ** contact form at http://qt.io
15 ** contact form at http://qt.io
16 **
16 **
17 ****************************************************************************/
17 ****************************************************************************/
18
18
19 #include <private/percentbarchartitem_p.h>
19 #include <private/percentbarchartitem_p.h>
20 #include <private/bar_p.h>
20 #include <private/bar_p.h>
21 #include <private/qabstractbarseries_p.h>
21 #include <private/qabstractbarseries_p.h>
22 #include <QtCharts/QBarSet>
22 #include <QtCharts/QBarSet>
23 #include <private/qbarset_p.h>
23 #include <private/qbarset_p.h>
24
24
25 QT_CHARTS_BEGIN_NAMESPACE
25 QT_CHARTS_BEGIN_NAMESPACE
26
26
27 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
27 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
28 AbstractBarChartItem(series, item)
28 AbstractBarChartItem(series, item)
29 {
29 {
30 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
30 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
31 this, SLOT(handleLabelsPositionChanged()));
31 this, SLOT(handleLabelsPositionChanged()));
32 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
32 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
33 }
33 }
34
34
35 void PercentBarChartItem::initializeLayout()
35 void PercentBarChartItem::initializeLayout()
36 {
36 {
37 qreal categoryCount = m_series->d_func()->categoryCount();
37 qreal categoryCount = m_series->d_func()->categoryCount();
38 qreal setCount = m_series->count();
38 qreal setCount = m_series->count();
39 qreal barWidth = m_series->d_func()->barWidth();
39 qreal barWidth = m_series->d_func()->barWidth();
40
40
41 m_layout.clear();
41 m_layout.clear();
42 for(int category = 0; category < categoryCount; category++) {
42 for(int category = 0; category < categoryCount; category++) {
43 for (int set = 0; set < setCount; set++) {
43 for (int set = 0; set < setCount; set++) {
44 QRectF rect;
44 QRectF rect;
45 QPointF topLeft;
45 QPointF topLeft;
46 QPointF bottomRight;
46 QPointF bottomRight;
47
47
48 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
48 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
49 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
49 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
51 } else {
51 } else {
52 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
52 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
53 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
53 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
54 }
54 }
55
55
56 if (!m_validData)
56 if (!m_validData)
57 return;
57 return;
58
58
59 rect.setTopLeft(topLeft);
59 rect.setTopLeft(topLeft);
60 rect.setBottomRight(bottomRight);
60 rect.setBottomRight(bottomRight);
61 m_layout.append(rect.normalized());
61 m_layout.append(rect.normalized());
62 }
62 }
63 }
63 }
64 }
64 }
65
65
66 QVector<QRectF> PercentBarChartItem::calculateLayout()
66 QVector<QRectF> PercentBarChartItem::calculateLayout()
67 {
67 {
68 QVector<QRectF> layout;
68 QVector<QRectF> layout;
69
69
70 // Use temporary qreals for accuracy
70 // Use temporary qreals for accuracy
71 qreal categoryCount = m_series->d_func()->categoryCount();
71 qreal categoryCount = m_series->d_func()->categoryCount();
72 qreal setCount = m_series->count();
72 qreal setCount = m_series->count();
73 qreal barWidth = m_series->d_func()->barWidth();
73 qreal barWidth = m_series->d_func()->barWidth();
74
74
75 for(int category = 0; category < categoryCount; category++) {
75 for(int category = 0; category < categoryCount; category++) {
76 qreal sum = 0;
76 qreal sum = 0;
77 qreal categorySum = m_series->d_func()->categorySum(category);
77 qreal categorySum = m_series->d_func()->categorySum(category);
78 for (int set = 0; set < setCount; set++) {
78 for (int set = 0; set < setCount; set++) {
79 qreal value = m_series->barSets().at(set)->at(category);
79 qreal value = m_series->barSets().at(set)->at(category);
80 QRectF rect;
80 QRectF rect;
81 qreal topY = 0;
81 qreal topY = 0;
82 qreal newSum = value + sum;
82 qreal newSum = value + sum;
83 if (newSum > 0)
83 if (newSum > 0)
84 topY = 100 * newSum / categorySum;
84 topY = 100 * newSum / categorySum;
85 qreal bottomY = 0;
85 qreal bottomY = 0;
86 if (sum > 0)
86 if (sum > 0)
87 bottomY = 100 * sum / categorySum;
87 bottomY = 100 * sum / categorySum;
88 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
88 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
89 QPointF bottomRight;
89 QPointF bottomRight;
90 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
90 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
91 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
91 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
92 else
92 else
93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
94
94
95 rect.setTopLeft(topLeft);
95 rect.setTopLeft(topLeft);
96 rect.setBottomRight(bottomRight);
96 rect.setBottomRight(bottomRight);
97 layout.append(rect.normalized());
97 layout.append(rect.normalized());
98 sum = newSum;
98 sum = newSum;
99 }
99 }
100 }
100 }
101 return layout;
101 return layout;
102 }
102 }
103
103
104 void PercentBarChartItem::handleUpdatedBars()
104 void PercentBarChartItem::handleUpdatedBars()
105 {
105 {
106 // Handle changes in pen, brush, labels etc.
106 // Handle changes in pen, brush, labels etc.
107 int categoryCount = m_series->d_func()->categoryCount();
107 int categoryCount = m_series->d_func()->categoryCount();
108 int setCount = m_series->count();
108 int setCount = m_series->count();
109 int itemIndex(0);
109 int itemIndex(0);
110 static const QString valueTag(QLatin1String("@value"));
110 static const QString valueTag(QLatin1String("@value"));
111
111
112 for (int category = 0; category < categoryCount; category++) {
112 for (int category = 0; category < categoryCount; category++) {
113 for (int set = 0; set < setCount; set++) {
113 for (int set = 0; set < setCount; set++) {
114 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
114 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
115 Bar *bar = m_bars.at(itemIndex);
115 Bar *bar = m_bars.at(itemIndex);
116 bar->setPen(barSet->m_pen);
116 bar->setPen(barSet->m_pen);
117 bar->setBrush(barSet->m_brush);
117 bar->setBrush(barSet->m_brush);
118 bar->update();
118 bar->update();
119
119
120 QGraphicsTextItem *label = m_labels.at(itemIndex);
120 QGraphicsTextItem *label = m_labels.at(itemIndex);
121 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
121 qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
122 QString vString(presenter()->numberToString(p, 'f', 0));
122 QString vString(presenter()->numberToString(p, 'f', 0));
123 QString valueLabel;
123 QString valueLabel;
124 if (m_series->labelsFormat().isEmpty()) {
124 if (p == 0) {
125 vString.append(QStringLiteral("%"));
125 label->setVisible(false);
126 valueLabel = vString;
127 } else {
126 } else {
128 valueLabel = m_series->labelsFormat();
127 label->setVisible(true);
129 valueLabel.replace(valueTag, vString);
128 if (m_series->labelsFormat().isEmpty()) {
129 vString.append(QStringLiteral("%"));
130 valueLabel = vString;
131 } else {
132 valueLabel = m_series->labelsFormat();
133 valueLabel.replace(valueTag, vString);
134 }
130 }
135 }
131 label->setHtml(valueLabel);
136 label->setHtml(valueLabel);
132 label->setFont(barSet->m_labelFont);
137 label->setFont(barSet->m_labelFont);
133 label->setDefaultTextColor(barSet->m_labelBrush.color());
138 label->setDefaultTextColor(barSet->m_labelBrush.color());
134 label->update();
139 label->update();
135 itemIndex++;
140 itemIndex++;
136 }
141 }
137 }
142 }
138 }
143 }
139
144
140 void PercentBarChartItem::handleLabelsPositionChanged()
145 void PercentBarChartItem::handleLabelsPositionChanged()
141 {
146 {
142 positionLabels();
147 positionLabels();
143 }
148 }
144
149
145 void PercentBarChartItem::positionLabels()
150 void PercentBarChartItem::positionLabels()
146 {
151 {
147 positionLabelsVertical();
152 positionLabelsVertical();
148 }
153 }
149
154
150 #include "moc_percentbarchartitem_p.cpp"
155 #include "moc_percentbarchartitem_p.cpp"
151
156
152 QT_CHARTS_END_NAMESPACE
157 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now