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 <QtTest/QtTest>
31#include <QtCharts/QChartView>
32#include <QtCharts/QLegend>
33#include <QtCharts/QPieSeries>
34#include <QtCharts/QPieLegendMarker>
35#include <QtCharts/QAreaSeries>
36#include <QtCharts/QAreaLegendMarker>
37#include <QtCharts/QLineSeries>
38#include <QtCharts/QXYLegendMarker>
39#include <QtCharts/QScatterSeries>
40#include <QtCharts/QBarSeries>
41#include <QtCharts/QBarSet>
42#include <QtCharts/QBarLegendMarker>
43#include "tst_definitions.h"
44
45QT_CHARTS_USE_NAMESPACE
46
47class tst_QLegend : public QObject
48{
49 Q_OBJECT
50
51public slots:
52 void initTestCase();
53 void cleanupTestCase();
54 void init();
55 void cleanup();
56
57private slots:
58 void qlegend();
59 void qpieLegendMarker();
60 void qareaLegendMarker();
61 void qxyLegendMarker();
62 void qbarLegendMarker();
63 void markers();
64 void addAndRemoveSeries();
65 void pieMarkerProperties();
66 void barMarkerProperties();
67 void areaMarkerProperties();
68 void xyMarkerPropertiesLine();
69 void xyMarkerPropertiesScatter();
70 void markerSignals();
71
72private:
73
74 QChart *m_chart;
75};
76
77void tst_QLegend::initTestCase()
78{
79}
80
81void tst_QLegend::cleanupTestCase()
82{
83 QTest::qWait(ms: 1); // Allow final deleteLaters to run
84}
85
86void tst_QLegend::init()
87{
88 m_chart = newQChartOrQPolarChart();
89}
90
91void tst_QLegend::cleanup()
92{
93 delete m_chart;
94 m_chart = 0;
95}
96
97void tst_QLegend::qlegend()
98{
99 QVERIFY(m_chart);
100
101 QLegend *legend = m_chart->legend();
102 QVERIFY(legend);
103
104 QList<QLegendMarker*> markers = legend->markers();
105 QVERIFY(markers.count() == 0);
106}
107
108void tst_QLegend::qpieLegendMarker()
109{
110 SKIP_ON_POLAR();
111
112 QVERIFY(m_chart);
113 QLegend *legend = m_chart->legend();
114
115 QPieSeries *series = new QPieSeries();
116 QPieSlice *s1 = new QPieSlice(QString("s1"), 111.0);
117 series->append(slice: s1);
118 m_chart->addSeries(series);
119
120 // Should have one marker
121 QList<QLegendMarker*> markers = legend->markers();
122 QVERIFY(markers.count() == 1);
123 QLegendMarker *m = markers.at(i: 0);
124
125 // Should be piemarker
126 QVERIFY(m->type() == QLegendMarker::LegendMarkerTypePie);
127
128 // Related series and slice must match
129 QPieLegendMarker *pm = qobject_cast<QPieLegendMarker *> (object: m);
130 QVERIFY(pm);
131 QVERIFY(pm->series() == series);
132 QVERIFY(pm->slice() == s1);
133
134 // Add another slice
135 QPieSlice *s2 = new QPieSlice(QString("s2"), 111.0);
136 series->append(slice: s2);
137
138 markers = legend->markers();
139 QVERIFY(markers.count() == 2);
140 m = markers.at(i: 1);
141
142 QVERIFY(m->type() == QLegendMarker::LegendMarkerTypePie);
143
144 // Related series and slice must match
145 pm = qobject_cast<QPieLegendMarker *> (object: m);
146 QVERIFY(pm);
147 QVERIFY(pm->series() == series);
148 QVERIFY(pm->slice() == s2);
149}
150
151void tst_QLegend::qareaLegendMarker()
152{
153 QVERIFY(m_chart);
154 QLegend *legend = m_chart->legend();
155 QAreaSeries *series = new QAreaSeries();
156
157 QLineSeries *upper = new QLineSeries(series);
158 QLineSeries *lower = new QLineSeries(series);
159
160 upper->append(x: 1,y: 1);
161 lower->append(x: 1,y: 0);
162
163 series->setUpperSeries(upper);
164 series->setLowerSeries(lower);
165
166 m_chart->addSeries(series);
167
168 // Should have one marker
169 QList<QLegendMarker *> markers = legend->markers();
170 QVERIFY(markers.count() == 1);
171 QLegendMarker *m = markers.at(i: 0);
172
173 QVERIFY(m->series() == series);
174 QVERIFY(m->type() == QLegendMarker::LegendMarkerTypeArea);
175
176 QAreaLegendMarker *pm = qobject_cast<QAreaLegendMarker *> (object: m);
177 QVERIFY(pm);
178 QVERIFY(pm->series() == series);
179}
180
181void tst_QLegend::qxyLegendMarker()
182{
183 QVERIFY(m_chart);
184 QLegend *legend = m_chart->legend();
185
186 QLineSeries *series = new QLineSeries();
187 m_chart->addSeries(series);
188
189 // Should have one marker
190 QList<QLegendMarker *> markers = legend->markers();
191 QVERIFY(markers.count() == 1);
192 QLegendMarker *m = markers.at(i: 0);
193
194 QVERIFY(m->series() == series);
195 QVERIFY(m->type() == QLegendMarker::LegendMarkerTypeXY);
196
197 QXYLegendMarker *pm = qobject_cast<QXYLegendMarker *> (object: m);
198 QVERIFY(pm);
199 QVERIFY(pm->series() == series);
200}
201
202void tst_QLegend::qbarLegendMarker()
203{
204 SKIP_ON_POLAR();
205
206 QVERIFY(m_chart);
207 QLegend *legend = m_chart->legend();
208
209 QBarSeries *series = new QBarSeries();
210 QBarSet *set0 = new QBarSet(QString("set0"));
211 series->append(set: set0);
212 m_chart->addSeries(series);
213
214 // Should have one marker
215 QList<QLegendMarker *> markers = legend->markers();
216 QVERIFY(markers.count() == 1);
217 QLegendMarker *m = markers.at(i: 0);
218
219 QVERIFY(m->series() == series);
220 QVERIFY(m->type() == QLegendMarker::LegendMarkerTypeBar);
221
222 QBarLegendMarker *pm = qobject_cast<QBarLegendMarker *> (object: m);
223 QVERIFY(pm);
224 QVERIFY(pm->series() == series);
225 QVERIFY(pm->barset() == set0);
226
227 // Add another barset
228 QBarSet *set1 = new QBarSet(QString("set1"));
229 series->append(set: set1);
230
231 markers = legend->markers();
232 QVERIFY(markers.count() == 2);
233 m = markers.at(i: 1);
234
235 QVERIFY(m->series() == series);
236 QVERIFY(m->type() == QLegendMarker::LegendMarkerTypeBar);
237
238 pm = qobject_cast<QBarLegendMarker *> (object: m);
239 QVERIFY(pm);
240 QVERIFY(pm->series() == series);
241 QVERIFY(pm->barset() == set1);
242}
243
244void tst_QLegend::markers()
245{
246 SKIP_ON_POLAR();
247
248 QVERIFY(m_chart);
249 QLegend *legend = m_chart->legend();
250
251 QPieSeries *pie = new QPieSeries();
252 pie->append(label: QString("slice1"), value: 1);
253 pie->append(label: QString("slice2"), value: 2);
254 pie->append(label: QString("slice3"), value: 3);
255 m_chart->addSeries(series: pie);
256 QList<QPieSlice *> slices = pie->slices();
257
258 QBarSeries *bar = new QBarSeries();
259 QList<QBarSet *> sets;
260 sets.append(t: new QBarSet(QString("set0")));
261 sets.append(t: new QBarSet(QString("set1")));
262 bar->append(sets);
263 m_chart->addSeries(series: bar);
264
265 QLineSeries *line = new QLineSeries();
266 line->setName(QString("line1"));
267 m_chart->addSeries(series: line);
268
269 QAreaSeries *area = new QAreaSeries();
270 QLineSeries *upper = new QLineSeries(area);
271 QLineSeries *lower = new QLineSeries(area);
272 upper->append(x: 1,y: 1);
273 lower->append(x: 1,y: 0);
274 area->setUpperSeries(upper);
275 area->setLowerSeries(lower);
276
277 m_chart->addSeries(series: area);
278
279 QVERIFY(legend->markers(pie).count() == 3);
280 QVERIFY(legend->markers(bar).count() == 2);
281 QVERIFY(legend->markers(line).count() == 1);
282 QVERIFY(legend->markers(area).count() == 1);
283 QVERIFY(legend->markers().count() == 3+2+1+1);
284}
285
286void tst_QLegend::addAndRemoveSeries()
287{
288 SKIP_ON_POLAR();
289
290 QVERIFY(m_chart);
291 QLegend *legend = m_chart->legend();
292
293 QPieSeries *pie = new QPieSeries();
294 pie->append(label: QString("slice1"), value: 1);
295 pie->append(label: QString("slice2"), value: 2);
296 pie->append(label: QString("slice3"), value: 3);
297
298 m_chart->addSeries(series: pie);
299
300 QList<QLegendMarker *> markers = legend->markers();
301 QVERIFY(markers.count() == 3);
302
303 m_chart->removeSeries(series: pie);
304
305 markers = legend->markers();
306 QVERIFY(markers.count() == 0);
307
308 delete pie;
309}
310
311void tst_QLegend::pieMarkerProperties()
312{
313 SKIP_ON_POLAR();
314
315 QVERIFY(m_chart);
316 QLegend *legend = m_chart->legend();
317
318 QPieSeries *pie = new QPieSeries();
319 QPieSlice *slice = pie->append(label: QString("Slice1"), value: 1);
320 m_chart->addSeries(series: pie);
321
322 QLegendMarker *m = legend->markers(series: pie).at(i: 0);
323 QPieLegendMarker *pm = qobject_cast<QPieLegendMarker *> (object: m);
324 QVERIFY(pm);
325
326 QBrush b1(QColor(12,34,56,78));
327 QBrush b2(QColor(34,56,78,90));
328
329 // Change brush
330 slice->setBrush(b1);
331 QVERIFY(pm->brush() == b1);
332 slice->setBrush(b2);
333 QVERIFY(pm->brush() == b2);
334
335 // Change label
336 QVERIFY(pm->label().compare(QString("Slice1")) == 0);
337 slice->setLabel(QString("foo"));
338 QVERIFY(pm->label().compare(QString("foo")) == 0);
339 slice->setLabel(QString("bar"));
340 QVERIFY(pm->label().compare(QString("bar")) == 0);
341
342 // Change visibility
343 pie->setVisible(false);
344 TRY_COMPARE(pm->isVisible(), false);
345 pie->setVisible(true);
346 TRY_COMPARE(pm->isVisible(), true);
347}
348
349void tst_QLegend::barMarkerProperties()
350{
351 SKIP_ON_POLAR();
352
353 QVERIFY(m_chart);
354 QLegend *legend = m_chart->legend();
355
356 QBarSeries *bar = new QBarSeries();
357 QBarSet *barSet = new QBarSet(QString("Set0"));
358 *barSet << 1;
359 bar->append(set: barSet);
360 m_chart->addSeries(series: bar);
361
362 QLegendMarker *m = legend->markers(series: bar).at(i: 0);
363 QBarLegendMarker *pm = qobject_cast<QBarLegendMarker *> (object: m);
364 QVERIFY(pm);
365
366 QBrush b1(QColor(12,34,56,78));
367 QBrush b2(QColor(34,56,78,90));
368
369 // Change brush
370 barSet->setBrush(b1);
371 QVERIFY(pm->brush() == b1);
372 barSet->setBrush(b2);
373 QVERIFY(pm->brush() == b2);
374
375 // Change label
376 QVERIFY(pm->label().compare(QString("Set0")) == 0);
377 barSet->setLabel(QString("foo"));
378 QVERIFY(pm->label().compare(QString("foo")) == 0);
379 barSet->setLabel(QString("bar"));
380 QVERIFY(pm->label().compare(QString("bar")) == 0);
381
382 // Change visibility
383 bar->setVisible(false);
384 TRY_COMPARE(pm->isVisible(), false);
385 bar->setVisible(true);
386 TRY_COMPARE(pm->isVisible(), true);
387}
388
389void tst_QLegend::areaMarkerProperties()
390{
391 QVERIFY(m_chart);
392 QLegend *legend = m_chart->legend();
393
394 QAreaSeries *area = new QAreaSeries();
395 area->setName(QString("Area"));
396 QLineSeries *upper = new QLineSeries(area);
397 QLineSeries *lower = new QLineSeries(area);
398 upper->append(x: 1,y: 1);
399 lower->append(x: 1,y: 0);
400 area->setUpperSeries(upper);
401 area->setLowerSeries(lower);
402 m_chart->addSeries(series: area);
403
404 QLegendMarker *m = legend->markers(series: area).at(i: 0);
405 QAreaLegendMarker *pm = qobject_cast<QAreaLegendMarker *> (object: m);
406 QVERIFY(pm);
407
408 QBrush b1(QColor(12,34,56,78));
409 QBrush b2(QColor(34,56,78,90));
410
411 // Change brush
412 area->setBrush(b1);
413 QVERIFY(pm->brush() == b1);
414 area->setBrush(b2);
415 QVERIFY(pm->brush() == b2);
416
417 // Change name
418 QVERIFY(pm->label().compare(QString("Area")) == 0);
419 area->setName(QString("foo"));
420 QVERIFY(pm->label().compare(QString("foo")) == 0);
421 area->setName(QString("bar"));
422 QVERIFY(pm->label().compare(QString("bar")) == 0);
423
424 // Change visibility
425 area->setVisible(false);
426 TRY_COMPARE(pm->isVisible(), false);
427 area->setVisible(true);
428 TRY_COMPARE(pm->isVisible(), true);
429}
430
431void tst_QLegend::xyMarkerPropertiesLine()
432{
433 QVERIFY(m_chart);
434 QLegend *legend = m_chart->legend();
435
436 QLineSeries *line = new QLineSeries();
437 line->setName(QString("Line"));
438 line->append(x: 1,y: 1);
439 m_chart->addSeries(series: line);
440
441 QLegendMarker *m = legend->markers(series: line).at(i: 0);
442 QXYLegendMarker *pm = qobject_cast<QXYLegendMarker *> (object: m);
443 QVERIFY(pm);
444
445 // With line series, the marker is colored after pen, not brush
446 QPen b1(QColor(12,34,56,78));
447 QPen b2(QColor(34,56,78,90));
448
449 // Change brush
450 line->setPen(b1);
451 QVERIFY(pm->brush().color() == b1.color());
452 line->setPen(b2);
453 QVERIFY(pm->brush().color() == b2.color());
454
455 // Change name
456 QVERIFY(pm->label().compare(QString("Line")) == 0);
457 line->setName(QString("foo"));
458 QVERIFY(pm->label().compare(QString("foo")) == 0);
459 line->setName(QString("bar"));
460 QVERIFY(pm->label().compare(QString("bar")) == 0);
461
462 // Change visibility
463 line->setVisible(false);
464 TRY_COMPARE(pm->isVisible(), false);
465 line->setVisible(true);
466 TRY_COMPARE(pm->isVisible(), true);
467}
468
469void tst_QLegend::xyMarkerPropertiesScatter()
470{
471 QVERIFY(m_chart);
472 QLegend *legend = m_chart->legend();
473
474 QScatterSeries *scatter = new QScatterSeries();
475 scatter->setName(QString("Scatter"));
476 scatter->append(x: 1,y: 1);
477 m_chart->addSeries(series: scatter);
478
479 QLegendMarker *m = legend->markers(series: scatter).at(i: 0);
480 QXYLegendMarker *pm = qobject_cast<QXYLegendMarker *> (object: m);
481 QVERIFY(pm);
482
483 QBrush b1(QColor(12,34,56,78));
484 QBrush b2(QColor(34,56,78,90));
485
486 // Change brush
487 scatter->setBrush(b1);
488 QVERIFY(pm->brush() == b1);
489 scatter->setBrush(b2);
490 QVERIFY(pm->brush() == b2);
491
492 // Change name
493 QVERIFY(pm->label().compare(QString("Scatter")) == 0);
494 scatter->setName(QString("foo"));
495 QVERIFY(pm->label().compare(QString("foo")) == 0);
496 scatter->setName(QString("bar"));
497 QVERIFY(pm->label().compare(QString("bar")) == 0);
498
499 // Change visibility
500 scatter->setVisible(false);
501 TRY_COMPARE(pm->isVisible(), false);
502 scatter->setVisible(true);
503 TRY_COMPARE(pm->isVisible(), true);
504}
505
506void tst_QLegend::markerSignals()
507{
508 SKIP_ON_POLAR();
509 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
510 SKIP_IF_FLAKY_MOUSE_MOVE();
511
512 QChart *chart = newQChartOrQPolarChart();
513 QLegend *legend = chart->legend();
514
515 QBarSeries *bar = new QBarSeries();
516 QBarSet *set1 = new QBarSet(QString("set 1"));
517 *set1 << 10 << 10 << 10;
518 bar->append(set: set1);
519 QBarSet *set2 = new QBarSet(QString("set 2"));
520 *set2 << 10 << 10 << 10;
521 bar->append(set: set2);
522 chart->addSeries(series: bar);
523
524 QPieSeries *pie = new QPieSeries();
525 pie->append(label: QString("slice1"), value: 1);
526 pie->append(label: QString("slice2"), value: 2);
527 pie->append(label: QString("slice3"), value: 3);
528 chart->addSeries(series: pie);
529 legend->setAlignment(Qt::AlignRight);
530
531 QLineSeries *line = new QLineSeries();
532 line->setName(QString("Line 1"));
533 line->append(x: 1,y: 1);
534 chart->addSeries(series: line);
535
536 QAreaSeries *area = new QAreaSeries();
537 area->setName(QString("Area 1"));
538 QLineSeries *upper = new QLineSeries(area);
539 QLineSeries *lower = new QLineSeries(area);
540 upper->append(x: 2,y: 2);
541 lower->append(x: 1,y: 1);
542 area->setUpperSeries(upper);
543 area->setLowerSeries(lower);
544 chart->addSeries(series: area);
545
546 QScatterSeries *scatter = new QScatterSeries();
547 scatter->setName(QString("Scatter"));
548 scatter->append(x: 3,y: 3);
549 chart->addSeries(series: scatter);
550
551 QList<QSignalSpy *> spies;
552 foreach(QLegendMarker *m, legend->markers()) {
553 QSignalSpy *spy = new QSignalSpy(m, SIGNAL(hovered(bool)));
554 spies.append(t: spy);
555 }
556
557 QChartView view(chart);
558 view.resize(w: 400, h: 400);
559 view.show();
560 QVERIFY(QTest::qWaitForWindowExposed(&view));
561
562 // Sweep mouse over all legend items
563 for (int i = 0; i < 400; i++)
564 QTest::mouseMove(widget: view.viewport(), pos: QPoint(333, i));
565
566 foreach (QSignalSpy *spy, spies)
567 TRY_COMPARE(spy->count(), 2);
568
569 qDeleteAll(c: spies);
570}
571
572QTEST_MAIN(tst_QLegend)
573
574#include "tst_qlegend.moc"
575
576

source code of qtcharts/tests/auto/qlegend/tst_qlegend.cpp