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 <QtCharts/QLegend>
31#include <private/qlegend_p.h>
32#include <QtCharts/QAbstractSeries>
33#include <private/qabstractseries_p.h>
34#include <private/qchart_p.h>
35#include <private/legendlayout_p.h>
36#include <private/chartpresenter_p.h>
37#include <private/abstractchartlayout_p.h>
38#include <QtCharts/QLegendMarker>
39#include <private/qlegendmarker_p.h>
40#include <private/legendmarkeritem_p.h>
41#include <private/chartdataset_p.h>
42#include <QtGui/QPainter>
43#include <QtGui/QPen>
44#include <QtWidgets/QGraphicsItemGroup>
45
46QT_CHARTS_BEGIN_NAMESPACE
47
48/*!
49 \class QLegend
50 \inmodule QtCharts
51 \inherits QGraphicsWidget
52 \brief The QLegend class displays the legend of a chart.
53
54 A legend is a graphical object that displays the legend of a chart. The legend state is updated
55 by QChart when series change. By default, the legend is attached to the chart, but it can be
56 detached to make it independent of chart layout. Legend objects cannot be created or deleted,
57 but they can be referenced via the QChart class.
58
59 \image examples_percentbarchart_legend.png
60
61 \sa QChart
62*/
63/*!
64 \qmltype Legend
65 \instantiates QLegend
66 \inqmlmodule QtCharts
67
68 \brief Displays the legend of a chart.
69
70 A legend is a graphical object that displays the legend of a chart. The legend state is updated
71 by the ChartView type when series change. The \l Legend type properties can be attached to the
72 ChartView type. For example:
73 \code
74 ChartView {
75 legend.visible: true
76 legend.alignment: Qt.AlignBottom
77 // Add a few series...
78 }
79 \endcode
80
81 \image examples_percentbarchart_legend.png
82
83 \note There is no QML API available for modifying legend markers. Markers can be modified by
84 creating a custom legend, as illustrated by \l {qmlcustomlegend}{Qml Custom Example}.
85*/
86
87/*!
88 \property QLegend::alignment
89 \brief How the legend is aligned with the chart.
90
91 Can be Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one
92 flag, the result is undefined.
93*/
94/*!
95 \qmlproperty alignment Legend::alignment
96 Defines how the legend is aligned with the chart. Can be \l{Qt::AlignLeft}{Qt.AlignLeft},
97 \l{Qt::AlignRight}{Qt.AlignRight}, \l{Qt::AlignBottom}{Qt.AlignBottom}, or
98 \l{Qt::AlignTop}{Qt.AlignTop}. If you set more than one flag, the result is undefined.
99*/
100
101/*!
102 \property QLegend::backgroundVisible
103 \brief Whether the legend background is visible.
104*/
105/*!
106 \qmlproperty bool Legend::backgroundVisible
107 Whether the legend background is visible.
108*/
109
110/*!
111 \qmlproperty bool Legend::visible
112 Whether the legend is visible.
113
114 By default, this property is \c true.
115 \sa QGraphicsObject::visible
116*/
117
118/*!
119 \property QLegend::color
120 \brief The background (brush) color of the legend.
121
122 If you change the color of the legend, the style of the legend brush is set to
123 Qt::SolidPattern.
124*/
125/*!
126 \qmlproperty color Legend::color
127 The background (brush) color of the legend.
128*/
129
130/*!
131 \property QLegend::borderColor
132 \brief The line color of the legend.
133*/
134/*!
135 \qmlproperty color Legend::borderColor
136 The line color of the legend.
137*/
138
139/*!
140 \property QLegend::font
141 \brief The font of the markers used by the legend.
142*/
143/*!
144 \qmlproperty Font Legend::font
145 The font of the markers used by the legend.
146*/
147
148/*!
149 \property QLegend::labelColor
150 \brief The color of the brush used to draw labels.
151*/
152/*!
153 \qmlproperty color Legend::labelColor
154 The color of the brush used to draw labels.
155*/
156
157/*!
158 \property QLegend::reverseMarkers
159 \brief Whether reverse order is used for the markers in the legend.
160
161 This property is \c false by default.
162*/
163/*!
164 \qmlproperty bool Legend::reverseMarkers
165 Whether reverse order is used for the markers in the legend. This property
166 is \c false by default.
167*/
168
169/*!
170 \property QLegend::showToolTips
171 \brief Whether tooltips are shown when the text is truncated.
172
173 This property is \c false by default.
174*/
175
176/*!
177 \enum QLegend::MarkerShape
178
179 This enum describes the shape used when rendering legend marker items.
180
181 \value MarkerShapeDefault Default shape determined by QLegend is used for the marker.
182 This value is supported only for individual QLegendMarker items.
183 \value MarkerShapeRectangle Rectangular markers are used.
184 Marker size is determined by font size.
185 \value MarkerShapeCircle Circular markers are used.
186 Marker size is determined by font size.
187 \value MarkerShapeFromSeries The marker shape is determined by the series.
188 In case of a scatter series, the legend marker looks like a scatter dot and is the same
189 size as the dot. In case of a line or spline series, the legend marker looks like a small
190 segment of the line. For other series types, rectangular markers are shown.
191
192 \sa markerShape
193*/
194
195/*!
196 \qmlproperty enumeration Legend::markerShape
197 \since 5.9
198
199 The default shape of the legend markers.
200 The default value is \c{MarkerShapeRectangle}.
201
202 \value Legend.MarkerShapeRectangle Legend markers are rectangular
203 \value Legend.MarkerShapeCircle Legend markers are circular
204 \value Legend.MarkerShapeFromSeries Legend marker shape is determined by the series
205
206 \sa QLegend::MarkerShape
207*/
208
209/*!
210 \property QLegend::markerShape
211 \since 5.9
212
213 The default shape of the legend markers.
214 The default value is \c{MarkerShapeRectangle}.
215*/
216
217/*!
218 \qmlproperty bool Legend::showToolTips
219 Whether tooltips are shown when the text is truncated. This property is \c false by default.
220 This property currently has no effect as there is no support for tooltips in QML.
221*/
222
223/*!
224 \fn void QLegend::backgroundVisibleChanged(bool)
225 This signal is emitted when the visibility of the legend background changes to \a visible.
226*/
227
228/*!
229 \fn void QLegend::colorChanged(QColor)
230 This signal is emitted when the color of the legend background changes to \a color.
231*/
232
233/*!
234 \fn void QLegend::borderColorChanged(QColor)
235 This signal is emitted when the border color of the legend background changes to \a color.
236*/
237
238/*!
239 \fn void QLegend::fontChanged(QFont)
240 This signal is emitted when the font of the markers of the legend changes to \a font.
241*/
242
243/*!
244 \fn void QLegend::labelColorChanged(QColor color)
245 This signal is emitted when the color of the brush used to draw the legend
246 labels changes to \a color.
247*/
248
249/*!
250 \fn void QLegend::reverseMarkersChanged(bool)
251 This signal is emitted when the use of reverse order for the markers in the
252 legend is changed to \a reverseMarkers.
253*/
254
255/*!
256 \fn void QLegend::showToolTipsChanged(bool showToolTips)
257 This signal is emitted when the visibility of tooltips is changed to \a showToolTips.
258*/
259
260QLegend::QLegend(QChart *chart): QGraphicsWidget(chart),
261 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter, chart, this))
262{
263 setZValue(ChartPresenter::LegendZValue);
264 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
265 QObject::connect(sender: chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: d_ptr.data(), SLOT(handleSeriesAdded(QAbstractSeries*)));
266 QObject::connect(sender: chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: d_ptr.data(), SLOT(handleSeriesRemoved(QAbstractSeries*)));
267 setLayout(d_ptr->m_layout);
268}
269
270/*!
271 Destroys the legend object. The legend is always owned by a QChart, so an application
272 should never call this function.
273*/
274QLegend::~QLegend()
275{
276}
277
278/*!
279 \internal
280 */
281void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
282{
283 Q_UNUSED(option)
284 Q_UNUSED(widget)
285
286 if (!d_ptr->m_backgroundVisible)
287 return;
288
289 painter->setOpacity(opacity());
290 painter->setPen(d_ptr->m_pen);
291 painter->setBrush(d_ptr->m_brush);
292 painter->drawRoundedRect(rect: rect(), xRadius: d_ptr->roundness(size: rect().width()), yRadius: d_ptr->roundness(size: rect().height()),
293 mode: Qt::RelativeSize);
294}
295
296
297/*!
298 Sets the \a brush that is used to draw the background of the legend.
299 */
300void QLegend::setBrush(const QBrush &brush)
301{
302 if (d_ptr->m_brush != brush) {
303 d_ptr->m_brush = brush;
304 update();
305 emit colorChanged(color: brush.color());
306 }
307}
308
309/*!
310 Returns the brush used by the legend.
311 */
312QBrush QLegend::brush() const
313{
314 if (d_ptr->m_brush == QChartPrivate::defaultBrush())
315 return QBrush();
316 else
317 return d_ptr->m_brush;
318}
319
320void QLegend::setColor(QColor color)
321{
322 QBrush b = brush();
323 if (b.style() != Qt::SolidPattern || b.color() != color) {
324 b.setStyle(Qt::SolidPattern);
325 b.setColor(color);
326 setBrush(b);
327 }
328}
329
330QColor QLegend::color()
331{
332 return d_ptr->m_brush.color();
333}
334
335/*!
336 Sets the \a pen that is used to draw the legend borders.
337 */
338void QLegend::setPen(const QPen &pen)
339{
340 if (d_ptr->m_pen != pen) {
341 d_ptr->m_pen = pen;
342 update();
343 emit borderColorChanged(color: pen.color());
344 }
345}
346
347/*!
348 Returns the pen used by the legend.
349 */
350
351QPen QLegend::pen() const
352{
353 if (d_ptr->m_pen == QChartPrivate::defaultPen())
354 return QPen();
355 else
356 return d_ptr->m_pen;
357}
358
359void QLegend::setFont(const QFont &font)
360{
361 if (d_ptr->m_font != font) {
362 // Hide items to avoid flickering
363 d_ptr->items()->setVisible(false);
364 d_ptr->m_font = font;
365 foreach (QLegendMarker *marker, d_ptr->markers()) {
366 marker->setFont(d_ptr->m_font);
367 }
368 layout()->invalidate();
369 emit fontChanged(font);
370 }
371}
372
373QFont QLegend::font() const
374{
375 return d_ptr->m_font;
376}
377
378void QLegend::setBorderColor(QColor color)
379{
380 QPen p = pen();
381 if (p.color() != color) {
382 p.setColor(color);
383 setPen(p);
384 }
385}
386
387QColor QLegend::borderColor()
388{
389 return d_ptr->m_pen.color();
390}
391
392/*!
393 Sets the brush used to draw the legend labels to \a brush.
394*/
395void QLegend::setLabelBrush(const QBrush &brush)
396{
397 if (d_ptr->m_labelBrush != brush) {
398 d_ptr->m_labelBrush = brush;
399 foreach (QLegendMarker *marker, d_ptr->markers()) {
400 marker->setLabelBrush(d_ptr->m_labelBrush);
401 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
402 // instead of mapping it from label brush color
403 marker->setPen(brush.color());
404 }
405 emit labelColorChanged(color: brush.color());
406 }
407}
408
409/*!
410 Returns the brush used to draw labels.
411*/
412QBrush QLegend::labelBrush() const
413{
414 if (d_ptr->m_labelBrush == QChartPrivate::defaultBrush())
415 return QBrush();
416 else
417 return d_ptr->m_labelBrush;
418}
419
420void QLegend::setLabelColor(QColor color)
421{
422 QBrush b = labelBrush();
423 if (b.style() != Qt::SolidPattern || b.color() != color) {
424 b.setStyle(Qt::SolidPattern);
425 b.setColor(color);
426 setLabelBrush(b);
427 }
428}
429
430QColor QLegend::labelColor() const
431{
432 return d_ptr->m_labelBrush.color();
433}
434
435
436void QLegend::setAlignment(Qt::Alignment alignment)
437{
438 if (d_ptr->m_alignment != alignment) {
439 d_ptr->m_alignment = alignment;
440 layout()->invalidate();
441 }
442}
443
444Qt::Alignment QLegend::alignment() const
445{
446 return d_ptr->m_alignment;
447}
448
449/*!
450 Detaches the legend from the chart. The chart will no longer adjust the layout of the legend.
451 */
452void QLegend::detachFromChart()
453{
454 d_ptr->m_attachedToChart = false;
455// layout()->invalidate();
456 d_ptr->m_chart->layout()->invalidate();
457 setParent(0);
458
459}
460
461/*!
462 Attaches the legend to a chart. The chart may adjust the layout of the legend.
463 */
464void QLegend::attachToChart()
465{
466 d_ptr->m_attachedToChart = true;
467// layout()->invalidate();
468 d_ptr->m_chart->layout()->invalidate();
469 setParent(d_ptr->m_chart);
470}
471
472/*!
473 Returns \c true, if the legend is attached to a chart.
474 */
475bool QLegend::isAttachedToChart()
476{
477 return d_ptr->m_attachedToChart;
478}
479
480/*!
481 Sets the visibility of the legend background to \a visible.
482 */
483void QLegend::setBackgroundVisible(bool visible)
484{
485 if (d_ptr->m_backgroundVisible != visible) {
486 d_ptr->m_backgroundVisible = visible;
487 update();
488 emit backgroundVisibleChanged(visible);
489 }
490}
491
492/*!
493 Returns the visibility of the legend background.
494 */
495bool QLegend::isBackgroundVisible() const
496{
497 return d_ptr->m_backgroundVisible;
498}
499
500/*!
501 Returns the list of markers in the legend. The list can be filtered by specifying
502 the \a series for which the markers are returned.
503*/
504QList<QLegendMarker*> QLegend::markers(QAbstractSeries *series) const
505{
506 return d_ptr->markers(series);
507}
508
509bool QLegend::reverseMarkers()
510{
511 return d_ptr->m_reverseMarkers;
512}
513
514void QLegend::setReverseMarkers(bool reverseMarkers)
515{
516 if (d_ptr->m_reverseMarkers != reverseMarkers) {
517 d_ptr->m_reverseMarkers = reverseMarkers;
518 layout()->invalidate();
519 emit reverseMarkersChanged(reverseMarkers);
520 }
521}
522
523/*!
524 Returns whether the tooltips are shown for the legend labels
525 when they are elided.
526*/
527
528bool QLegend::showToolTips() const
529{
530 return d_ptr->m_showToolTips;
531}
532
533/*!
534 When \a show is \c true, the legend labels will show a tooltip when
535 the mouse hovers over them if the label itself is shown elided.
536 This is \c false by default.
537*/
538
539void QLegend::setShowToolTips(bool show)
540{
541 if (d_ptr->m_showToolTips != show) {
542 d_ptr->m_showToolTips = show;
543 d_ptr->updateToolTips();
544 emit showToolTipsChanged(showToolTips: show);
545 }
546}
547
548QLegend::MarkerShape QLegend::markerShape() const
549{
550 return d_ptr->m_markerShape;
551}
552
553void QLegend::setMarkerShape(QLegend::MarkerShape shape)
554{
555 QLegend::MarkerShape newShape = shape;
556 if (newShape == MarkerShapeDefault)
557 newShape = MarkerShapeRectangle;
558 if (d_ptr->m_markerShape != newShape) {
559 d_ptr->m_markerShape = newShape;
560 layout()->invalidate();
561 emit markerShapeChanged(shape: newShape);
562 }
563}
564
565/*!
566 \internal
567 \a event, see QGraphicsWidget for details.
568 */
569void QLegend::hideEvent(QHideEvent *event)
570{
571 if (isAttachedToChart())
572 d_ptr->m_presenter->layout()->invalidate();
573 QGraphicsWidget::hideEvent(event);
574}
575/*!
576 \internal
577 \a event, see QGraphicsWidget for details.
578 */
579void QLegend::showEvent(QShowEvent *event)
580{
581 if (isAttachedToChart())
582 layout()->invalidate();
583 QGraphicsWidget::showEvent(event);
584 //layout activation will show the items
585}
586
587////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
588
589QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q)
590 : q_ptr(q),
591 m_presenter(presenter),
592 m_layout(new LegendLayout(q)),
593 m_chart(chart),
594 m_items(new QGraphicsItemGroup(q)),
595 m_alignment(Qt::AlignTop),
596 m_brush(QChartPrivate::defaultBrush()),
597 m_pen(QChartPrivate::defaultPen()),
598 m_labelBrush(QChartPrivate::defaultBrush()),
599 m_diameter(5),
600 m_attachedToChart(true),
601 m_backgroundVisible(false),
602 m_reverseMarkers(false),
603 m_showToolTips(false),
604 m_markerShape(QLegend::MarkerShapeRectangle)
605{
606 m_items->setHandlesChildEvents(false);
607}
608
609QLegendPrivate::~QLegendPrivate()
610{
611
612}
613
614void QLegendPrivate::setOffset(const QPointF &offset)
615{
616 m_layout->setOffset(x: offset.x(), y: offset.y());
617}
618
619QPointF QLegendPrivate::offset() const
620{
621 return m_layout->offset();
622}
623
624int QLegendPrivate::roundness(qreal size)
625{
626 return 100 * m_diameter / int(size);
627}
628
629QList<QLegendMarker*> QLegendPrivate::markers(QAbstractSeries *series)
630{
631 // Return all markers
632 if (!series) {
633 return m_markers;
634 }
635
636 // Create filtered list
637 QList<QLegendMarker *> markers;
638 foreach (QLegendMarker *marker, m_markers) {
639 if (marker->series() == series) {
640 markers.append(t: marker);
641 }
642 }
643 return markers;
644}
645
646qreal QLegendPrivate::maxMarkerWidth() const
647{
648 qreal maxWidth = 0.0;
649 for (int i = 0; i < m_markers.size(); i++) {
650 LegendMarkerItem *item = m_markers.at(i)->d_ptr->item();
651 if (item)
652 maxWidth = qMax(a: item->markerRect().width(), b: maxWidth);
653 }
654 return maxWidth;
655}
656
657void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series)
658{
659 if (m_series.contains(t: series)) {
660 return;
661 }
662
663 QList<QLegendMarker*> newMarkers = series->d_ptr->createLegendMarkers(legend: q_ptr);
664 decorateMarkers(markers: newMarkers);
665 addMarkers(markers: newMarkers);
666
667 QObject::connect(sender: series->d_ptr.data(), SIGNAL(countChanged()), receiver: this, SLOT(handleCountChanged()));
668 QObject::connect(sender: series, SIGNAL(visibleChanged()), receiver: this, SLOT(handleSeriesVisibleChanged()));
669
670 m_series.append(t: series);
671 m_items->setVisible(false);
672 m_layout->invalidate();
673}
674
675void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
676{
677 if (m_series.contains(t: series)) {
678 m_series.removeOne(t: series);
679 }
680
681 // Find out, which markers to remove
682 QList<QLegendMarker *> removed;
683 foreach (QLegendMarker *m, m_markers) {
684 if (m->series() == series) {
685 removed << m;
686 }
687 }
688 removeMarkers(markers: removed);
689
690 QObject::disconnect(sender: series->d_ptr.data(), SIGNAL(countChanged()), receiver: this, SLOT(handleCountChanged()));
691 QObject::disconnect(sender: series, SIGNAL(visibleChanged()), receiver: this, SLOT(handleSeriesVisibleChanged()));
692
693 m_layout->invalidate();
694}
695
696void QLegendPrivate::handleSeriesVisibleChanged()
697{
698 QAbstractSeries *series = qobject_cast<QAbstractSeries *> (object: sender());
699 Q_ASSERT(series);
700
701 foreach (QLegendMarker *marker, m_markers) {
702 if (marker->series() == series) {
703 marker->setVisible(series->isVisible());
704 }
705 }
706
707 if (m_chart->isVisible())
708 m_layout->invalidate();
709}
710
711QObject *QLegendPrivate::relatedObject(const QLegendMarker *l)
712{
713 return l->d_ptr->relatedObject();
714}
715
716// Find equivalent QLegendMarker by checking for relatedObject()
717static int indexOfEquivalent(const QLegendMarker *needle,
718 const QList<QLegendMarker *> &hayStack)
719{
720 const QObject *needleObject = QLegendPrivate::relatedObject(l: needle);
721 for (int i = 0, size = hayStack.size(); i < size; ++i) {
722 if (QLegendPrivate::relatedObject(l: hayStack.at(i)) == needleObject)
723 return i;
724 }
725 return -1;
726}
727
728// Find QLegendMarker for series
729static int indexOfSeries(const QAbstractSeries *series,
730 const QList<QLegendMarker *> &hayStack)
731{
732 for (int i = 0, size = hayStack.size(); i < size; ++i) {
733 if (hayStack.at(i)->series() == series)
734 return i;
735 }
736 return -1;
737}
738
739void QLegendPrivate::handleCountChanged()
740{
741 // Here we handle the changes in marker count.
742 // Can happen for example when pieslice(s) have been added to or removed from pieseries.
743
744 QAbstractSeriesPrivate *seriesP = qobject_cast<QAbstractSeriesPrivate *>(object: sender());
745 QAbstractSeries *series = seriesP->q_ptr;
746 QList<QLegendMarker *> createdMarkers = seriesP->createLegendMarkers(legend: q_ptr);
747 QVector<bool> isNew(createdMarkers.size(), true);
748
749 const int pos = indexOfSeries(series, hayStack: m_markers);
750 // Remove markers of the series from m_markers and check against the newly
751 // created ones.
752 if (pos != -1) {
753 while (pos < m_markers.size() && m_markers.at(i: pos)->series() == series) {
754 QLegendMarker *oldMarker = m_markers.takeAt(i: pos);
755 const int newIndex = indexOfEquivalent(needle: oldMarker, hayStack: createdMarkers);
756 if (newIndex == -1) {
757 removeMarkerHelper(marker: oldMarker); // no longer exists
758 } else {
759 // Replace newly created marker by its equivalent
760 delete createdMarkers[newIndex];
761 createdMarkers[newIndex] = oldMarker;
762 isNew[newIndex] = false;
763 }
764 }
765 }
766
767 for (int i = 0, size = createdMarkers.size(); i < size; ++i) {
768 if (isNew.at(i)) {
769 insertMarkerHelper(marker: createdMarkers.at(i));
770 decorateMarker(marker: createdMarkers.at(i));
771 }
772 }
773
774 // Re-insert createdMarkers into m_markers in correct order.
775 if (pos == -1 || pos == m_markers.size()) {
776 m_markers.append(t: createdMarkers);
777 } else {
778 for (int c = createdMarkers.size() - 1; c >= 0; --c)
779 m_markers.insert(i: pos, t: createdMarkers.at(i: c));
780 }
781
782 q_ptr->layout()->invalidate();
783}
784
785// Helper function for marker insertion except m_markers handling
786void QLegendPrivate::insertMarkerHelper(QLegendMarker *marker)
787{
788 LegendMarkerItem *item = marker->d_ptr->item();
789 m_items->addToGroup(item);
790 m_markerHash.insert(akey: item, avalue: marker);
791}
792
793void QLegendPrivate::addMarkers(QList<QLegendMarker *> markers)
794{
795 foreach (QLegendMarker *marker, markers) {
796 insertMarkerHelper(marker);
797 m_markers << marker;
798 }
799}
800
801// Helper function for marker removal except m_markers handling
802void QLegendPrivate::removeMarkerHelper(QLegendMarker *marker)
803{
804 LegendMarkerItem *item = marker->d_ptr->item();
805 item->setVisible(false);
806 m_items->removeFromGroup(item);
807 m_markerHash.remove(akey: item);
808 delete marker;
809}
810
811void QLegendPrivate::removeMarkers(QList<QLegendMarker *> markers)
812{
813 foreach (QLegendMarker *marker, markers) {
814 m_markers.removeOne(t: marker);
815 removeMarkerHelper(marker);
816 }
817}
818
819void QLegendPrivate::decorateMarker(QLegendMarker *marker)
820{
821 marker->setFont(m_font);
822 marker->setLabelBrush(m_labelBrush);
823}
824
825void QLegendPrivate::decorateMarkers(QList<QLegendMarker *> markers)
826{
827 for (QLegendMarker *marker : markers)
828 decorateMarker(marker);
829}
830
831void QLegendPrivate::updateToolTips()
832{
833 foreach (QLegendMarker *m, m_markers) {
834 if (m->d_ptr->m_item->displayedLabel() != m->label())
835 m->d_ptr->m_item->setToolTip(m->label());
836 else
837 m->d_ptr->m_item->setToolTip(QString());
838 }
839}
840
841QT_CHARTS_END_NAMESPACE
842
843#include "moc_qlegend.cpp"
844#include "moc_qlegend_p.cpp"
845

source code of qtcharts/src/charts/legend/qlegend.cpp