1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Charts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include "../qabstractaxis/tst_qabstractaxis.h"
31#include <QtCharts/QValueAxis>
32#include <QtCharts/QLineSeries>
33
34class tst_QValueAxis: public tst_QAbstractAxis
35{
36Q_OBJECT
37
38public slots:
39 void init();
40 void cleanup() override;
41
42private slots:
43 void qvalueaxis_data();
44 void qvalueaxis();
45 void max_raw_data();
46 void max_raw();
47 void max_data();
48 void max();
49 void max_animation_data();
50 void max_animation();
51 void min_raw_data();
52 void min_raw();
53 void min_data();
54 void min();
55 void min_animation_data();
56 void min_animation();
57 void applyNiceNumbers_data();
58 void applyNiceNumbers();
59 void range_raw_data();
60 void range_raw();
61 void range_data();
62 void range();
63 void range_animation_data();
64 void range_animation();
65 void ticksCount_data();
66 void ticksCount();
67 void noautoscale_data();
68 void noautoscale();
69 void autoscale_data();
70 void autoscale();
71 void reverse();
72 void labels();
73 void dynamicTicks();
74
75private:
76 void removeAxes();
77
78 QValueAxis* m_valuesaxis;
79 QLineSeries* m_series;
80};
81
82void tst_QValueAxis::init()
83{
84 m_valuesaxis = new QValueAxis();
85 m_series = new QLineSeries();
86 *m_series << QPointF(-100, -100) << QPointF(0, 0) << QPointF(100, 100);
87 tst_QAbstractAxis::initAxes(axis: m_valuesaxis,series: m_series);
88 m_chart->addSeries(series: m_series);
89 m_chart->createDefaultAxes();
90}
91
92void tst_QValueAxis::cleanup()
93{
94 removeAxes();
95 delete m_series;
96 delete m_valuesaxis;
97 m_series = 0;
98 m_valuesaxis = 0;
99 tst_QAbstractAxis::cleanup();
100}
101
102void tst_QValueAxis::removeAxes()
103{
104 const auto oldAxes = m_chart->axes(orientation: Qt::Horizontal) + m_chart->axes(orientation: Qt::Vertical);
105 for (auto oldAxis : oldAxes)
106 m_chart->removeAxis(axis: oldAxis);
107}
108
109void tst_QValueAxis::qvalueaxis_data()
110{
111}
112
113void tst_QValueAxis::qvalueaxis()
114{
115 qabstractaxis();
116
117 QVERIFY(qFuzzyCompare(m_valuesaxis->max(), 0));
118 QVERIFY(qFuzzyCompare(m_valuesaxis->min(), 0));
119 QCOMPARE(m_valuesaxis->tickCount(), 5);
120 QCOMPARE(m_valuesaxis->type(), QAbstractAxis::AxisTypeValue);
121
122 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
123 m_series->attachAxis(axis: m_valuesaxis);
124 m_view->show();
125 QVERIFY(QTest::qWaitForWindowExposed(m_view));
126
127 QVERIFY(!qFuzzyCompare(m_valuesaxis->max(), 0));
128 QVERIFY(!qFuzzyCompare(m_valuesaxis->min(), 0));
129 QCOMPARE(m_valuesaxis->tickCount(), 5);
130
131 QCOMPARE(m_valuesaxis->isReverse(), false);
132}
133
134void tst_QValueAxis::max_raw_data()
135{
136 QTest::addColumn<qreal>(name: "max");
137 QTest::newRow(dataTag: "1.0") << (qreal)1.0;
138 QTest::newRow(dataTag: "50.0") << (qreal)50.0;
139 QTest::newRow(dataTag: "101.0") << (qreal)101.0;
140}
141
142void tst_QValueAxis::max_raw()
143{
144 QFETCH(qreal, max);
145
146 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
147 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
148 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
149
150 m_valuesaxis->setMax(max);
151 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), max), "Not equal");
152
153 QCOMPARE(spy0.count(), 1);
154 QCOMPARE(spy1.count(), 0);
155 QCOMPARE(spy2.count(), 1);
156
157}
158
159void tst_QValueAxis::max_data()
160{
161 max_raw_data();
162}
163
164void tst_QValueAxis::max()
165{
166 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
167 m_series->attachAxis(axis: m_valuesaxis);
168 m_view->show();
169 QVERIFY(QTest::qWaitForWindowExposed(m_view));
170 max_raw();
171}
172
173void tst_QValueAxis::max_animation_data()
174{
175 max_data();
176}
177
178void tst_QValueAxis::max_animation()
179{
180 m_chart->setAnimationOptions(QChart::GridAxisAnimations);
181 max();
182}
183
184void tst_QValueAxis::min_raw_data()
185{
186 QTest::addColumn<qreal>(name: "min");
187 QTest::newRow(dataTag: "-1.0") << (qreal)-1.0;
188 QTest::newRow(dataTag: "-50.0") << (qreal)-50.0;
189 QTest::newRow(dataTag: "-101.0") << (qreal)-101.0;
190}
191
192void tst_QValueAxis::min_raw()
193{
194 QFETCH(qreal, min);
195
196 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
197 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
198 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
199
200 m_valuesaxis->setMin(min);
201 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), min), "Not equal");
202
203 QCOMPARE(spy0.count(), 0);
204 QCOMPARE(spy1.count(), 1);
205 QCOMPARE(spy2.count(), 1);
206}
207
208void tst_QValueAxis::min_data()
209{
210 min_raw_data();
211}
212
213void tst_QValueAxis::min()
214{
215 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
216 m_series->attachAxis(axis: m_valuesaxis);
217 m_view->show();
218 QVERIFY(QTest::qWaitForWindowExposed(m_view));
219 min_raw();
220}
221
222void tst_QValueAxis::min_animation_data()
223{
224 min_data();
225}
226
227void tst_QValueAxis::min_animation()
228{
229 m_chart->setAnimationOptions(QChart::GridAxisAnimations);
230 min();
231}
232
233void tst_QValueAxis::applyNiceNumbers_data()
234{
235 QTest::addColumn<bool>(name: "niceNumbersEnabled");
236 QTest::addColumn<qreal>(name: "min");
237 QTest::addColumn<qreal>(name: "max");
238 QTest::addColumn<int>(name: "ticks");
239 QTest::addColumn<qreal>(name: "expectedMin");
240 QTest::addColumn<qreal>(name: "expectedMax");
241 QTest::addColumn<int>(name: "expectedTicks");
242 QTest::newRow(dataTag: "true 0.1 , 99.0 , 5") << true << (qreal)0.1 << (qreal)99.0 << 5 << (qreal)0.0 << (qreal)100.0 << 6;
243 QTest::newRow(dataTag: "true 1 , 10.0 , 5") << true << (qreal)1.0 << (qreal)10.0 << 5 << (qreal)0.0 << (qreal)10.0 << 6;
244 QTest::newRow(dataTag: "true 0.1 , 6.6 , 5") << true << (qreal)0.1 << (qreal)6.6 << 5 << (qreal)0.0 << (qreal)8.0 << 5;
245 QTest::newRow(dataTag: "false 0.1 , 6.6 , 5") << false << (qreal)0.1 << (qreal)6.6 << 5 << (qreal)0.1 << (qreal)6.6 << 5;
246 QTest::newRow(dataTag: "true 0.1, 99, 5") << true << (qreal)0.1 << (qreal)99.0 << 5 << (qreal)0.0 << (qreal)100.0 << 6;
247 QTest::newRow(dataTag: "true 5, 93.5 , 5") << true << (qreal)5.0 << (qreal)93.5 << 5 << (qreal)0.0 << (qreal)100.0 << 6;
248}
249
250void tst_QValueAxis::applyNiceNumbers()
251{
252 QFETCH(bool, niceNumbersEnabled);
253 QFETCH(qreal, min);
254 QFETCH(qreal, max);
255 QFETCH(int, ticks);
256 QFETCH(qreal, expectedMin);
257 QFETCH(qreal, expectedMax);
258 QFETCH(int, expectedTicks);
259
260 m_valuesaxis->setRange(min, max);
261 m_valuesaxis->setTickCount(ticks);
262
263 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), min), "Min not equal");
264 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), max), "Max not equal");
265
266 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
267 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
268 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
269
270 if(niceNumbersEnabled) m_valuesaxis->applyNiceNumbers();
271
272 if(!qFuzzyCompare(p1: expectedMin, p2: min))
273 QCOMPARE(spy1.count(), 1);
274 if(!qFuzzyCompare(p1: expectedMax, p2: max))
275 QCOMPARE(spy0.count(), 1);
276 if((!qFuzzyCompare(p1: expectedMin, p2: min)) || (!qFuzzyCompare(p1: expectedMax, p2: max)))
277 QCOMPARE(spy2.count(), 1);
278
279 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), expectedMin), "Min not equal");
280 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), expectedMax), "Max not equal");
281 QCOMPARE(m_valuesaxis->tickCount(), expectedTicks);
282
283}
284
285void tst_QValueAxis::range_raw_data()
286{
287 QTest::addColumn<qreal>(name: "min");
288 QTest::addColumn<qreal>(name: "max");
289 QTest::newRow(dataTag: "1.0 - 101.0") << (qreal)-1.0 << (qreal)101.0;
290 QTest::newRow(dataTag: "25.0 - 75.0") << (qreal)25.0 << (qreal)75.0;
291 QTest::newRow(dataTag: "101.0") << (qreal)40.0 << (qreal)60.0;
292 QTest::newRow(dataTag: "smallNumbers") << (qreal)-1e-12 << (qreal)1e-13;
293}
294
295void tst_QValueAxis::range_raw()
296{
297 QFETCH(qreal, min);
298 QFETCH(qreal, max);
299
300 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
301 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
302 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
303
304 m_valuesaxis->setRange(min, max);
305 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), min), "Min not equal");
306 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), max), "Max not equal");
307
308 QCOMPARE(spy0.count(), 1);
309 QCOMPARE(spy1.count(), 1);
310 QCOMPARE(spy2.count(), 1);
311}
312
313void tst_QValueAxis::range_data()
314{
315 range_raw_data();
316}
317
318void tst_QValueAxis::range()
319{
320 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
321 m_series->attachAxis(axis: m_valuesaxis);
322 m_view->show();
323 QVERIFY(QTest::qWaitForWindowExposed(m_view));
324 range_raw();
325}
326
327void tst_QValueAxis::range_animation_data()
328{
329 range_data();
330}
331
332void tst_QValueAxis::range_animation()
333{
334 m_chart->setAnimationOptions(QChart::GridAxisAnimations);
335 range();
336}
337
338void tst_QValueAxis::ticksCount_data()
339{
340 QTest::addColumn<int>(name: "ticksCount");
341 QTest::addColumn<int>(name: "expectedCount");
342 QTest::newRow(dataTag: "0") << 2;
343 QTest::newRow(dataTag: "1") << 2;
344 QTest::newRow(dataTag: "2") << 2;
345 QTest::newRow(dataTag: "3") << 3;
346 QTest::newRow(dataTag: "-1") << 2;
347}
348
349void tst_QValueAxis::ticksCount()
350{
351 QFETCH(int, ticksCount);
352
353 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
354 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
355 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
356
357 m_valuesaxis->setTickCount(ticksCount);
358 QCOMPARE(m_valuesaxis->tickCount(), ticksCount);
359
360 QCOMPARE(spy0.count(), 0);
361 QCOMPARE(spy1.count(), 0);
362 QCOMPARE(spy2.count(), 0);
363
364 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
365 m_series->attachAxis(axis: m_valuesaxis);
366 m_view->show();
367 QVERIFY(QTest::qWaitForWindowExposed(m_view));
368
369 QCOMPARE(m_valuesaxis->tickCount(), ticksCount);
370}
371
372void tst_QValueAxis::noautoscale_data()
373{
374 QTest::addColumn<qreal>(name: "min");
375 QTest::addColumn<qreal>(name: "max");
376 QTest::newRow(dataTag: "1.0 - 101.0") << (qreal)-1.0 << (qreal)101.0;
377 QTest::newRow(dataTag: "25.0 - 75.0") << (qreal)25.0 << (qreal)75.0;
378 QTest::newRow(dataTag: "101.0") << (qreal)40.0 << (qreal)60.0;
379}
380
381void tst_QValueAxis::noautoscale()
382{
383 QFETCH(qreal, min);
384 QFETCH(qreal, max);
385
386 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
387 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
388 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
389
390 m_valuesaxis->setRange(min, max);
391 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), min), "Min not equal");
392 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), max), "Max not equal");
393
394 QCOMPARE(spy0.count(), 1);
395 QCOMPARE(spy1.count(), 1);
396 QCOMPARE(spy2.count(), 1);
397
398 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
399 m_series->attachAxis(axis: m_valuesaxis);
400 m_view->show();
401 QVERIFY(QTest::qWaitForWindowExposed(m_view));
402 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), min), "Min not equal");
403 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), max), "Max not equal");
404}
405
406void tst_QValueAxis::autoscale_data()
407{
408
409}
410
411void tst_QValueAxis::autoscale()
412{
413 QSignalSpy spy0(m_valuesaxis, SIGNAL(maxChanged(qreal)));
414 QSignalSpy spy1(m_valuesaxis, SIGNAL(minChanged(qreal)));
415 QSignalSpy spy2(m_valuesaxis, SIGNAL(rangeChanged(qreal,qreal)));
416
417 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), 0), "Min not equal");
418 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), 0), "Max not equal");
419 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
420 m_series->attachAxis(axis: m_valuesaxis);
421
422 QCOMPARE(spy0.count(), 1);
423 QCOMPARE(spy1.count(), 1);
424 QCOMPARE(spy2.count(), 1);
425
426 m_view->show();
427 QVERIFY(QTest::qWaitForWindowExposed(m_view));
428 QVERIFY2(qFuzzyCompare(m_valuesaxis->min(), -100), "Min not equal");
429 QVERIFY2(qFuzzyCompare(m_valuesaxis->max(), 100), "Max not equal");
430}
431
432void tst_QValueAxis::reverse()
433{
434 QSignalSpy spy(m_valuesaxis, SIGNAL(reverseChanged(bool)));
435 QCOMPARE(m_valuesaxis->isReverse(), false);
436
437 m_valuesaxis->setReverse();
438 QCOMPARE(m_valuesaxis->isReverse(), true);
439
440 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
441 m_series->attachAxis(axis: m_valuesaxis);
442 QCOMPARE(spy.count(), 1);
443
444 m_view->show();
445 QVERIFY(QTest::qWaitForWindowExposed(m_view));
446 QCOMPARE(m_valuesaxis->isReverse(), true);
447}
448
449void tst_QValueAxis::labels()
450{
451 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
452 m_series->attachAxis(axis: m_valuesaxis);
453 m_view->resize(w: 300, h: 300);
454 m_view->show();
455 QVERIFY(QTest::qWaitForWindowExposed(m_view));
456
457 QList<QGraphicsItem *> childItems = m_chart->scene()->items();
458 QList<QGraphicsTextItem *> textItems;
459 QStringList originalStrings;
460 for (QGraphicsItem *i : childItems) {
461 if (QGraphicsTextItem *text = qgraphicsitem_cast<QGraphicsTextItem *>(item: i)) {
462 if (text->parentItem() != m_chart) {
463 textItems << text;
464 originalStrings << text->toPlainText();
465 }
466 }
467 }
468 m_valuesaxis->setLabelFormat("%.0f");
469 // Wait for the format to have updated
470 QTest::qWait(ms: 100);
471 QStringList updatedStrings;
472 for (QGraphicsTextItem *i : textItems)
473 updatedStrings << i->toPlainText();
474 // The order will be the same as we kept the order of the items
475 QVERIFY(originalStrings != updatedStrings);
476 updatedStrings.clear();
477 // The labels should be back to the original defaults
478 m_valuesaxis->setLabelFormat("");
479 QTest::qWait(ms: 100);
480 for (QGraphicsTextItem *i : textItems)
481 updatedStrings << i->toPlainText();
482 QCOMPARE(originalStrings, updatedStrings);
483}
484
485void tst_QValueAxis::dynamicTicks()
486{
487 removeAxes(); // remove default axes created by init()
488 QValueAxis *valuesaxis = new QValueAxis();
489 m_chart->addAxis(axis: m_valuesaxis, alignment: Qt::AlignBottom);
490 m_series->attachAxis(axis: m_valuesaxis);
491 m_chart->addAxis(axis: valuesaxis, alignment: Qt::AlignLeft);
492 m_series->attachAxis(axis: valuesaxis);
493 m_view->resize(w: 400, h: 400);
494 m_valuesaxis->setRange(min: -111.0, max: 111);
495 m_valuesaxis->setTickType(QValueAxis::TicksDynamic);
496 m_valuesaxis->setTickAnchor(100.0);
497 m_valuesaxis->setTickInterval(100.0);
498 valuesaxis->setRange(min: -111.0, max: 111);
499 valuesaxis->setTickType(QValueAxis::TicksDynamic);
500 valuesaxis->setTickAnchor(100.0);
501 valuesaxis->setTickInterval(50.0);
502 valuesaxis->setLabelFormat("%.2f");
503 m_view->show();
504 QTest::qWaitForWindowShown(window: m_view);
505
506 QStringList expectedList;
507 expectedList << "" << "100.00" << "50.00" << "0.00" << "-50.00" << "-100.00" <<
508 "100.0" << "0.0" << "-100.0";
509
510 QList<QGraphicsItem *> childItems = m_chart->scene()->items();
511 QList<QGraphicsTextItem *> textItems;
512 QStringList observedStrings;
513 for (QGraphicsItem *i : childItems) {
514 if (QGraphicsTextItem *text = qgraphicsitem_cast<QGraphicsTextItem *>(item: i)) {
515 if (text->parentItem() != m_chart) {
516 textItems << text;
517 observedStrings << text->toPlainText();
518 }
519 }
520 }
521
522 QCOMPARE(observedStrings, expectedList);
523}
524
525QTEST_MAIN(tst_QValueAxis)
526#include "tst_qvalueaxis.moc"
527
528

source code of qtcharts/tests/auto/qvalueaxis/tst_qvalueaxis.cpp