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