##// END OF EJS Templates
Added support for bar series value label angle...
Miikka Heikkinen -
r2802:458692a5a594
parent child
Show More
@@ -51,6 +51,7 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphics
51 51 connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
52 52 connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
53 53 this, SLOT(handleLabelsPositionChanged()));
54 connect(series, SIGNAL(labelsAngleChanged(qreal)), this, SLOT(positionLabels()));
54 55 setZValue(ChartPresenter::BarSeriesZValue);
55 56 handleDataStructureChanged();
56 57 handleVisibleChanged();
@@ -249,20 +250,101 void AbstractBarChartItem::handleLabelsPositionChanged()
249 250
250 251 void AbstractBarChartItem::positionLabels()
251 252 {
253 // By default position labels on horizontal bar series
254 // Vertical bar series overload positionLabels() to call positionLabelsVertical()
255
256 QTransform transform;
257 const qreal angle = m_series->d_func()->labelsAngle();
258 if (angle != 0.0)
259 transform.rotate(angle);
260
252 261 for (int i = 0; i < m_layout.count(); i++) {
253 262 QGraphicsTextItem *label = m_labels.at(i);
263
264 QRectF labelRect = label->boundingRect();
265 QPointF center = labelRect.center();
266
254 267 qreal xPos = 0;
255 qreal yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
268 qreal yPos = m_layout.at(i).center().y() - center.y();
269
270 int xDiff = 0;
271 if (angle != 0.0) {
272 label->setTransformOriginPoint(center.x(), center.y());
273 label->setRotation(m_series->d_func()->labelsAngle());
274 qreal oldWidth = labelRect.width();
275 labelRect = transform.mapRect(labelRect);
276 xDiff = (labelRect.width() - oldWidth) / 2;
277 }
256 278
257 279 int offset = m_bars.at(i)->pen().width() / 2 + 2;
258 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
259 xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
260 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
261 xPos = m_layout.at(i).right() - label->boundingRect().width() - offset;
262 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
263 xPos = m_layout.at(i).left() + offset;
264 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
265 xPos = m_layout.at(i).right() + offset;
280
281 switch (m_series->labelsPosition()) {
282 case QAbstractBarSeries::LabelsCenter:
283 xPos = m_layout.at(i).center().x() - center.x();
284 break;
285 case QAbstractBarSeries::LabelsInsideEnd:
286 xPos = m_layout.at(i).right() - labelRect.width() - offset + xDiff;
287 break;
288 case QAbstractBarSeries::LabelsInsideBase:
289 xPos = m_layout.at(i).left() + offset + xDiff;
290 break;
291 case QAbstractBarSeries::LabelsOutsideEnd:
292 xPos = m_layout.at(i).right() + offset + xDiff;
293 break;
294 default:
295 // Invalid position, never comes here
296 break;
297 }
298
299 label->setPos(xPos, yPos);
300 label->setZValue(zValue() + 1);
301 }
302 }
303
304 void AbstractBarChartItem::positionLabelsVertical()
305 {
306 QTransform transform;
307 const qreal angle = m_series->d_func()->labelsAngle();
308 if (angle != 0.0)
309 transform.rotate(angle);
310
311 for (int i = 0; i < m_layout.count(); i++) {
312 QGraphicsTextItem *label = m_labels.at(i);
313
314 QRectF labelRect = label->boundingRect();
315 QPointF center = labelRect.center();
316
317 qreal xPos = m_layout.at(i).center().x() - center.x();
318 qreal yPos = 0;
319
320 int yDiff = 0;
321 if (angle != 0.0) {
322 label->setTransformOriginPoint(center.x(), center.y());
323 label->setRotation(m_series->d_func()->labelsAngle());
324 qreal oldHeight = labelRect.height();
325 labelRect = transform.mapRect(labelRect);
326 yDiff = (labelRect.height() - oldHeight) / 2;
327 }
328
329 int offset = m_bars.at(i)->pen().width() / 2 + 2;
330
331 switch (m_series->labelsPosition()) {
332 case QAbstractBarSeries::LabelsCenter:
333 yPos = m_layout.at(i).center().y() - center.y();
334 break;
335 case QAbstractBarSeries::LabelsInsideEnd:
336 yPos = m_layout.at(i).top() + offset + yDiff;
337 break;
338 case QAbstractBarSeries::LabelsInsideBase:
339 yPos = m_layout.at(i).bottom() - labelRect.height() - offset + yDiff;
340 break;
341 case QAbstractBarSeries::LabelsOutsideEnd:
342 yPos = m_layout.at(i).top() - labelRect.height() - offset + yDiff;
343 break;
344 default:
345 // Invalid position, never comes here
346 break;
347 }
266 348
267 349 label->setPos(xPos, yPos);
268 350 label->setZValue(zValue() + 1);
@@ -72,6 +72,7 public Q_SLOTS:
72 72 virtual void positionLabels();
73 73
74 74 protected:
75 void positionLabelsVertical();
75 76
76 77 qreal m_domainMinX;
77 78 qreal m_domainMaxX;
@@ -197,6 +197,23 QT_CHARTS_BEGIN_NAMESPACE
197 197 */
198 198
199 199 /*!
200 \property QAbstractBarSeries::labelsAngle
201 The angle of the value labels in degrees.
202 */
203 /*!
204 \qmlproperty qreal QAbstractBarSeries::labelsAngle
205 The angle of the value labels in degrees.
206 */
207 /*!
208 \fn void QAbstractBarSeries::labelsAngleChanged(qreal angle)
209 Signal is emitted when the \a angle of the value labels is changed.
210 */
211 /*!
212 \qmlsignal AbstractBarSeries::onLabelsAngleChanged(qreal angle)
213 Signal is emitted when the \a angle of the value labels is changed.
214 */
215
216 /*!
200 217 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
201 218 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
202 219 Clicked bar inside set is indexed by \a index
@@ -531,6 +548,21 QString QAbstractBarSeries::labelsFormat() const
531 548 return d->m_labelsFormat;
532 549 }
533 550
551 void QAbstractBarSeries::setLabelsAngle(qreal angle)
552 {
553 Q_D(QAbstractBarSeries);
554 if (d->m_labelsAngle != angle) {
555 d->m_labelsAngle = angle;
556 emit labelsAngleChanged(angle);
557 }
558 }
559
560 qreal QAbstractBarSeries::labelsAngle() const
561 {
562 Q_D(const QAbstractBarSeries);
563 return d->m_labelsAngle;
564 }
565
534 566 void QAbstractBarSeries::setLabelsPosition(QAbstractBarSeries::LabelsPosition position)
535 567 {
536 568 Q_D(QAbstractBarSeries);
@@ -555,7 +587,8 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
555 587 m_visible(true),
556 588 m_blockBarUpdate(false),
557 589 m_labelsFormat(),
558 m_labelsPosition(QAbstractBarSeries::LabelsCenter)
590 m_labelsPosition(QAbstractBarSeries::LabelsCenter),
591 m_labelsAngle(0)
559 592 {
560 593 }
561 594
@@ -799,6 +832,11 bool QAbstractBarSeriesPrivate::blockBarUpdate()
799 832 return m_blockBarUpdate;
800 833 }
801 834
835 qreal QAbstractBarSeriesPrivate::labelsAngle() const
836 {
837 return m_labelsAngle;
838 }
839
802 840 void QAbstractBarSeriesPrivate::initializeDomain()
803 841 {
804 842 qreal minX(domain()->minX());
@@ -36,6 +36,7 class QT_CHARTS_EXPORT QAbstractBarSeries : public QAbstractSeries
36 36 Q_PROPERTY(bool labelsVisible READ isLabelsVisible WRITE setLabelsVisible NOTIFY labelsVisibleChanged)
37 37 Q_PROPERTY(QString labelsFormat READ labelsFormat WRITE setLabelsFormat NOTIFY labelsFormatChanged)
38 38 Q_PROPERTY(LabelsPosition labelsPosition READ labelsPosition WRITE setLabelsPosition NOTIFY labelsPositionChanged)
39 Q_PROPERTY(qreal labelsAngle READ labelsAngle WRITE setLabelsAngle NOTIFY labelsAngleChanged)
39 40 Q_ENUMS(LabelsPosition)
40 41
41 42 public:
@@ -67,6 +68,9 public:
67 68 void setLabelsFormat(const QString &format);
68 69 QString labelsFormat() const;
69 70
71 void setLabelsAngle(qreal angle);
72 qreal labelsAngle() const;
73
70 74 void setLabelsPosition(QAbstractBarSeries::LabelsPosition position);
71 75 QAbstractBarSeries::LabelsPosition labelsPosition() const;
72 76
@@ -83,6 +87,7 Q_SIGNALS:
83 87 void labelsVisibleChanged();
84 88 void labelsFormatChanged(const QString &format);
85 89 void labelsPositionChanged(QAbstractBarSeries::LabelsPosition position);
90 void labelsAngleChanged(qreal angle);
86 91
87 92 void barsetsAdded(QList<QBarSet *> sets);
88 93 void barsetsRemoved(QList<QBarSet *> sets);
@@ -85,6 +85,8 public:
85 85
86 86 bool blockBarUpdate();
87 87
88 qreal labelsAngle() const;
89
88 90 Q_SIGNALS:
89 91 void clicked(int index, QBarSet *barset);
90 92 void pressed(int index, QBarSet *barset);
@@ -107,6 +109,7 protected:
107 109 bool m_blockBarUpdate;
108 110 QString m_labelsFormat;
109 111 QAbstractBarSeries::LabelsPosition m_labelsPosition;
112 qreal m_labelsAngle;
110 113
111 114 private:
112 115 Q_DECLARE_PUBLIC(QAbstractBarSeries)
@@ -98,24 +98,7 void BarChartItem::handleLabelsPositionChanged()
98 98
99 99 void BarChartItem::positionLabels()
100 100 {
101 for (int i = 0; i < m_layout.count(); i++) {
102 QGraphicsTextItem *label = m_labels.at(i);
103 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
104 qreal yPos = 0;
105
106 int offset = m_bars.at(i)->pen().width() / 2 + 2;
107 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
108 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
109 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
110 yPos = m_layout.at(i).top() - offset;
111 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
112 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
113 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
114 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
115
116 label->setPos(xPos, yPos);
117 label->setZValue(zValue() + 1);
118 }
101 positionLabelsVertical();
119 102 }
120 103
121 104 #include "moc_barchartitem_p.cpp"
@@ -144,24 +144,7 void PercentBarChartItem::handleLabelsPositionChanged()
144 144
145 145 void PercentBarChartItem::positionLabels()
146 146 {
147 for (int i = 0; i < m_layout.count(); i++) {
148 QGraphicsTextItem *label = m_labels.at(i);
149 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
150 qreal yPos = 0;
151
152 int offset = m_bars.at(i)->pen().width() / 2 + 2;
153 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
154 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
155 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
156 yPos = m_layout.at(i).top() - offset;
157 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
158 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
159 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
160 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
161
162 label->setPos(xPos, yPos);
163 label->setZValue(zValue() + 1);
164 }
147 positionLabelsVertical();
165 148 }
166 149
167 150 #include "moc_percentbarchartitem_p.cpp"
@@ -110,24 +110,7 void StackedBarChartItem::handleLabelsPositionChanged()
110 110
111 111 void StackedBarChartItem::positionLabels()
112 112 {
113 for (int i = 0; i < m_layout.count(); i++) {
114 QGraphicsTextItem *label = m_labels.at(i);
115 qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
116 qreal yPos = 0;
117
118 int offset = m_bars.at(i)->pen().width() / 2 + 2;
119 if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
120 yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
121 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
122 yPos = m_layout.at(i).top() - offset;
123 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
124 yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
125 else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
126 yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
127
128 label->setPos(xPos, yPos);
129 label->setZValue(zValue() + 1);
130 }
113 positionLabelsVertical();
131 114 }
132 115
133 116 #include "moc_stackedbarchartitem_p.cpp"
@@ -60,6 +60,7 private slots:
60 60 void setLabelsVisible();
61 61 void setLabelsFormat();
62 62 void setLabelsPosition();
63 void setLabelsAngle();
63 64 void opacity();
64 65 void mouseclicked_data();
65 66 void mouseclicked();
@@ -405,6 +406,19 void tst_QBarSeries::setLabelsPosition()
405 406 QCOMPARE(m_barseries->labelsPosition(), QBarSeries::LabelsCenter);
406 407 }
407 408
409 void tst_QBarSeries::setLabelsAngle()
410 {
411 QSignalSpy labelsAngleSpy(m_barseries,
412 SIGNAL(labelsAngleChanged(qreal)));
413 QCOMPARE(m_barseries->labelsAngle(), 0.0);
414
415 m_barseries->setLabelsAngle(55.0);
416 TRY_COMPARE(labelsAngleSpy.count(), 1);
417 QList<QVariant> arguments = labelsAngleSpy.takeFirst();
418 QVERIFY(arguments.at(0).value<qreal>() == 55.0);
419 QCOMPARE(m_barseries->labelsAngle(), 55.0);
420 }
421
408 422 void tst_QBarSeries::opacity()
409 423 {
410 424 QSignalSpy opacitySpy(m_barseries, SIGNAL(opacityChanged()));
@@ -57,6 +57,7 private slots:
57 57 void setLabelsVisible();
58 58 void setLabelsFormat();
59 59 void setLabelsPosition();
60 void setLabelsAngle();
60 61 void mouseclicked_data();
61 62 void mouseclicked();
62 63 void mousehovered_data();
@@ -370,6 +371,19 void tst_QHorizontalBarSeries::setLabelsPosition()
370 371 QCOMPARE(m_barseries->labelsPosition(), QHorizontalBarSeries::LabelsCenter);
371 372 }
372 373
374 void tst_QHorizontalBarSeries::setLabelsAngle()
375 {
376 QSignalSpy labelsAngleSpy(m_barseries,
377 SIGNAL(labelsAngleChanged(qreal)));
378 QCOMPARE(m_barseries->labelsAngle(), 0.0);
379
380 m_barseries->setLabelsAngle(55.0);
381 TRY_COMPARE(labelsAngleSpy.count(), 1);
382 QList<QVariant> arguments = labelsAngleSpy.takeFirst();
383 QVERIFY(arguments.at(0).value<qreal>() == 55.0);
384 QCOMPARE(m_barseries->labelsAngle(), 55.0);
385 }
386
373 387 void tst_QHorizontalBarSeries::mouseclicked_data()
374 388 {
375 389
@@ -45,6 +45,7 private slots:
45 45 void type();
46 46 void setLabelsFormat();
47 47 void setLabelsPosition();
48 void setLabelsAngle();
48 49 void mouseclicked_data();
49 50 void mouseclicked();
50 51 void mousehovered_data();
@@ -155,6 +156,19 void tst_QHorizontalPercentBarSeries::setLabelsPosition()
155 156 QCOMPARE(m_barseries->labelsPosition(), QHorizontalPercentBarSeries::LabelsCenter);
156 157 }
157 158
159 void tst_QHorizontalPercentBarSeries::setLabelsAngle()
160 {
161 QSignalSpy labelsAngleSpy(m_barseries,
162 SIGNAL(labelsAngleChanged(qreal)));
163 QCOMPARE(m_barseries->labelsAngle(), 0.0);
164
165 m_barseries->setLabelsAngle(55.0);
166 TRY_COMPARE(labelsAngleSpy.count(), 1);
167 QList<QVariant> arguments = labelsAngleSpy.takeFirst();
168 QVERIFY(arguments.at(0).value<qreal>() == 55.0);
169 QCOMPARE(m_barseries->labelsAngle(), 55.0);
170 }
171
158 172 void tst_QHorizontalPercentBarSeries::mouseclicked_data()
159 173 {
160 174
@@ -45,6 +45,7 private slots:
45 45 void type();
46 46 void setLabelsFormat();
47 47 void setLabelsPosition();
48 void setLabelsAngle();
48 49 void mouseclicked_data();
49 50 void mouseclicked();
50 51 void mousehovered_data();
@@ -154,6 +155,19 void tst_QHorizontalStackedBarSeries::setLabelsPosition()
154 155 QCOMPARE(m_barseries->labelsPosition(), QHorizontalStackedBarSeries::LabelsCenter);
155 156 }
156 157
158 void tst_QHorizontalStackedBarSeries::setLabelsAngle()
159 {
160 QSignalSpy labelsAngleSpy(m_barseries,
161 SIGNAL(labelsAngleChanged(qreal)));
162 QCOMPARE(m_barseries->labelsAngle(), 0.0);
163
164 m_barseries->setLabelsAngle(55.0);
165 TRY_COMPARE(labelsAngleSpy.count(), 1);
166 QList<QVariant> arguments = labelsAngleSpy.takeFirst();
167 QVERIFY(arguments.at(0).value<qreal>() == 55.0);
168 QCOMPARE(m_barseries->labelsAngle(), 55.0);
169 }
170
157 171 void tst_QHorizontalStackedBarSeries::mouseclicked_data()
158 172 {
159 173
@@ -45,6 +45,7 private slots:
45 45 void type();
46 46 void setLabelsFormat();
47 47 void setLabelsPosition();
48 void setLabelsAngle();
48 49 void mouseclicked_data();
49 50 void mouseclicked();
50 51 void mousehovered_data();
@@ -160,6 +161,19 void tst_QPercentBarSeries::setLabelsPosition()
160 161 QCOMPARE(m_barseries->labelsPosition(), QPercentBarSeries::LabelsCenter);
161 162 }
162 163
164 void tst_QPercentBarSeries::setLabelsAngle()
165 {
166 QSignalSpy labelsAngleSpy(m_barseries,
167 SIGNAL(labelsAngleChanged(qreal)));
168 QCOMPARE(m_barseries->labelsAngle(), 0.0);
169
170 m_barseries->setLabelsAngle(55.0);
171 TRY_COMPARE(labelsAngleSpy.count(), 1);
172 QList<QVariant> arguments = labelsAngleSpy.takeFirst();
173 QVERIFY(arguments.at(0).value<qreal>() == 55.0);
174 QCOMPARE(m_barseries->labelsAngle(), 55.0);
175 }
176
163 177 void tst_QPercentBarSeries::mouseclicked()
164 178 {
165 179 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
@@ -45,6 +45,7 private slots:
45 45 void type();
46 46 void setLabelsFormat();
47 47 void setLabelsPosition();
48 void setLabelsAngle();
48 49 void mouseclicked_data();
49 50 void mouseclicked();
50 51 void mousehovered_data();
@@ -154,6 +155,19 void tst_QStackedBarSeries::setLabelsPosition()
154 155 QCOMPARE(m_barseries->labelsPosition(), QStackedBarSeries::LabelsCenter);
155 156 }
156 157
158 void tst_QStackedBarSeries::setLabelsAngle()
159 {
160 QSignalSpy labelsAngleSpy(m_barseries,
161 SIGNAL(labelsAngleChanged(qreal)));
162 QCOMPARE(m_barseries->labelsAngle(), 0.0);
163
164 m_barseries->setLabelsAngle(55.0);
165 TRY_COMPARE(labelsAngleSpy.count(), 1);
166 QList<QVariant> arguments = labelsAngleSpy.takeFirst();
167 QVERIFY(arguments.at(0).value<qreal>() == 55.0);
168 QCOMPARE(m_barseries->labelsAngle(), 55.0);
169 }
170
157 171 void tst_QStackedBarSeries::mouseclicked_data()
158 172 {
159 173
@@ -186,6 +186,14 Row {
186 186 text: "set 1 label color"
187 187 onClicked: series.at(0).labelColor = main.nextColor();
188 188 }
189 Button {
190 text: "labels angle +"
191 onClicked: series.labelsAngle = series.labelsAngle + 5;
192 }
193 Button {
194 text: "labels angle -"
195 onClicked: series.labelsAngle = series.labelsAngle - 5;
196 }
189 197 FontEditor {
190 198 id: fontEditor
191 199 fontDescription: "label"
General Comments 0
You need to be logged in to leave comments. Login now