@@ -183,6 +183,9 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt | |||
|
183 | 183 | painter->setClipRegion(QRegion(clipRect.toRect(), QRegion::Ellipse)); |
|
184 | 184 | else |
|
185 | 185 | painter->setClipRect(clipRect); |
|
186 | ||
|
187 | reversePainter(painter, clipRect); | |
|
188 | ||
|
186 | 189 | painter->drawPath(m_path); |
|
187 | 190 | if (m_pointsVisible) { |
|
188 | 191 | painter->setPen(m_pointPen); |
@@ -191,6 +194,8 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt | |||
|
191 | 194 | painter->drawPoints(m_lower->geometryPoints()); |
|
192 | 195 | } |
|
193 | 196 | |
|
197 | reversePainter(painter, clipRect); | |
|
198 | ||
|
194 | 199 | // Draw series point label |
|
195 | 200 | if (m_pointLabelsVisible) { |
|
196 | 201 | static const QString xPointTag(QLatin1String("@xPoint")); |
@@ -214,9 +219,17 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt | |||
|
214 | 219 | // Position text in relation to the point |
|
215 | 220 | int pointLabelWidth = fm.width(pointLabel); |
|
216 | 221 | QPointF position(m_upper->geometryPoints().at(i)); |
|
217 | position.setX(position.x() - pointLabelWidth / 2); | |
|
218 |
position.set |
|
|
219 | ||
|
222 | if (!seriesPrivate()->reverseXAxis()) | |
|
223 | position.setX(position.x() - pointLabelWidth / 2); | |
|
224 | else | |
|
225 | position.setX(domain()->size().width() - position.x() - pointLabelWidth / 2); | |
|
226 | if (!seriesPrivate()->reverseYAxis()) { | |
|
227 | position.setY(position.y() - m_series->upperSeries()->pen().width() / 2 | |
|
228 | - labelOffset); | |
|
229 | } else { | |
|
230 | position.setY(domain()->size().height() - position.y() | |
|
231 | - m_series->upperSeries()->pen().width() / 2 - labelOffset); | |
|
232 | } | |
|
220 | 233 | painter->drawText(position, pointLabel); |
|
221 | 234 | } |
|
222 | 235 | } |
@@ -232,8 +245,17 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt | |||
|
232 | 245 | // Position text in relation to the point |
|
233 | 246 | int pointLabelWidth = fm.width(pointLabel); |
|
234 | 247 | QPointF position(m_lower->geometryPoints().at(i)); |
|
235 | position.setX(position.x() - pointLabelWidth / 2); | |
|
236 |
position.set |
|
|
248 | if (!seriesPrivate()->reverseXAxis()) | |
|
249 | position.setX(position.x() - pointLabelWidth / 2); | |
|
250 | else | |
|
251 | position.setX(domain()->size().width() - position.x() - pointLabelWidth / 2); | |
|
252 | if (!seriesPrivate()->reverseYAxis()) { | |
|
253 | position.setY(position.y() - m_series->lowerSeries()->pen().width() / 2 | |
|
254 | - labelOffset); | |
|
255 | } else { | |
|
256 | position.setY(domain()->size().height() - position.y() | |
|
257 | - m_series->lowerSeries()->pen().width() / 2 - labelOffset); | |
|
258 | } | |
|
237 | 259 | painter->drawText(position, pointLabel); |
|
238 | 260 | } |
|
239 | 261 | } |
@@ -91,6 +91,7 void ChartAxisElement::connectSlots() | |||
|
91 | 91 | QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&))); |
|
92 | 92 | QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool))); |
|
93 | 93 | QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal))); |
|
94 | QObject::connect(axis(), SIGNAL(reverseChanged(bool)), this, SLOT(handleReverseChanged(bool))); | |
|
94 | 95 | } |
|
95 | 96 | |
|
96 | 97 | void ChartAxisElement::handleArrowVisibleChanged(bool visible) |
@@ -208,6 +209,14 void ChartAxisElement::handleRangeChanged(qreal min, qreal max) | |||
|
208 | 209 | } |
|
209 | 210 | } |
|
210 | 211 | |
|
212 | void ChartAxisElement::handleReverseChanged(bool reverse) | |
|
213 | { | |
|
214 | Q_UNUSED(reverse); | |
|
215 | ||
|
216 | QGraphicsLayoutItem::updateGeometry(); | |
|
217 | presenter()->layout()->invalidate(); | |
|
218 | } | |
|
219 | ||
|
211 | 220 | bool ChartAxisElement::isEmpty() |
|
212 | 221 | { |
|
213 | 222 | return axisGeometry().isEmpty() |
@@ -123,6 +123,7 public Q_SLOTS: | |||
|
123 | 123 | void handleTitleTextChanged(const QString &title); |
|
124 | 124 | void handleTitleVisibleChanged(bool visible); |
|
125 | 125 | void handleRangeChanged(qreal min, qreal max); |
|
126 | void handleReverseChanged(bool reverse); | |
|
126 | 127 | |
|
127 | 128 | Q_SIGNALS: |
|
128 | 129 | void clicked(); |
@@ -102,10 +102,20 void HorizontalAxis::updateGeometry() | |||
|
102 | 102 | QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i)); |
|
103 | 103 | |
|
104 | 104 | //grid line |
|
105 | gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom()); | |
|
105 | if (axis()->isReverse()) { | |
|
106 | gridItem->setLine(gridRect.right() - layout[i] + gridRect.left(), gridRect.top(), | |
|
107 | gridRect.right() - layout[i] + gridRect.left(), gridRect.bottom()); | |
|
108 | } else { | |
|
109 | gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom()); | |
|
110 | } | |
|
106 | 111 | |
|
107 | 112 | //label text wrapping |
|
108 |
QString text |
|
|
113 | QString text; | |
|
114 | if (axis()->isReverse() && axis()->type() != QAbstractAxis::AxisTypeCategory) | |
|
115 | text = labelList.at(labelList.count() - i - 1); | |
|
116 | else | |
|
117 | text = labelList.at(i); | |
|
118 | ||
|
109 | 119 | QRectF boundingRect; |
|
110 | 120 | // don't truncate empty labels |
|
111 | 121 | if (text.isEmpty()) { |
@@ -130,18 +140,50 void HorizontalAxis::updateGeometry() | |||
|
130 | 140 | |
|
131 | 141 | //ticks and label position |
|
132 | 142 | if (axis()->alignment() == Qt::AlignTop) { |
|
133 | labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2.0) - labelPadding()); | |
|
134 | tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding()); | |
|
143 | if (axis()->isReverse()) { | |
|
144 | labelItem->setPos(gridRect.right() - layout[layout.size() - i - 1] | |
|
145 | + gridRect.left() - center.x(), | |
|
146 | axisRect.bottom() - rect.height() | |
|
147 | + (heightDiff / 2.0) - labelPadding()); | |
|
148 | tickItem->setLine(gridRect.right() + gridRect.left() - layout[i], | |
|
149 | axisRect.bottom(), | |
|
150 | gridRect.right() + gridRect.left() - layout[i], | |
|
151 | axisRect.bottom() - labelPadding()); | |
|
152 | } else { | |
|
153 | labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() | |
|
154 | + (heightDiff / 2.0) - labelPadding()); | |
|
155 | tickItem->setLine(layout[i], axisRect.bottom(), | |
|
156 | layout[i], axisRect.bottom() - labelPadding()); | |
|
157 | } | |
|
135 | 158 | } else if (axis()->alignment() == Qt::AlignBottom) { |
|
136 | labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0) + labelPadding()); | |
|
137 | tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding()); | |
|
159 | if (axis()->isReverse()) { | |
|
160 | labelItem->setPos(gridRect.right() - layout[layout.size() - i - 1] | |
|
161 | + gridRect.left() - center.x(), | |
|
162 | axisRect.top() - (heightDiff / 2.0) + labelPadding()); | |
|
163 | tickItem->setLine(gridRect.right() + gridRect.left() - layout[i], axisRect.top(), | |
|
164 | gridRect.right() + gridRect.left() - layout[i], | |
|
165 | axisRect.top() + labelPadding()); | |
|
166 | } else { | |
|
167 | labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0) | |
|
168 | + labelPadding()); | |
|
169 | tickItem->setLine(layout[i], axisRect.top(), | |
|
170 | layout[i], axisRect.top() + labelPadding()); | |
|
171 | } | |
|
138 | 172 | } |
|
139 | 173 | |
|
140 | 174 | //label in between |
|
141 | 175 | bool forceHide = false; |
|
142 | 176 | if (intervalAxis() && (i + 1) != layout.size()) { |
|
143 |
qreal leftBound |
|
|
144 | qreal rightBound = qMin(layout[i + 1], gridRect.right()); | |
|
177 | qreal leftBound; | |
|
178 | qreal rightBound; | |
|
179 | if (axis()->isReverse()) { | |
|
180 | leftBound = qMax(gridRect.right() + gridRect.left() - layout[i + 1], | |
|
181 | gridRect.left()); | |
|
182 | rightBound = qMin(gridRect.right() + gridRect.left() - layout[i], gridRect.right()); | |
|
183 | } else { | |
|
184 | leftBound = qMax(layout[i], gridRect.left()); | |
|
185 | rightBound = qMin(layout[i + 1], gridRect.right()); | |
|
186 | } | |
|
145 | 187 | const qreal delta = rightBound - leftBound; |
|
146 | 188 | if (axis()->type() != QAbstractAxis::AxisTypeCategory) { |
|
147 | 189 | // Hide label in case visible part of the category at the grid edge is too narrow |
@@ -163,7 +205,10 void HorizontalAxis::updateGeometry() | |||
|
163 | 205 | } |
|
164 | 206 | } else if (categoryAxis->labelsPosition() |
|
165 | 207 | == QCategoryAxis::AxisLabelsPositionOnValue) { |
|
166 | labelItem->setPos(rightBound - center.x(), labelItem->pos().y()); | |
|
208 | if (axis()->isReverse()) | |
|
209 | labelItem->setPos(leftBound - center.x(), labelItem->pos().y()); | |
|
210 | else | |
|
211 | labelItem->setPos(rightBound - center.x(), labelItem->pos().y()); | |
|
167 | 212 | } |
|
168 | 213 | } |
|
169 | 214 | } |
@@ -188,14 +233,29 void HorizontalAxis::updateGeometry() | |||
|
188 | 233 | qreal leftBound; |
|
189 | 234 | qreal rightBound; |
|
190 | 235 | if (i == 0) { |
|
191 | leftBound = gridRect.left(); | |
|
192 | rightBound = layout[0]; | |
|
193 | } else { | |
|
194 | leftBound = layout[i]; | |
|
195 | if (i == layout.size() - 1) | |
|
236 | if (axis()->isReverse()) { | |
|
237 | leftBound = gridRect.right() + gridRect.left() - layout[i]; | |
|
196 | 238 | rightBound = gridRect.right(); |
|
197 | else | |
|
198 |
|
|
|
239 | } else { | |
|
240 | leftBound = gridRect.left(); | |
|
241 | rightBound = layout[0]; | |
|
242 | } | |
|
243 | } else { | |
|
244 | if (axis()->isReverse()) { | |
|
245 | rightBound = gridRect.right() + gridRect.left() - layout[i]; | |
|
246 | if (i == layout.size() - 1) { | |
|
247 | leftBound = gridRect.left(); | |
|
248 | } else { | |
|
249 | leftBound = qMax(gridRect.right() + gridRect.left() - layout[i + 1], | |
|
250 | gridRect.left()); | |
|
251 | } | |
|
252 | } else { | |
|
253 | leftBound = layout[i]; | |
|
254 | if (i == layout.size() - 1) | |
|
255 | rightBound = gridRect.right(); | |
|
256 | else | |
|
257 | rightBound = qMin(layout[i + 1], gridRect.right()); | |
|
258 | } | |
|
199 | 259 | } |
|
200 | 260 | if (leftBound < gridRect.left()) |
|
201 | 261 | leftBound = gridRect.left(); |
@@ -246,6 +246,23 QT_CHARTS_BEGIN_NAMESPACE | |||
|
246 | 246 | */ |
|
247 | 247 | |
|
248 | 248 | /*! |
|
249 | \property QAbstractAxis::reverse | |
|
250 | The reverse property defines if reverse axis is used. By default the value is false. | |
|
251 | ||
|
252 | Reverse axis is supported with line, spline, scatter and area series with cartesian chart. | |
|
253 | All axes of the same orientation attached to same series must be reversed if one is reversed or | |
|
254 | the behavior is undefined. | |
|
255 | */ | |
|
256 | /*! | |
|
257 | \qmlproperty alignment AbstractAxis::reverse | |
|
258 | The reverse property defines if reverse axis is used. By default the value is false. | |
|
259 | ||
|
260 | Reverse axis is supported with line, spline, scatter and area series with cartesian chart. | |
|
261 | All axes of the same orientation attached to same series must be reversed if one is reversed or | |
|
262 | the behavior is undefined. | |
|
263 | */ | |
|
264 | ||
|
265 | /*! | |
|
249 | 266 | \fn void QAbstractAxis::visibleChanged(bool visible) |
|
250 | 267 | Visibility of the axis has changed to \a visible. |
|
251 | 268 | */ |
@@ -831,6 +848,19 Qt::Alignment QAbstractAxis::alignment() const | |||
|
831 | 848 | return d_ptr->alignment(); |
|
832 | 849 | } |
|
833 | 850 | |
|
851 | bool QAbstractAxis::isReverse() const | |
|
852 | { | |
|
853 | return d_ptr->m_reverse; | |
|
854 | } | |
|
855 | ||
|
856 | void QAbstractAxis::setReverse(bool reverse) | |
|
857 | { | |
|
858 | if (d_ptr->m_reverse != reverse && type() != QAbstractAxis::AxisTypeBarCategory) { | |
|
859 | d_ptr->m_reverse = reverse; | |
|
860 | emit reverseChanged(reverse); | |
|
861 | } | |
|
862 | } | |
|
863 | ||
|
834 | 864 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
835 | 865 | |
|
836 | 866 | QAbstractAxisPrivate::QAbstractAxisPrivate(QAbstractAxis *q) |
@@ -855,7 +885,8 QAbstractAxisPrivate::QAbstractAxisPrivate(QAbstractAxis *q) | |||
|
855 | 885 | m_shadesPen(QChartPrivate::defaultPen()), |
|
856 | 886 | m_shadesBrush(QChartPrivate::defaultBrush()), |
|
857 | 887 | m_shadesOpacity(1.0), |
|
858 | m_dirty(false) | |
|
888 | m_dirty(false), | |
|
889 | m_reverse(false) | |
|
859 | 890 | { |
|
860 | 891 | } |
|
861 | 892 |
@@ -61,6 +61,7 class QT_CHARTS_EXPORT QAbstractAxis : public QObject | |||
|
61 | 61 | Q_PROPERTY(Qt::Orientation orientation READ orientation) |
|
62 | 62 | //aligment |
|
63 | 63 | Q_PROPERTY(Qt::Alignment alignment READ alignment) |
|
64 | Q_PROPERTY(bool reverse READ isReverse WRITE setReverse NOTIFY reverseChanged) | |
|
64 | 65 | |
|
65 | 66 | public: |
|
66 | 67 | |
@@ -145,6 +146,10 public: | |||
|
145 | 146 | void setMax(const QVariant &max); |
|
146 | 147 | void setRange(const QVariant &min, const QVariant &max); |
|
147 | 148 | |
|
149 | //reverse handling | |
|
150 | void setReverse(bool reverse = true); | |
|
151 | bool isReverse() const; | |
|
152 | ||
|
148 | 153 | Q_SIGNALS: |
|
149 | 154 | void visibleChanged(bool visible); |
|
150 | 155 | void linePenChanged(const QPen &pen); |
@@ -166,6 +171,7 Q_SIGNALS: | |||
|
166 | 171 | void shadesBorderColorChanged(QColor color); |
|
167 | 172 | void shadesPenChanged(const QPen &pen); |
|
168 | 173 | void shadesBrushChanged(const QBrush &brush); |
|
174 | void reverseChanged(bool reverse); | |
|
169 | 175 | |
|
170 | 176 | protected: |
|
171 | 177 | QScopedPointer<QAbstractAxisPrivate> d_ptr; |
@@ -118,6 +118,8 private: | |||
|
118 | 118 | |
|
119 | 119 | bool m_dirty; |
|
120 | 120 | |
|
121 | bool m_reverse; | |
|
122 | ||
|
121 | 123 | friend class QAbstractAxis; |
|
122 | 124 | friend class ChartDataSet; |
|
123 | 125 | friend class ChartPresenter; |
@@ -104,10 +104,20 void VerticalAxis::updateGeometry() | |||
|
104 | 104 | QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i)); |
|
105 | 105 | |
|
106 | 106 | //grid line |
|
107 | gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]); | |
|
107 | if (axis()->isReverse()) { | |
|
108 | gridItem->setLine(gridRect.left(), gridRect.top() + gridRect.bottom() - layout[i], | |
|
109 | gridRect.right(), gridRect.top() + gridRect.bottom() - layout[i]); | |
|
110 | } else { | |
|
111 | gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]); | |
|
112 | } | |
|
108 | 113 | |
|
109 | 114 | //label text wrapping |
|
110 |
QString text |
|
|
115 | QString text; | |
|
116 | if (axis()->isReverse() && axis()->type() != QAbstractAxis::AxisTypeCategory) | |
|
117 | text = labelList.at(labelList.count() - i - 1); | |
|
118 | else | |
|
119 | text = labelList.at(i); | |
|
120 | ||
|
111 | 121 | QRectF boundingRect; |
|
112 | 122 | // don't truncate empty labels |
|
113 | 123 | if (text.isEmpty()) { |
@@ -132,19 +142,54 void VerticalAxis::updateGeometry() | |||
|
132 | 142 | |
|
133 | 143 | //ticks and label position |
|
134 | 144 | if (axis()->alignment() == Qt::AlignLeft) { |
|
135 | labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) - labelPadding(), layout[i] - center.y()); | |
|
136 | tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]); | |
|
145 | if (axis()->isReverse()) { | |
|
146 | labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) | |
|
147 | - labelPadding(), | |
|
148 | gridRect.top() + gridRect.bottom() | |
|
149 | - layout[layout.size() - i - 1] - center.y()); | |
|
150 | tickItem->setLine(axisRect.right() - labelPadding(), | |
|
151 | gridRect.top() + gridRect.bottom() - layout[i], | |
|
152 | axisRect.right(), | |
|
153 | gridRect.top() + gridRect.bottom() - layout[i]); | |
|
154 | } else { | |
|
155 | labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) | |
|
156 | - labelPadding(), | |
|
157 | layout[i] - center.y()); | |
|
158 | tickItem->setLine(axisRect.right() - labelPadding(), layout[i], | |
|
159 | axisRect.right(), layout[i]); | |
|
160 | } | |
|
137 | 161 | } else if (axis()->alignment() == Qt::AlignRight) { |
|
138 | labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), layout[i] - center.y()); | |
|
139 |
tickItem->setLine(axisRect.left(), |
|
|
162 | if (axis()->isReverse()) { | |
|
163 | tickItem->setLine(axisRect.left(), | |
|
164 | gridRect.top() + gridRect.bottom() - layout[i], | |
|
165 | axisRect.left() + labelPadding(), | |
|
166 | gridRect.top() + gridRect.bottom() - layout[i]); | |
|
167 | labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), | |
|
168 | gridRect.top() + gridRect.bottom() | |
|
169 | - layout[layout.size() - i - 1] - center.y()); | |
|
170 | } else { | |
|
171 | labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), | |
|
172 | layout[i] - center.y()); | |
|
173 | tickItem->setLine(axisRect.left(), layout[i], | |
|
174 | axisRect.left() + labelPadding(), layout[i]); | |
|
175 | } | |
|
140 | 176 | } |
|
141 | 177 | |
|
142 | 178 | //label in between |
|
143 | 179 | bool forceHide = false; |
|
144 | 180 | bool labelOnValue = false; |
|
145 | 181 | if (intervalAxis() && (i + 1) != layout.size()) { |
|
146 |
qreal lowerBound |
|
|
147 |
qreal upperBound |
|
|
182 | qreal lowerBound; | |
|
183 | qreal upperBound; | |
|
184 | if (axis()->isReverse()) { | |
|
185 | lowerBound = qMax(gridRect.top() + gridRect.bottom() - layout[i + 1], | |
|
186 | gridRect.top()); | |
|
187 | upperBound = qMin(gridRect.top() + gridRect.bottom() - layout[i], | |
|
188 | gridRect.bottom()); | |
|
189 | } else { | |
|
190 | lowerBound = qMin(layout[i], gridRect.bottom()); | |
|
191 | upperBound = qMax(layout[i + 1], gridRect.top()); | |
|
192 | } | |
|
148 | 193 | const qreal delta = lowerBound - upperBound; |
|
149 | 194 | if (axis()->type() != QAbstractAxis::AxisTypeCategory) { |
|
150 | 195 | // Hide label in case visible part of the category at the grid edge is too narrow |
@@ -168,13 +213,21 void VerticalAxis::updateGeometry() | |||
|
168 | 213 | } else if (categoryAxis->labelsPosition() |
|
169 | 214 | == QCategoryAxis::AxisLabelsPositionOnValue) { |
|
170 | 215 | labelOnValue = true; |
|
171 | labelItem->setPos(labelItem->pos().x(), upperBound - center.y()); | |
|
216 | if (axis()->isReverse()) { | |
|
217 | labelItem->setPos(labelItem->pos().x(), gridRect.top() + gridRect.bottom() | |
|
218 | - layout[i + 1] - center.y()); | |
|
219 | } else { | |
|
220 | labelItem->setPos(labelItem->pos().x(), upperBound - center.y()); | |
|
221 | } | |
|
172 | 222 | } |
|
173 | 223 | } |
|
174 | 224 | } |
|
175 | 225 | |
|
176 | 226 | //label overlap detection - compensate one pixel for rounding errors |
|
177 | if (labelItem->pos().y() + boundingRect.height() > height || forceHide || | |
|
227 | if (axis()->isReverse()) { | |
|
228 | if (forceHide) | |
|
229 | labelItem->setVisible(false); | |
|
230 | } else if (labelItem->pos().y() + boundingRect.height() > height || forceHide || | |
|
178 | 231 | ((labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() |
|
179 | 232 | && !labelOnValue) || |
|
180 | 233 | (labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0) && !labelOnValue)) { |
@@ -195,14 +248,29 void VerticalAxis::updateGeometry() | |||
|
195 | 248 | qreal lowerBound; |
|
196 | 249 | qreal upperBound; |
|
197 | 250 | if (i == 0) { |
|
198 | lowerBound = gridRect.bottom(); | |
|
199 | upperBound = layout[0]; | |
|
200 | } else { | |
|
201 | lowerBound = layout[i]; | |
|
202 | if (i == layout.size() - 1) | |
|
251 | if (axis()->isReverse()) { | |
|
203 | 252 | upperBound = gridRect.top(); |
|
204 | else | |
|
205 | upperBound = qMax(layout[i + 1], gridRect.top()); | |
|
253 | lowerBound = gridRect.top() + gridRect.bottom() - layout[i]; | |
|
254 | } else { | |
|
255 | lowerBound = gridRect.bottom(); | |
|
256 | upperBound = layout[0]; | |
|
257 | } | |
|
258 | } else { | |
|
259 | if (axis()->isReverse()) { | |
|
260 | upperBound = gridRect.top() + gridRect.bottom() - layout[i]; | |
|
261 | if (i == layout.size() - 1) { | |
|
262 | lowerBound = gridRect.bottom(); | |
|
263 | } else { | |
|
264 | lowerBound = qMax(gridRect.top() + gridRect.bottom() - layout[i + 1], | |
|
265 | gridRect.top()); | |
|
266 | } | |
|
267 | } else { | |
|
268 | lowerBound = layout[i]; | |
|
269 | if (i == layout.size() - 1) | |
|
270 | upperBound = gridRect.top(); | |
|
271 | else | |
|
272 | upperBound = qMax(layout[i + 1], gridRect.top()); | |
|
273 | } | |
|
206 | 274 | |
|
207 | 275 | } |
|
208 | 276 | if (lowerBound > gridRect.bottom()) |
@@ -40,6 +40,19 void ChartItem::handleDomainUpdated() | |||
|
40 | 40 | qWarning() << __FUNCTION__<< "Slot not implemented"; |
|
41 | 41 | } |
|
42 | 42 | |
|
43 | void ChartItem::reversePainter(QPainter *painter, const QRectF &clipRect) | |
|
44 | { | |
|
45 | if (m_series->reverseXAxis()) { | |
|
46 | painter->translate(clipRect.width(), 0); | |
|
47 | painter->scale(-1, 1); | |
|
48 | } | |
|
49 | ||
|
50 | if (m_series->reverseYAxis()) { | |
|
51 | painter->translate(0, clipRect.height()); | |
|
52 | painter->scale(1, -1); | |
|
53 | } | |
|
54 | } | |
|
55 | ||
|
43 | 56 | #include "moc_chartitem_p.cpp" |
|
44 | 57 | |
|
45 | 58 | QT_CHARTS_END_NAMESPACE |
@@ -44,6 +44,9 public: | |||
|
44 | 44 | public Q_SLOTS: |
|
45 | 45 | virtual void handleDomainUpdated(); |
|
46 | 46 | |
|
47 | void reversePainter(QPainter *painter, const QRectF &clipRect); | |
|
48 | QAbstractSeriesPrivate* seriesPrivate() const {return m_series;} | |
|
49 | ||
|
47 | 50 | protected: |
|
48 | 51 | bool m_validData; |
|
49 | 52 | private: |
@@ -363,6 +363,8 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt | |||
|
363 | 363 | painter->setClipRect(clipRect); |
|
364 | 364 | } |
|
365 | 365 | |
|
366 | reversePainter(painter, clipRect); | |
|
367 | ||
|
366 | 368 | if (m_pointsVisible) { |
|
367 | 369 | painter->setBrush(m_linePen.color()); |
|
368 | 370 | painter->drawPath(m_linePath); |
@@ -378,6 +380,8 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt | |||
|
378 | 380 | } |
|
379 | 381 | } |
|
380 | 382 | |
|
383 | reversePainter(painter, clipRect); | |
|
384 | ||
|
381 | 385 | if (m_pointLabelsVisible) |
|
382 | 386 | m_series->d_func()->drawSeriesPointLabels(painter, m_points, m_linePen.width() / 2); |
|
383 | 387 |
@@ -318,6 +318,40 void QAbstractSeriesPrivate::initializeAnimations(QChart::AnimationOptions optio | |||
|
318 | 318 | Q_UNUSED(options); |
|
319 | 319 | } |
|
320 | 320 | |
|
321 | bool QAbstractSeriesPrivate::reverseXAxis() | |
|
322 | { | |
|
323 | bool reverseXAxis = false; | |
|
324 | if (m_axes.size() != 0 && !(m_chart->chartType() == QChart::ChartTypePolar)) { | |
|
325 | int i = 0; | |
|
326 | while (i < m_axes.size()) { | |
|
327 | if (m_axes.at(i)->orientation() == Qt::Horizontal && m_axes.at(i)->isReverse()) { | |
|
328 | reverseXAxis = true; | |
|
329 | break; | |
|
330 | } | |
|
331 | i++; | |
|
332 | } | |
|
333 | } | |
|
334 | ||
|
335 | return reverseXAxis; | |
|
336 | } | |
|
337 | ||
|
338 | bool QAbstractSeriesPrivate::reverseYAxis() | |
|
339 | { | |
|
340 | bool reverseYAxis = false; | |
|
341 | if (m_axes.size() != 0 && !(m_chart->chartType() == QChart::ChartTypePolar)) { | |
|
342 | int i = 0; | |
|
343 | while (i < m_axes.size()) { | |
|
344 | if (m_axes.at(i)->orientation() == Qt::Vertical && m_axes.at(i)->isReverse()) { | |
|
345 | reverseYAxis = true; | |
|
346 | break; | |
|
347 | } | |
|
348 | i++; | |
|
349 | } | |
|
350 | } | |
|
351 | ||
|
352 | return reverseYAxis; | |
|
353 | } | |
|
354 | ||
|
321 | 355 | #include "moc_qabstractseries.cpp" |
|
322 | 356 | #include "moc_qabstractseries_p.cpp" |
|
323 | 357 |
@@ -77,6 +77,8 public: | |||
|
77 | 77 | ChartPresenter *presenter() const; |
|
78 | 78 | |
|
79 | 79 | QChart* chart() { return m_chart; } |
|
80 | bool reverseXAxis(); | |
|
81 | bool reverseYAxis(); | |
|
80 | 82 | |
|
81 | 83 | Q_SIGNALS: |
|
82 | 84 | void countChanged(); |
@@ -86,6 +88,7 protected: | |||
|
86 | 88 | QChart *m_chart; |
|
87 | 89 | QScopedPointer<ChartItem> m_item; |
|
88 | 90 | QList<QAbstractAxis*> m_axes; |
|
91 | ||
|
89 | 92 | private: |
|
90 | 93 | QScopedPointer<AbstractDomain> m_domain; |
|
91 | 94 | QString m_name; |
@@ -169,7 +169,17 void ScatterChartItem::updateGeometry() | |||
|
169 | 169 | // if it was caused by an insert, but this shouldn't be a problem as the points are |
|
170 | 170 | // fake anyway. After remove animation stops, geometry is updated to correct one. |
|
171 | 171 | m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i)); |
|
172 | item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2); | |
|
172 | QPointF position; | |
|
173 | if (seriesPrivate()->reverseXAxis()) | |
|
174 | position.setX(domain()->size().width() - point.x() - rect.width() / 2); | |
|
175 | else | |
|
176 | position.setX(point.x() - rect.width() / 2); | |
|
177 | if (seriesPrivate()->reverseYAxis()) | |
|
178 | position.setY(domain()->size().height() - point.y() - rect.height() / 2); | |
|
179 | else | |
|
180 | position.setY(point.y() - rect.height() / 2); | |
|
181 | item->setPos(position); | |
|
182 | ||
|
173 | 183 | |
|
174 | 184 | if (!m_visible || offGridStatus.at(i)) |
|
175 | 185 | item->setVisible(false); |
@@ -446,6 +446,8 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o | |||
|
446 | 446 | painter->setClipRect(clipRect); |
|
447 | 447 | } |
|
448 | 448 | |
|
449 | reversePainter(painter, clipRect); | |
|
450 | ||
|
449 | 451 | painter->drawPath(m_path); |
|
450 | 452 | |
|
451 | 453 | if (m_pointsVisible) { |
@@ -456,6 +458,8 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o | |||
|
456 | 458 | painter->drawPoints(geometryPoints()); |
|
457 | 459 | } |
|
458 | 460 | |
|
461 | reversePainter(painter, clipRect); | |
|
462 | ||
|
459 | 463 | if (m_pointLabelsVisible) |
|
460 | 464 | m_series->d_func()->drawSeriesPointLabels(painter, m_points, m_linePen.width() / 2); |
|
461 | 465 |
@@ -851,8 +851,14 void QXYSeriesPrivate::drawSeriesPointLabels(QPainter *painter, const QVector<QP | |||
|
851 | 851 | // Position text in relation to the point |
|
852 | 852 | int pointLabelWidth = fm.width(pointLabel); |
|
853 | 853 | QPointF position(points.at(i)); |
|
854 | position.setX(position.x() - pointLabelWidth / 2); | |
|
855 |
position.set |
|
|
854 | if (!reverseXAxis()) | |
|
855 | position.setX(position.x() - pointLabelWidth / 2); | |
|
856 | else | |
|
857 | position.setX(domain()->size().width() - position.x() - pointLabelWidth / 2); | |
|
858 | if (!reverseYAxis()) | |
|
859 | position.setY(position.y() - labelOffset); | |
|
860 | else | |
|
861 | position.setY(domain()->size().height() - position.y() - labelOffset); | |
|
856 | 862 | |
|
857 | 863 | painter->drawText(position, pointLabel); |
|
858 | 864 | } |
@@ -303,6 +303,8 public: | |||
|
303 | 303 | |
|
304 | 304 | // QtCharts 2.1 |
|
305 | 305 | qmlRegisterType<DeclarativeCategoryAxis, 1>(uri, 2, 1, "CategoryAxis"); |
|
306 | qmlRegisterUncreatableType<QAbstractAxis>(uri, 2, 1, "AbstractAxis", | |
|
307 | QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead.")); | |
|
306 | 308 | } |
|
307 | 309 | |
|
308 | 310 | }; |
@@ -1497,9 +1497,13 Module { | |||
|
1497 | 1497 | Component { |
|
1498 | 1498 | name: "QtCharts::QAbstractAxis" |
|
1499 | 1499 | prototype: "QObject" |
|
1500 | exports: ["QtCharts/AbstractAxis 1.0", "QtCharts/AbstractAxis 2.0"] | |
|
1500 | exports: [ | |
|
1501 | "QtCharts/AbstractAxis 1.0", | |
|
1502 | "QtCharts/AbstractAxis 2.0", | |
|
1503 | "QtCharts/AbstractAxis 2.1" | |
|
1504 | ] | |
|
1501 | 1505 | isCreatable: false |
|
1502 | exportMetaObjectRevisions: [0, 0] | |
|
1506 | exportMetaObjectRevisions: [0, 0, 0] | |
|
1503 | 1507 | Property { name: "visible"; type: "bool" } |
|
1504 | 1508 | Property { name: "lineVisible"; type: "bool" } |
|
1505 | 1509 | Property { name: "linePen"; type: "QPen" } |
@@ -1522,6 +1526,7 Module { | |||
|
1522 | 1526 | Property { name: "titleFont"; type: "QFont" } |
|
1523 | 1527 | Property { name: "orientation"; type: "Qt::Orientation"; isReadonly: true } |
|
1524 | 1528 | Property { name: "alignment"; type: "Qt::Alignment"; isReadonly: true } |
|
1529 | Property { name: "reverse"; type: "bool" } | |
|
1525 | 1530 | Signal { |
|
1526 | 1531 | name: "visibleChanged" |
|
1527 | 1532 | Parameter { name: "visible"; type: "bool" } |
@@ -1602,6 +1607,10 Module { | |||
|
1602 | 1607 | name: "shadesBrushChanged" |
|
1603 | 1608 | Parameter { name: "brush"; type: "QBrush" } |
|
1604 | 1609 | } |
|
1610 | Signal { | |
|
1611 | name: "reverseChanged" | |
|
1612 | Parameter { name: "reverse"; type: "bool" } | |
|
1613 | } | |
|
1605 | 1614 | } |
|
1606 | 1615 | Component { |
|
1607 | 1616 | name: "QtCharts::QAbstractBarSeries" |
@@ -56,6 +56,7 private slots: | |||
|
56 | 56 | |
|
57 | 57 | void interval_data(); |
|
58 | 58 | void interval(); |
|
59 | void reverse(); | |
|
59 | 60 | |
|
60 | 61 | private: |
|
61 | 62 | QCategoryAxis* m_categoryaxis; |
@@ -110,6 +111,8 void tst_QCategoryAxis::qcategoryaxis() | |||
|
110 | 111 | |
|
111 | 112 | QVERIFY(!qFuzzyCompare(m_categoryaxis->max(), 0)); |
|
112 | 113 | QVERIFY(!qFuzzyCompare(m_categoryaxis->min(), 0)); |
|
114 | ||
|
115 | QCOMPARE(m_categoryaxis->isReverse(), false); | |
|
113 | 116 | } |
|
114 | 117 | |
|
115 | 118 | void tst_QCategoryAxis::max_raw_data() |
@@ -313,6 +316,22 void tst_QCategoryAxis::labels_position() | |||
|
313 | 316 | QCOMPARE(spy.count(), 1); |
|
314 | 317 | } |
|
315 | 318 | |
|
319 | void tst_QCategoryAxis::reverse() | |
|
320 | { | |
|
321 | QSignalSpy spy(m_categoryaxis, SIGNAL(reverseChanged(bool))); | |
|
322 | QCOMPARE(m_categoryaxis->isReverse(), false); | |
|
323 | ||
|
324 | m_categoryaxis->setReverse(); | |
|
325 | QCOMPARE(m_categoryaxis->isReverse(), true); | |
|
326 | ||
|
327 | m_chart->setAxisX(m_categoryaxis, m_series); | |
|
328 | QCOMPARE(spy.count(), 1); | |
|
329 | ||
|
330 | m_view->show(); | |
|
331 | QTest::qWaitForWindowShown(m_view); | |
|
332 | QCOMPARE(m_categoryaxis->isReverse(), true); | |
|
333 | } | |
|
334 | ||
|
316 | 335 | QTEST_MAIN(tst_QCategoryAxis) |
|
317 | 336 | #include "tst_qcategoryaxis.moc" |
|
318 | 337 |
@@ -52,6 +52,7 private slots: | |||
|
52 | 52 | void range(); |
|
53 | 53 | void range_animation_data(); |
|
54 | 54 | void range_animation(); |
|
55 | void reverse(); | |
|
55 | 56 | |
|
56 | 57 | private: |
|
57 | 58 | QDateTimeAxis *m_dateTimeAxisX; |
@@ -113,6 +114,9 void tst_QDateTimeAxis::qdatetimeaxis() | |||
|
113 | 114 | |
|
114 | 115 | QVERIFY(m_dateTimeAxisX->max().toMSecsSinceEpoch() != 0); |
|
115 | 116 | QVERIFY(m_dateTimeAxisX->min().toMSecsSinceEpoch() != 0); |
|
117 | ||
|
118 | QCOMPARE(m_dateTimeAxisX->isReverse(), false); | |
|
119 | QCOMPARE(m_dateTimeAxisY->isReverse(), false); | |
|
116 | 120 | } |
|
117 | 121 | |
|
118 | 122 | void tst_QDateTimeAxis::max_raw_data() |
@@ -307,6 +311,20 void tst_QDateTimeAxis::range_animation() | |||
|
307 | 311 | range(); |
|
308 | 312 | } |
|
309 | 313 | |
|
314 | void tst_QDateTimeAxis::reverse() | |
|
315 | { | |
|
316 | QSignalSpy spy(m_dateTimeAxisX, SIGNAL(reverseChanged(bool))); | |
|
317 | QCOMPARE(m_dateTimeAxisX->isReverse(), false); | |
|
318 | ||
|
319 | m_dateTimeAxisX->setReverse(); | |
|
320 | QCOMPARE(m_dateTimeAxisX->isReverse(), true); | |
|
321 | QCOMPARE(spy.count(), 1); | |
|
322 | ||
|
323 | m_view->show(); | |
|
324 | QTest::qWaitForWindowShown(m_view); | |
|
325 | QCOMPARE(m_dateTimeAxisX->isReverse(), true); | |
|
326 | } | |
|
327 | ||
|
310 | 328 | QTEST_MAIN(tst_QDateTimeAxis) |
|
311 | 329 | #include "tst_qdatetimeaxis.moc" |
|
312 | 330 |
@@ -57,6 +57,7 private slots: | |||
|
57 | 57 | void autoscale_data(); |
|
58 | 58 | void autoscale(); |
|
59 | 59 | void zoom(); |
|
60 | void reverse(); | |
|
60 | 61 | |
|
61 | 62 | private: |
|
62 | 63 | QLogValueAxis* m_logvaluesaxis; |
@@ -109,6 +110,8 void tst_QLogValueAxis::qlogvalueaxis() | |||
|
109 | 110 | |
|
110 | 111 | QCOMPARE(m_logvaluesaxis->max(), (qreal)100); |
|
111 | 112 | QCOMPARE(m_logvaluesaxis->min(), (qreal)1); |
|
113 | ||
|
114 | QCOMPARE(m_logvaluesaxis->isReverse(), false); | |
|
112 | 115 | } |
|
113 | 116 | |
|
114 | 117 | void tst_QLogValueAxis::max_raw_data() |
@@ -313,8 +316,6 void tst_QLogValueAxis::noautoscale() | |||
|
313 | 316 | QCOMPARE(spy0.count(), 1); |
|
314 | 317 | QCOMPARE(spy1.count(), 1); |
|
315 | 318 | QCOMPARE(spy2.count(), 1); |
|
316 | ||
|
317 | m_chart->setAxisX(m_logvaluesaxis, m_series); | |
|
318 | 319 | m_view->show(); |
|
319 | 320 | QTest::qWaitForWindowShown(m_view); |
|
320 | 321 | QCOMPARE(m_logvaluesaxis->min(), min); |
@@ -381,6 +382,20 void tst_QLogValueAxis::zoom() | |||
|
381 | 382 | |
|
382 | 383 | } |
|
383 | 384 | |
|
385 | void tst_QLogValueAxis::reverse() | |
|
386 | { | |
|
387 | QSignalSpy spy(m_logvaluesaxis, SIGNAL(reverseChanged(bool))); | |
|
388 | QCOMPARE(m_logvaluesaxis->isReverse(), false); | |
|
389 | ||
|
390 | m_logvaluesaxis->setReverse(); | |
|
391 | QCOMPARE(m_logvaluesaxis->isReverse(), true); | |
|
392 | QCOMPARE(spy.count(), 1); | |
|
393 | ||
|
394 | m_view->show(); | |
|
395 | QTest::qWaitForWindowShown(m_view); | |
|
396 | QCOMPARE(m_logvaluesaxis->isReverse(), true); | |
|
397 | } | |
|
398 | ||
|
384 | 399 | QTEST_MAIN(tst_QLogValueAxis) |
|
385 | 400 | #include "tst_qlogvalueaxis.moc" |
|
386 | 401 |
@@ -46,12 +46,28 Rectangle { | |||
|
46 | 46 | |
|
47 | 47 | function test_properties() { |
|
48 | 48 | compare(lineSeries1.axisY.labelsPosition, CategoryAxis.AxisLabelsPositionCenter); |
|
49 | verify(lineSeries1.axisX.reverse == false, "AxisX reverse"); | |
|
50 | verify(lineSeries1.axisY.reverse == false, "AxisY reverse"); | |
|
51 | ||
|
52 | // Modify properties | |
|
53 | lineSeries1.axisX.reverse = true; | |
|
54 | verify(lineSeries1.axisX.reverse == true, "AxisX reverse"); | |
|
55 | lineSeries1.axisX.reverse = false; | |
|
56 | verify(lineSeries1.axisX.reverse == false, "AxisX reverse"); | |
|
49 | 57 | } |
|
50 | 58 | |
|
51 | 59 | function test_signals() { |
|
52 | 60 | axisLabelsPositionSpy.clear(); |
|
61 | reverseChangedSpy.clear(); | |
|
53 | 62 | lineSeries1.axisY.labelsPosition = CategoryAxis.AxisLabelsPositionOnValue; |
|
54 | compare(axisLabelsPositionSpy.count, 1, "onLabelsPositionChanged") | |
|
63 | compare(axisLabelsPositionSpy.count, 1, "onLabelsPositionChanged"); | |
|
64 | ||
|
65 | lineSeries1.axisX.reverse = true; | |
|
66 | compare(reverseChangedSpy.count, 1, "onReverseChanged"); | |
|
67 | ||
|
68 | // restore original values | |
|
69 | lineSeries1.axisX.reverse = false; | |
|
70 | compare(reverseChangedSpy.count, 2, "onReverseChanged"); | |
|
55 | 71 | } |
|
56 | 72 | } |
|
57 | 73 | |
@@ -93,5 +109,10 Rectangle { | |||
|
93 | 109 | XYPoint { x: 0; y: 0 } |
|
94 | 110 | XYPoint { x: 5; y: 5 } |
|
95 | 111 | } |
|
112 | SignalSpy { | |
|
113 | id: reverseChangedSpy | |
|
114 | target: axisX | |
|
115 | signalName: "reverseChanged" | |
|
116 | } | |
|
96 | 117 | } |
|
97 | 118 | } |
@@ -40,10 +40,16 Rectangle { | |||
|
40 | 40 | verify(axisX.tickCount == 5, "AxisX tick count"); |
|
41 | 41 | verify(axisY.tickCount == 5, "AxisY tick count"); |
|
42 | 42 | verify(axisX.labelFormat == "", "label format"); |
|
43 | verify(axisX.reverse == false, "AxisX reverse"); | |
|
44 | verify(axisY.reverse == false, "AxisY reverse"); | |
|
43 | 45 | |
|
44 | 46 | // Modify properties |
|
45 | 47 | axisX.tickCount = 3; |
|
46 | 48 | verify(axisX.tickCount == 3, "set tick count"); |
|
49 | axisX.reverse = true; | |
|
50 | verify(axisX.reverse == true, "AxisX reverse"); | |
|
51 | axisX.reverse = false; | |
|
52 | verify(axisX.reverse == false, "AxisX reverse"); | |
|
47 | 53 | } |
|
48 | 54 | |
|
49 | 55 | function test_functions() { |
@@ -67,6 +73,8 Rectangle { | |||
|
67 | 73 | function test_signals() { |
|
68 | 74 | minChangedSpy.clear(); |
|
69 | 75 | maxChangedSpy.clear(); |
|
76 | reverseChangedSpy.clear(); | |
|
77 | ||
|
70 | 78 | axisX.min = 2; |
|
71 | 79 | compare(minChangedSpy.count, 1, "onMinChanged"); |
|
72 | 80 | compare(maxChangedSpy.count, 0, "onMaxChanged"); |
@@ -75,11 +83,16 Rectangle { | |||
|
75 | 83 | compare(minChangedSpy.count, 1, "onMinChanged"); |
|
76 | 84 | compare(maxChangedSpy.count, 1, "onMaxChanged"); |
|
77 | 85 | |
|
86 | axisX.reverse = true; | |
|
87 | compare(reverseChangedSpy.count, 1, "onReverseChanged"); | |
|
88 | ||
|
78 | 89 | // restore original values |
|
79 | 90 | axisX.min = 0; |
|
80 | 91 | axisX.max = 10; |
|
92 | axisX.reverse = false; | |
|
81 | 93 | compare(minChangedSpy.count, 2, "onMinChanged"); |
|
82 | 94 | compare(maxChangedSpy.count, 2, "onMaxChanged"); |
|
95 | compare(reverseChangedSpy.count, 2, "onReverseChanged"); | |
|
83 | 96 | } |
|
84 | 97 | } |
|
85 | 98 | |
@@ -110,5 +123,10 Rectangle { | |||
|
110 | 123 | target: axisX |
|
111 | 124 | signalName: "maxChanged" |
|
112 | 125 | } |
|
126 | SignalSpy { | |
|
127 | id: reverseChangedSpy | |
|
128 | target: axisX | |
|
129 | signalName: "reverseChanged" | |
|
130 | } | |
|
113 | 131 | } |
|
114 | 132 | } |
@@ -59,6 +59,7 private slots: | |||
|
59 | 59 | void noautoscale(); |
|
60 | 60 | void autoscale_data(); |
|
61 | 61 | void autoscale(); |
|
62 | void reverse(); | |
|
62 | 63 | |
|
63 | 64 | private: |
|
64 | 65 | QValueAxis* m_valuesaxis; |
@@ -113,6 +114,8 void tst_QValueAxis::qvalueaxis() | |||
|
113 | 114 | QVERIFY(!qFuzzyCompare(m_valuesaxis->max(), 0)); |
|
114 | 115 | QVERIFY(!qFuzzyCompare(m_valuesaxis->min(), 0)); |
|
115 | 116 | QCOMPARE(m_valuesaxis->tickCount(), 5); |
|
117 | ||
|
118 | QCOMPARE(m_valuesaxis->isReverse(), false); | |
|
116 | 119 | } |
|
117 | 120 | |
|
118 | 121 | void tst_QValueAxis::max_raw_data() |
@@ -406,6 +409,22 void tst_QValueAxis::autoscale() | |||
|
406 | 409 | QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), 100), "Max not equal"); |
|
407 | 410 | } |
|
408 | 411 | |
|
412 | void tst_QValueAxis::reverse() | |
|
413 | { | |
|
414 | QSignalSpy spy(m_valuesaxis, SIGNAL(reverseChanged(bool))); | |
|
415 | QCOMPARE(m_valuesaxis->isReverse(), false); | |
|
416 | ||
|
417 | m_valuesaxis->setReverse(); | |
|
418 | QCOMPARE(m_valuesaxis->isReverse(), true); | |
|
419 | ||
|
420 | m_chart->setAxisX(m_valuesaxis, m_series); | |
|
421 | QCOMPARE(spy.count(), 1); | |
|
422 | ||
|
423 | m_view->show(); | |
|
424 | QTest::qWaitForWindowShown(m_view); | |
|
425 | QCOMPARE(m_valuesaxis->isReverse(), true); | |
|
426 | } | |
|
427 | ||
|
409 | 428 | QTEST_MAIN(tst_QValueAxis) |
|
410 | 429 | #include "tst_qvalueaxis.moc" |
|
411 | 430 |
@@ -23,23 +23,13 ChartView { | |||
|
23 | 23 | id: chartView |
|
24 | 24 | title: "chart axes" |
|
25 | 25 | |
|
26 | // TODO: Do we need a property for orientation or properties "axisX" and "axisY" on ChartView | |
|
27 | // to make an axis the default axis for all series with no other axes defined...? | |
|
28 | // ValueAxis { | |
|
29 | // orientation: ValueAxis.AxisX | |
|
30 | // min: 0 | |
|
31 | // max: 10 | |
|
32 | // } | |
|
33 | // axisX: ValueAxis { | |
|
34 | // min: 0 | |
|
35 | // max: 10 | |
|
36 | // } | |
|
37 | // ...Now that we don't have this implementation, the following axes won't have any affect: | |
|
38 | 26 |
|
|
27 | id: valueAxisX | |
|
39 | 28 | min: 0 |
|
40 | 29 | max: 10 |
|
41 | 30 | } |
|
42 | 31 | ValueAxis { |
|
32 | id: valueAxisY | |
|
43 | 33 | min: 0 |
|
44 | 34 | max: 5 |
|
45 | 35 | } |
@@ -51,6 +41,8 ChartView { | |||
|
51 | 41 | XYPoint { x: 2; y: 2 } |
|
52 | 42 | XYPoint { x: 3; y: 3 } |
|
53 | 43 | XYPoint { x: 4; y: 4 } |
|
44 | axisX: valueAxisX | |
|
45 | axisY: valueAxisY | |
|
54 | 46 | } |
|
55 | 47 | |
|
56 | 48 | ScatterSeries { |
@@ -64,6 +56,8 ChartView { | |||
|
64 | 56 | XYPoint { x: 2; y: 2 } |
|
65 | 57 | XYPoint { x: 3; y: 3 } |
|
66 | 58 | XYPoint { x: 4; y: 4 } |
|
59 | axisX: valueAxisX | |
|
60 | axisY: valueAxisY | |
|
67 | 61 | } |
|
68 | 62 | |
|
69 | 63 | // Component.onCompleted: { |
@@ -24,10 +24,12 ChartView { | |||
|
24 | 24 | title: "chart axes reverted" |
|
25 | 25 | |
|
26 | 26 | ValueAxis { |
|
27 | id: valueAxisX | |
|
27 | 28 | min: 0 |
|
28 | 29 | max: 10 |
|
29 | 30 | } |
|
30 | 31 | ValueAxis { |
|
32 | id: valueAxisY | |
|
31 | 33 | min: 0 |
|
32 | 34 | max: 5 |
|
33 | 35 | } |
@@ -43,6 +45,8 ChartView { | |||
|
43 | 45 | XYPoint { x: 2; y: 2 } |
|
44 | 46 | XYPoint { x: 3; y: 3 } |
|
45 | 47 | XYPoint { x: 4; y: 4 } |
|
48 | axisX: valueAxisX | |
|
49 | axisY: valueAxisY | |
|
46 | 50 | } |
|
47 | 51 | |
|
48 | 52 | LineSeries { |
@@ -52,5 +56,7 ChartView { | |||
|
52 | 56 | XYPoint { x: 2; y: 2 } |
|
53 | 57 | XYPoint { x: 3; y: 3 } |
|
54 | 58 | XYPoint { x: 4; y: 4 } |
|
59 | axisX: valueAxisX | |
|
60 | axisY: valueAxisY | |
|
55 | 61 | } |
|
56 | 62 | } |
@@ -34,6 +34,8 ChartView { | |||
|
34 | 34 | XYPoint { x: 2.9; y: 4.9 } |
|
35 | 35 | XYPoint { x: 3.4; y: 3.0 } |
|
36 | 36 | XYPoint { x: 4.1; y: 3.3 } |
|
37 | axisX: axisX | |
|
38 | axisY: axisY | |
|
37 | 39 | } |
|
38 | 40 | |
|
39 | 41 | onVisibleChanged: console.log("chart.onVisibleChanged: " + visible); |
@@ -65,6 +67,7 ChartView { | |||
|
65 | 67 | } |
|
66 | 68 | |
|
67 | 69 | ValueAxis{ |
|
70 | id: axisX | |
|
68 | 71 | onColorChanged: console.log("axisX.onColorChanged: " + color); |
|
69 | 72 | onLabelsVisibleChanged: console.log("axisX.onLabelsVisibleChanged: " + visible); |
|
70 | 73 | onLabelsColorChanged: console.log("axisX.onLabelsColorChanged: " + color); |
@@ -75,9 +78,11 ChartView { | |||
|
75 | 78 | onShadesBorderColorChanged: console.log("axisX.onShadesBorderColorChanged: " + color); |
|
76 | 79 | onMinChanged: console.log("axisX.onMinChanged: " + min); |
|
77 | 80 | onMaxChanged: console.log("axisX.onMaxChanged: " + max); |
|
81 | onReverseChanged: console.log("axisX.onReverseChanged: " + reverse); | |
|
78 | 82 | } |
|
79 | 83 | |
|
80 | 84 | ValueAxis{ |
|
85 | id: axisY | |
|
81 | 86 | onColorChanged: console.log("axisY.onColorChanged: " + color); |
|
82 | 87 | onLabelsVisibleChanged: console.log("axisY.onLabelsVisibleChanged: " + visible); |
|
83 | 88 | onLabelsColorChanged: console.log("axisY.onLabelsColorChanged: " + color); |
@@ -88,6 +93,7 ChartView { | |||
|
88 | 93 | onShadesBorderColorChanged: console.log("axisY.onShadesBorderColorChanged: " + color); |
|
89 | 94 | onMinChanged: console.log("axisY.onMinChanged: " + min); |
|
90 | 95 | onMaxChanged: console.log("axisY.onMaxChanged: " + max); |
|
96 | onReverseChanged: console.log("axisY.onReverseChanged: " + reverse); | |
|
91 | 97 | } |
|
92 | 98 | |
|
93 | 99 | Rectangle { |
General Comments 0
You need to be logged in to leave comments.
Login now