##// END OF EJS Templates
Added possibility to set labels position for QCategoryAxis...
Titta Heikkala -
r2780:740f4f94adf8
parent child
Show More
@@ -99,6 +99,25 QT_CHARTS_BEGIN_NAMESPACE
99 99 Axis emits signal when the categories of the axis have changed.
100 100 */
101 101
102 /*!
103 \enum QCategoryAxis::AxisLabelsPosition
104
105 This enum describes the position of the category labels.
106
107 \value AxisLabelsPositionCenter Labels are centered to category.
108 \value AxisLabelsPositionOnValue Labels are positioned to the high end limit of the category.
109 */
110 /*!
111 \property QCategoryAxis::labelsPosition
112 Defines the position of the category labels. The labels in the beginning and in the end of the
113 axes may overlap other axes labels when positioned on value.
114 */
115 /*!
116 \qmlproperty AxisLabelsPosition CategoryAxis::labelsPosition
117 Defines the position of the category labels. The labels in the beginning and in the end of the
118 axes may overlap other axes labels when positioned on value.
119 */
120
102 121
103 122 /*!
104 123 Constructs an axis object which is a child of \a parent.
@@ -284,11 +303,27 QAbstractAxis::AxisType QCategoryAxis::type() const
284 303 return QAbstractAxis::AxisTypeCategory;
285 304 }
286 305
306 void QCategoryAxis::setLabelsPosition(QCategoryAxis::AxisLabelsPosition position)
307 {
308 Q_D(QCategoryAxis);
309 if (d->m_labelsPosition != position) {
310 d->m_labelsPosition = position;
311 emit labelsPositionChanged(position);
312 }
313 }
314
315 QCategoryAxis::AxisLabelsPosition QCategoryAxis::labelsPosition() const
316 {
317 Q_D(const QCategoryAxis);
318 return d->m_labelsPosition;
319 }
320
287 321 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288 322
289 323 QCategoryAxisPrivate::QCategoryAxisPrivate(QCategoryAxis *q)
290 324 : QValueAxisPrivate(q),
291 m_categoryMinimum(0)
325 m_categoryMinimum(0),
326 m_labelsPosition(QCategoryAxis::AxisLabelsPositionCenter)
292 327 {
293 328
294 329 }
@@ -32,8 +32,16 class QT_CHARTS_EXPORT QCategoryAxis : public QValueAxis
32 32 Q_PROPERTY(qreal startValue READ startValue WRITE setStartValue)
33 33 Q_PROPERTY(int count READ count)
34 34 Q_PROPERTY(QStringList categoriesLabels READ categoriesLabels)
35 Q_PROPERTY(AxisLabelsPosition labelsPosition READ labelsPosition WRITE setLabelsPosition NOTIFY labelsPositionChanged)
36 Q_ENUMS(AxisLabelsPosition)
35 37
36 38 public:
39
40 enum AxisLabelsPosition {
41 AxisLabelsPositionCenter = 0x0,
42 AxisLabelsPositionOnValue = 0x1
43 };
44
37 45 explicit QCategoryAxis(QObject *parent = 0);
38 46 ~QCategoryAxis();
39 47
@@ -55,8 +63,12 public:
55 63 QStringList categoriesLabels();
56 64 int count() const;
57 65
66 QCategoryAxis::AxisLabelsPosition labelsPosition() const;
67 void setLabelsPosition(QCategoryAxis::AxisLabelsPosition position);
68
58 69 Q_SIGNALS:
59 70 void categoriesChanged();
71 void labelsPositionChanged(QCategoryAxis::AxisLabelsPosition position);
60 72
61 73 private:
62 74 Q_DECLARE_PRIVATE(QCategoryAxis)
@@ -50,6 +50,7 private:
50 50 QMap<QString , Range> m_categoriesMap;
51 51 QStringList m_categories;
52 52 qreal m_categoryMinimum;
53 QCategoryAxis::AxisLabelsPosition m_labelsPosition;
53 54
54 55 private:
55 56 Q_DECLARE_PUBLIC(QCategoryAxis)
@@ -19,6 +19,7
19 19 #include <private/horizontalaxis_p.h>
20 20 #include <private/qabstractaxis_p.h>
21 21 #include <private/chartpresenter_p.h>
22 #include <QtCharts/QCategoryAxis>
22 23 #include <QtCore/QtMath>
23 24 #include <QtCore/QDebug>
24 25
@@ -142,12 +143,28 void HorizontalAxis::updateGeometry()
142 143 qreal leftBound = qMax(layout[i], gridRect.left());
143 144 qreal rightBound = qMin(layout[i + 1], gridRect.right());
144 145 const qreal delta = rightBound - leftBound;
145 // Hide label in case visible part of the category at the grid edge is too narrow
146 if (delta < boundingRect.width()
147 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
148 forceHide = true;
146 if (axis()->type() != QAbstractAxis::AxisTypeCategory) {
147 // Hide label in case visible part of the category at the grid edge is too narrow
148 if (delta < boundingRect.width()
149 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
150 forceHide = true;
151 } else {
152 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
153 }
149 154 } else {
150 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
155 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
156 if (categoryAxis->labelsPosition() == QCategoryAxis::AxisLabelsPositionCenter) {
157 if (delta < boundingRect.width()
158 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
159 forceHide = true;
160 } else {
161 labelItem->setPos(leftBound + (delta / 2.0) - center.x(),
162 labelItem->pos().y());
163 }
164 } else if (categoryAxis->labelsPosition()
165 == QCategoryAxis::AxisLabelsPositionOnValue) {
166 labelItem->setPos(rightBound - center.x(), labelItem->pos().y());
167 }
151 168 }
152 169 }
153 170
@@ -19,6 +19,7
19 19 #include <private/verticalaxis_p.h>
20 20 #include <QtCharts/QAbstractAxis>
21 21 #include <private/chartpresenter_p.h>
22 #include <QtCharts/QCategoryAxis>
22 23 #include <QtCore/QDebug>
23 24
24 25 QT_CHARTS_BEGIN_NAMESPACE
@@ -140,23 +141,43 void VerticalAxis::updateGeometry()
140 141
141 142 //label in between
142 143 bool forceHide = false;
144 bool labelOnValue = false;
143 145 if (intervalAxis() && (i + 1) != layout.size()) {
144 146 qreal lowerBound = qMin(layout[i], gridRect.bottom());
145 147 qreal upperBound = qMax(layout[i + 1], gridRect.top());
146 148 const qreal delta = lowerBound - upperBound;
147 // Hide label in case visible part of the category at the grid edge is too narrow
148 if (delta < boundingRect.height()
149 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
150 forceHide = true;
149 if (axis()->type() != QAbstractAxis::AxisTypeCategory) {
150 // Hide label in case visible part of the category at the grid edge is too narrow
151 if (delta < boundingRect.height()
152 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
153 forceHide = true;
154 } else {
155 labelItem->setPos(labelItem->pos().x(),
156 lowerBound - (delta / 2.0) - center.y());
157 }
151 158 } else {
152 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
159 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
160 if (categoryAxis->labelsPosition() == QCategoryAxis::AxisLabelsPositionCenter) {
161 if (delta < boundingRect.height()
162 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
163 forceHide = true;
164 } else {
165 labelItem->setPos(labelItem->pos().x(),
166 lowerBound - (delta / 2.0) - center.y());
167 }
168 } else if (categoryAxis->labelsPosition()
169 == QCategoryAxis::AxisLabelsPositionOnValue) {
170 labelOnValue = true;
171 labelItem->setPos(labelItem->pos().x(), upperBound - center.y());
172 }
153 173 }
154 174 }
155 175
156 176 //label overlap detection - compensate one pixel for rounding errors
157 177 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
158 (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() ||
159 labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) {
178 ((labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom()
179 && !labelOnValue) ||
180 (labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0) && !labelOnValue)) {
160 181 labelItem->setVisible(false);
161 182 }
162 183 else {
@@ -300,7 +300,11 public:
300 300 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
301 301 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 2, 0, "Margins",
302 302 QLatin1String("Trying to create uncreatable: Margins."));
303
304 // QtCharts 2.1
305 qmlRegisterType<DeclarativeCategoryAxis, 1>(uri, 2, 1, "CategoryAxis");
303 306 }
307
304 308 };
305 309
306 310 QT_CHARTS_END_NAMESPACE
@@ -93,6 +93,20 void DeclarativeCategoryAxis::appendAxisChildren(QQmlListProperty<QObject> *list
93 93 Q_UNUSED(element)
94 94 }
95 95
96 DeclarativeCategoryAxis::AxisLabelsPosition DeclarativeCategoryAxis::labelsPosition() const
97 {
98 return (DeclarativeCategoryAxis::AxisLabelsPosition) QCategoryAxis::labelsPosition();
99 }
100
101 void DeclarativeCategoryAxis::setLabelsPosition(AxisLabelsPosition position)
102 {
103 QCategoryAxis::AxisLabelsPosition labelsPosition = (QCategoryAxis::AxisLabelsPosition) position;
104 if (labelsPosition != m_labelsPosition) {
105 QCategoryAxis::setLabelsPosition(labelsPosition);
106 emit labelsPositionChanged(position);
107 }
108 }
109
96 110 #include "moc_declarativecategoryaxis.cpp"
97 111
98 112 QT_CHARTS_END_NAMESPACE
@@ -50,15 +50,31 class DeclarativeCategoryAxis : public QCategoryAxis, public QQmlParserStatus
50 50 Q_INTERFACES(QQmlParserStatus)
51 51 Q_PROPERTY(QQmlListProperty<QObject> axisChildren READ axisChildren)
52 52 Q_CLASSINFO("DefaultProperty", "axisChildren")
53 Q_PROPERTY(AxisLabelsPosition labelsPosition READ labelsPosition WRITE setLabelsPosition NOTIFY labelsPositionChanged REVISION 1)
54 Q_ENUMS(AxisLabelsPosition)
53 55
54 56 public:
57 // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api
58 enum AxisLabelsPosition {
59 AxisLabelsPositionCenter = 0x0,
60 AxisLabelsPositionOnValue = 0x1
61 };
62
55 63 explicit DeclarativeCategoryAxis(QObject *parent = 0);
56 64 QQmlListProperty<QObject> axisChildren();
57 65
66
58 67 public: // from QDeclarativeParserStatus
59 68 void classBegin();
60 69 void componentComplete();
61 70
71 public:
72 AxisLabelsPosition labelsPosition() const;
73 void setLabelsPosition(AxisLabelsPosition position);
74
75 Q_SIGNALS:
76 Q_REVISION(1) void labelsPositionChanged(AxisLabelsPosition position);
77
62 78 public Q_SLOTS:
63 79 Q_INVOKABLE void append(const QString &label, qreal categoryEndValue);
64 80 Q_INVOKABLE void remove(const QString &label);
@@ -67,6 +83,9 public Q_SLOTS:
67 83
68 84 private:
69 85 static bool endValueLessThan(const QPair<QString, qreal> &value1, const QPair<QString, qreal> &value2);
86
87 private:
88 AxisLabelsPosition m_labelsPosition;
70 89 };
71 90
72 91 QT_CHARTS_END_NAMESPACE
@@ -430,9 +430,26 Module {
430 430 name: "QtCharts::DeclarativeCategoryAxis"
431 431 defaultProperty: "axisChildren"
432 432 prototype: "QtCharts::QCategoryAxis"
433 exports: ["QtCharts/CategoryAxis 1.1", "QtCharts/CategoryAxis 2.0"]
434 exportMetaObjectRevisions: [0, 0]
433 exports: [
434 "QtCharts/CategoryAxis 1.1",
435 "QtCharts/CategoryAxis 2.0",
436 "QtCharts/CategoryAxis 2.1"
437 ]
438 exportMetaObjectRevisions: [0, 0, 1]
439 Enum {
440 name: "AxisLabelsPosition"
441 values: {
442 "AxisLabelsPositionCenter": 0,
443 "AxisLabelsPositionOnValue": 1
444 }
445 }
435 446 Property { name: "axisChildren"; type: "QObject"; isList: true; isReadonly: true }
447 Property { name: "labelsPosition"; revision: 1; type: "AxisLabelsPosition" }
448 Signal {
449 name: "labelsPositionChanged"
450 revision: 1
451 Parameter { name: "position"; type: "AxisLabelsPosition" }
452 }
436 453 Method {
437 454 name: "append"
438 455 Parameter { name: "label"; type: "string" }
@@ -1911,10 +1928,22 Module {
1911 1928 Component {
1912 1929 name: "QtCharts::QCategoryAxis"
1913 1930 prototype: "QtCharts::QValueAxis"
1931 Enum {
1932 name: "AxisLabelsPosition"
1933 values: {
1934 "AxisLabelsPositionCenter": 0,
1935 "AxisLabelsPositionOnValue": 1
1936 }
1937 }
1914 1938 Property { name: "startValue"; type: "double" }
1915 1939 Property { name: "count"; type: "int"; isReadonly: true }
1916 1940 Property { name: "categoriesLabels"; type: "QStringList"; isReadonly: true }
1941 Property { name: "labelsPosition"; type: "AxisLabelsPosition" }
1917 1942 Signal { name: "categoriesChanged" }
1943 Signal {
1944 name: "labelsPositionChanged"
1945 Parameter { name: "position"; type: "QCategoryAxis::AxisLabelsPosition" }
1946 }
1918 1947 }
1919 1948 Component {
1920 1949 name: "QtCharts::QDateTimeAxis"
@@ -52,6 +52,7 private slots:
52 52 void range();
53 53 void range_animation_data();
54 54 void range_animation();
55 void labels_position();
55 56
56 57 void interval_data();
57 58 void interval();
@@ -63,6 +64,7 private:
63 64
64 65 void tst_QCategoryAxis::initTestCase()
65 66 {
67 qRegisterMetaType<QCategoryAxis::AxisLabelsPosition>("QCategoryAxis::AxisLabelsPosition");
66 68 }
67 69
68 70 void tst_QCategoryAxis::cleanupTestCase()
@@ -100,6 +102,7 void tst_QCategoryAxis::qcategoryaxis()
100 102 QVERIFY(qFuzzyCompare(m_categoryaxis->max(), 0));
101 103 QVERIFY(qFuzzyCompare(m_categoryaxis->min(), 0));
102 104 QCOMPARE(m_categoryaxis->type(), QAbstractAxis::AxisTypeCategory);
105 QCOMPARE(m_categoryaxis->labelsPosition(), QCategoryAxis::AxisLabelsPositionCenter);
103 106
104 107 m_chart->setAxisX(m_categoryaxis, m_series);
105 108 m_view->show();
@@ -301,6 +304,15 void tst_QCategoryAxis::interval()
301 304 QCOMPARE(m_categoryaxis->endValue("replaced"), (qreal)75);
302 305 }
303 306
307 void tst_QCategoryAxis::labels_position()
308 {
309 QSignalSpy spy(m_categoryaxis,
310 SIGNAL(labelsPositionChanged(QCategoryAxis::AxisLabelsPosition)));
311 m_categoryaxis->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue);
312 QCOMPARE(m_categoryaxis->labelsPosition(), QCategoryAxis::AxisLabelsPositionOnValue);
313 QCOMPARE(spy.count(), 1);
314 }
315
304 316 QTEST_MAIN(tst_QCategoryAxis)
305 317 #include "tst_qcategoryaxis.moc"
306 318
@@ -18,7 +18,7
18 18
19 19 import QtQuick 2.0
20 20 import QtTest 1.0
21 import QtCharts 2.0
21 import QtCharts 2.1
22 22
23 23 Rectangle {
24 24 width: 400
@@ -43,6 +43,16 Rectangle {
43 43 compare(lineSeries1.axisY.categoriesLabels[1], "label1", "AxisY categories labels");
44 44 compare(lineSeries1.axisY.categoriesLabels[2], "label2", "AxisY categories labels");
45 45 }
46
47 function test_properties() {
48 compare(lineSeries1.axisY.labelsPosition, CategoryAxis.AxisLabelsPositionCenter);
49 }
50
51 function test_signals() {
52 axisLabelsPositionSpy.clear();
53 lineSeries1.axisY.labelsPosition = CategoryAxis.AxisLabelsPositionOnValue;
54 compare(axisLabelsPositionSpy.count, 1, "onLabelsPositionChanged")
55 }
46 56 }
47 57
48 58 ChartView {
@@ -73,6 +83,11 Rectangle {
73 83 label: "label2"
74 84 endValue: 10
75 85 }
86 SignalSpy {
87 id: axisLabelsPositionSpy
88 target: axisY
89 signalName: "labelsPositionChanged"
90 }
76 91 }
77 92 XYPoint { x: -1; y: -1 }
78 93 XYPoint { x: 0; y: 0 }
@@ -38,6 +38,7 private:
38 38 QString imports_1_3();
39 39 QString imports_1_4();
40 40 QString imports_2_0();
41 QString imports_2_1();
41 42
42 43 };
43 44
@@ -78,6 +79,12 QString tst_qml::imports_2_0()
78 79 "import QtCharts 2.0 \n";
79 80 }
80 81
82 QString tst_qml::imports_2_1()
83 {
84 return "import QtQuick 2.1 \n"
85 "import QtCharts 2.1 \n";
86 }
87
81 88 void tst_qml::initTestCase()
82 89 {
83 90 }
@@ -168,6 +175,8 void tst_qml::checkPlugin_data()
168 175 QTest::newRow("LogValueAxis_2_0") << imports_2_0() + "LogValueAxis{}";
169 176 QTest::newRow("BoxPlotSeries_2_0") << imports_2_0() + "BoxPlotSeries{}";
170 177 QTest::newRow("BoxSet_2_0") << imports_2_0() + "BoxSet{}";
178
179 QTest::newRow("CategoryAxis") << imports_2_1() + "CategoryAxis{}";
171 180 }
172 181
173 182 void tst_qml::checkPlugin()
General Comments 0
You need to be logged in to leave comments. Login now