##// END OF EJS Templates
Add possibility to set reverse values to axes...
Titta Heikkala -
r2781:7c9f8e5a27d8
parent child
Show More
@@ -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));
217 position.setX(position.x() - pointLabelWidth / 2);
222 if (!seriesPrivate()->reverseXAxis())
218 position.setY(position.y() - m_series->upperSeries()->pen().width() / 2 - labelOffset);
223 position.setX(position.x() - pointLabelWidth / 2);
219
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 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));
235 position.setX(position.x() - pointLabelWidth / 2);
248 if (!seriesPrivate()->reverseXAxis())
236 position.setY(position.y() - m_series->lowerSeries()->pen().width() / 2 - labelOffset);
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 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 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 //label text wrapping
112 //label text wrapping
108 QString text = labelList.at(i);
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 = qMax(layout[i], gridRect.left());
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,7 +205,10 void HorizontalAxis::updateGeometry()
163 }
205 }
164 } else if (categoryAxis->labelsPosition()
206 } else if (categoryAxis->labelsPosition()
165 == QCategoryAxis::AxisLabelsPositionOnValue) {
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 qreal leftBound;
233 qreal leftBound;
189 qreal rightBound;
234 qreal rightBound;
190 if (i == 0) {
235 if (i == 0) {
191 leftBound = gridRect.left();
236 if (axis()->isReverse()) {
192 rightBound = layout[0];
237 leftBound = gridRect.right() + gridRect.left() - layout[i];
193 } else {
194 leftBound = layout[i];
195 if (i == layout.size() - 1)
196 rightBound = gridRect.right();
238 rightBound = gridRect.right();
197 else
239 } else {
198 rightBound = qMin(layout[i + 1], gridRect.right());
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 if (leftBound < gridRect.left())
260 if (leftBound < gridRect.left())
201 leftBound = gridRect.left();
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 \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 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 //label text wrapping
114 //label text wrapping
110 QString text = labelList.at(i);
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(), layout[i], axisRect.left() + labelPadding(), layout[i]);
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 = qMin(layout[i], gridRect.bottom());
182 qreal lowerBound;
147 qreal upperBound = qMax(layout[i + 1], gridRect.top());
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;
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 //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) {
198 lowerBound = gridRect.bottom();
251 if (axis()->isReverse()) {
199 upperBound = layout[0];
200 } else {
201 lowerBound = layout[i];
202 if (i == layout.size() - 1)
203 upperBound = gridRect.top();
252 upperBound = gridRect.top();
204 else
253 lowerBound = gridRect.top() + gridRect.bottom() - layout[i];
205 upperBound = qMax(layout[i + 1], gridRect.top());
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 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 position.setX(position.x() - pointLabelWidth / 2);
854 if (!reverseXAxis())
855 position.setY(position.y() - labelOffset);
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 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 ValueAxis {
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 {
@@ -105,6 +105,10 Row {
105
105
106 onClicked: axis.tickCount--;
106 onClicked: axis.tickCount--;
107 }
107 }
108 Button {
109 text: "axis reverse"
110 onClicked: axis.reverse = !axis.reverse;
111 }
108
112
109 FontEditor {
113 FontEditor {
110 id: fontEditor
114 id: fontEditor
General Comments 0
You need to be logged in to leave comments. Login now