1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtGraphs/qbarset.h>
5#include <private/qbarset_p.h>
6#include <private/charthelpers_p.h>
7
8QT_BEGIN_NAMESPACE
9
10/*!
11 \class QBarSet
12 \inmodule QtGraphs
13 \ingroup graphs_2D
14 \brief The QBarSet class represents one set of bars in a bar graph.
15
16 A bar set contains one data value for each category. The first value of a set is assumed to
17 belong to the first category, the second one to the second category, and so on. If the set has
18 fewer values than there are categories, the missing values are assumed to be located at the end
19 of the set. For missing values in the middle of a set, the numerical value of zero is used.
20 Labels for zero value sets are not shown.
21
22 \sa QBarSeries
23*/
24/*!
25 \qmltype BarSet
26 \nativetype QBarSet
27 \inqmlmodule QtGraphs
28 \ingroup graphs_qml_2D
29 \brief Represents one set of bars in a bar graph.
30
31 A bar set contains one data value for each category. The first value of a set is assumed to
32 belong to the first category, the second one to the second category, and so on. If the set has
33 fewer values than there are categories, the missing values are assumed to be located at the end
34 of the set. For missing values in the middle of a set, the numerical value of zero is used.
35 Labels for zero value sets are not shown.
36
37 \sa BarSeries
38*/
39
40/*!
41 \property QBarSet::label
42 \brief The label of the bar set.
43*/
44/*!
45 \qmlproperty string BarSet::label
46 The label of the bar set.
47*/
48
49/*!
50 \property QBarSet::color
51 \brief The fill color of the bar set.
52*/
53/*!
54 \qmlproperty color BarSet::color
55 The fill color of the bar set.
56*/
57
58/*!
59 \property QBarSet::selectedColor
60 \brief The fill color of the selected set.
61*/
62/*!
63 \qmlproperty color BarSet::selectedColor
64 The fill color of the selected set.
65*/
66
67/*!
68 \property QBarSet::borderColor
69 \brief The border color of the bar set.
70*/
71/*!
72 \qmlproperty color BarSet::borderColor
73 The border color of the bar set.
74*/
75
76/*!
77 \property QBarSet::borderWidth
78 \brief The width of the border line.
79 By default, the width is -1, meaning the border width is defined by the theme.
80*/
81/*!
82 \qmlproperty real BarSet::borderWidth
83 By default, the width is -1, meaning the border width is defined by the theme.
84*/
85
86/*!
87 \property QBarSet::count
88 \brief The number of values in the bar set.
89*/
90/*!
91 \qmlproperty int BarSet::count
92 The number of values in the bar set.
93*/
94
95/*!
96 \property QBarSet::labelColor
97 \brief The text (label) color of the bar set.
98*/
99/*!
100 \qmlproperty color BarSet::labelColor
101 The text (label) color of the bar set.
102*/
103
104/*!
105 \property QBarSet::selectedBars
106 \brief The indexes of the bars which are currently selected.
107*/
108/*!
109 \qmlproperty list BarSet::selectedBars
110 The indexes of the bars which are currently selected.
111*/
112
113/*!
114 \property QBarSet::values
115 \brief The values of the bar set.
116
117 You can set a list of either \l [QML]{real} or \l [QML]{point}
118 types as values.
119
120 If you set a list of real types as values, they directly define the bar set values.
121
122 If you set a list of point types as values, the x-coordinate of the point specifies its
123 zero-based index in the bar set. The size of the bar set is the highest x-coordinate value + 1.
124 If a point is missing for any x-coordinate between zero and the highest value,
125 it gets the value zero.
126 */
127/*!
128 \qmlproperty QVariantList BarSet::values
129 The values of the bar set. You can set a list of either \l [QML]{real} or \l [QML]{point}
130 types as values.
131
132 If you set a list of real types as values, they directly define the bar set values.
133
134 If you set a list of point types as values, the x-coordinate of the point specifies its
135 zero-based index in the bar set. The size of the bar set is the highest x-coordinate value + 1.
136 If a point is missing for any x-coordinate between zero and the highest value,
137 it gets the value zero.
138
139 For example, the following bar sets have equal values:
140 \code
141 myBarSet1.values = [5, 0, 1, 5];
142 myBarSet2.values = [Qt.point(0, 5), Qt.point(2, 1), Qt.point(3, 5)];
143 \endcode
144*/
145
146/*!
147 \fn void QBarSet::update()
148 This signal is emitted when the barset is updated.
149*/
150/*!
151 \qmlsignal BarSet::update()
152 This signal is emitted when the barset is updated.
153*/
154
155/*!
156 \qmlsignal BarSet::labelChanged()
157 This signal is emitted when the label of the bar set changes.
158 \sa label
159*/
160
161/*!
162 \qmlsignal BarSet::colorChanged(color)
163 This signal is emitted when the fill color of the bar set changes to \a color.
164*/
165
166/*!
167 \qmlsignal BarSet::borderColorChanged(color)
168 This signal is emitted when the border color of the bar set changes to \a color.
169*/
170
171/*!
172 \qmlsignal BarSet::labelColorChanged(color)
173 This signal is emitted when the text (label) color of the bar set changes to \a color.
174*/
175
176/*!
177 \qmlsignal BarSet::valuesChanged()
178 This signal is emitted when the values of the bar set change.
179*/
180
181/*!
182 \qmlsignal BarSet::selectedColorChanged(color color)
183 This signal is emitted when the selected bar color changes. The new color is
184 \a color.
185*/
186
187/*!
188 \qmlsignal BarSet::countChanged()
189 This signal is emitted when the barset's value count changes.
190*/
191
192/*!
193 \qmlsignal BarSet::borderWidthChanged(real width)
194 This signal is emitted when the barset's border width changes.
195 The new width is \a width.
196*/
197
198/*!
199 \fn void QBarSet::valuesAdded(qsizetype index, qsizetype count)
200 This signal is emitted when new values are added to the bar set.
201 \a index indicates the position of the first inserted value, and \a count is the number
202 of inserted values.
203 \sa append(), insert()
204*/
205/*!
206 \qmlsignal BarSet::valuesAdded(int index, int count)
207 This signal is emitted when new values are added to the bar set.
208 \a index indicates the position of the first inserted value, and \a count is the number
209 of inserted values.
210*/
211
212/*!
213 \fn void QBarSet::valuesRemoved(qsizetype index, qsizetype count)
214 This signal is emitted when values are removed from the bar set.
215 \a index indicates the position of the first removed value, and \a count is the number
216 of removed values.
217 \sa remove()
218*/
219/*!
220 \qmlsignal BarSet::valuesRemoved(int index, int count)
221 This signal is emitted when values are removed from the bar set.
222 \a index indicates the position of the first removed value, and \a count is the number
223 of removed values.
224*/
225
226/*!
227 \fn void QBarSet::valueChanged(qsizetype index)
228 This signal is emitted when the value at the position specified by \a index is modified.
229 \sa at()
230*/
231/*!
232 \qmlsignal BarSet::valueChanged(int index)
233 This signal is emitted when the value at the position specified by \a index is modified.
234*/
235
236/*!
237 \fn void QBarSet::updatedBars()
238 This signal is emitted when the bars in this set are updated.
239*/
240/*!
241 \qmlsignal BarSet::updatedBars()
242 This signal is emitted when the bars in this set are updated.
243*/
244
245/*!
246 \fn void QBarSet::valueAdded(qsizetype index, qsizetype count)
247 This signal is emitted when new values are added to the bar set.
248 \a index indicates the position of the first inserted value, and \a count
249 is the number of inserted values.
250*/
251/*!
252 \qmlsignal BarSet::valueAdded(int index, int count)
253 This signal is emitted when new values are added to the bar set.
254 \a index indicates the position of the first inserted value, and \a count
255 is the number of inserted values.
256*/
257
258/*!
259 \fn void QBarSet::valueRemoved(qsizetype index, qsizetype count)
260 This signal is emitted when values are removed from the bar set.
261 \a index indicates the position of the first removed value, and \a count
262 is the number of removed values.
263*/
264/*!
265 \qmlsignal BarSet::valueRemoved(int index, int count)
266 This signal is emitted when values are removed from the bar set.
267 \a index indicates the position of the first removed value, and \a count
268 is the number of removed values.
269*/
270
271/*!
272 \fn void QBarSet::selectedBarsChanged(const QList<qsizetype> &indexes)
273 This signal is emitted when the selected bar changes. \a indexes is
274 a list selected bar indexes.
275*/
276/*!
277 \qmlsignal BarSet::selectedBarsChanged(list<int> indexes)
278 This signal is emitted when the selected bar changes. \a indexes is
279 a list selected bar indexes.
280*/
281
282QBarSet::QBarSet(QObject *parent)
283 : QBarSet(QString(), parent)
284{}
285
286/*!
287 Constructs a bar set with the label \a label and the parent \a parent.
288*/
289QBarSet::QBarSet(const QString &label, QObject *parent)
290 : QObject(*(new QBarSetPrivate(label)), parent)
291{}
292
293/*!
294 Removes the bar set.
295*/
296QBarSet::~QBarSet()
297{
298 // NOTE: d_ptr destroyed by QObject
299}
300
301/*!
302 Sets \a label as the new label for the bar set.
303*/
304void QBarSet::setLabel(const QString &label)
305{
306 Q_D(QBarSet);
307 if (d->m_label != label) {
308 d->m_label = label;
309 d->setLabelsDirty(true);
310 emit update();
311 emit labelChanged();
312 }
313}
314
315/*!
316 Returns the label of the bar set.
317*/
318QString QBarSet::label() const
319{
320 Q_D(const QBarSet);
321 return d->m_label;
322}
323
324/*!
325 \qmlmethod BarSet::append(real value)
326 Appends the new value specified by \a value to the end of the bar set.
327*/
328/*!
329 Appends the new value specified by \a value to the end of the bar set.
330*/
331void QBarSet::append(qreal value)
332{
333 Q_D(QBarSet);
334 // Convert to QPointF
335 qsizetype index = d->m_values.size();
336 d->append(value: QPointF(d->m_values.size(), value));
337 emit valuesAdded(index, count: 1);
338 emit update();
339}
340
341/*!
342 \qmlmethod BarSet::append(list<real> values)
343 Appends the list of real values specified by \a values to the end of the bar set.
344
345 \sa append()
346*/
347/*!
348 Appends the list of real values specified by \a values to the end of the bar set.
349
350 \sa append()
351*/
352void QBarSet::append(const QList<qreal> &values)
353{
354 Q_D(QBarSet);
355 qsizetype index = d->m_values.size();
356 d->append(values);
357 emit valuesAdded(index, count: values.size());
358 emit update();
359}
360
361/*!
362 \qmlmethod BarSet::insert(int index, real value)
363 Inserts \a value in the position specified by \a index.
364 The values following the inserted value are moved up one position.
365
366 \sa remove()
367*/
368/*!
369 Inserts \a value in the position specified by \a index.
370 The values following the inserted value are moved up one position.
371
372 \sa remove()
373*/
374void QBarSet::insert(qsizetype index, qreal value)
375{
376 Q_D(QBarSet);
377 d->insert(index, value);
378
379 bool callSignal = false;
380 if (!d->m_selectedBars.isEmpty()) {
381 // if value was inserted we need to move already selected bars by 1
382 QSet<qsizetype> selectedAfterInsert;
383 for (const auto &value : std::as_const(t&: d->m_selectedBars)) {
384 if (value >= index) {
385 selectedAfterInsert << value + 1;
386 callSignal = true;
387 } else {
388 selectedAfterInsert << value;
389 }
390 }
391 d->m_selectedBars = selectedAfterInsert;
392 emit update();
393 }
394
395 emit valuesAdded(index, count: 1);
396 if (callSignal)
397 emit selectedBarsChanged(indexes: selectedBars());
398}
399
400/*!
401 \qmlmethod BarSet::remove(int index, int count)
402 Removes the number of values specified by \a count from the bar set starting
403 with the value specified by \a index.
404
405 If you leave out \a count, only the value specified by \a index is removed.
406*/
407/*!
408 Removes the number of values specified by \a count from the bar set starting with
409 the value specified by \a index.
410 \sa insert()
411*/
412void QBarSet::remove(qsizetype index, qsizetype count)
413{
414 Q_D(QBarSet);
415 qsizetype removedCount = d->remove(index, count);
416 if (removedCount > 0) {
417 emit valuesRemoved(index, count: removedCount);
418 emit update();
419 }
420}
421
422/*!
423 \qmlmethod BarSet::replace(int index, real value)
424 Adds the value specified by \a value to the bar set at the position
425 specified by \a index.
426*/
427/*!
428 Adds the value specified by \a value to the bar set at the position specified by \a index.
429*/
430void QBarSet::replace(qsizetype index, qreal value)
431{
432 Q_D(QBarSet);
433 if (index >= 0 && index < d->m_values.size()) {
434 d->replace(index, value);
435 emit valueChanged(index);
436 emit update();
437 }
438}
439
440/*!
441 \qmlmethod real BarSet::at(int index)
442 Returns the value specified by \a index from the bar set.
443 If the index is out of bounds, 0.0 is returned.
444*/
445/*!
446 Returns the value specified by \a index from the bar set.
447 If the index is out of bounds, 0.0 is returned.
448*/
449qreal QBarSet::at(qsizetype index) const
450{
451 Q_D(const QBarSet);
452 if (index < 0 || index >= d->m_values.size())
453 return 0;
454 return d->m_values.at(i: index).y();
455}
456
457/*!
458 \qmlmethod int BarSet::count()
459 Returns the number of values in a bar set.
460*/
461/*!
462 Returns the number of values in a bar set.
463*/
464qsizetype QBarSet::count() const
465{
466 Q_D(const QBarSet);
467 return d->m_values.size();
468}
469
470/*!
471 \qmlmethod real BarSet::sum()
472 Returns the sum of all values in the bar set.
473*/
474/*!
475 Returns the sum of all values in the bar set.
476*/
477qreal QBarSet::sum() const
478{
479 Q_D(const QBarSet);
480 qreal total(0);
481 for (int i = 0; i < d->m_values.size(); i++)
482 total += d->m_values.at(i).y();
483 return total;
484}
485
486/*!
487 \qmlmethod BarSet::clear()
488 Removes all values from the set.
489*/
490/*!
491 Removes all values from the set.
492*/
493void QBarSet::clear()
494{
495 Q_D(QBarSet);
496 remove(index: 0, count: d->m_values.size());
497}
498
499/*!
500 A convenience operator for appending the real value specified by \a value to the end of the
501 bar set.
502
503 \sa append()
504*/
505QBarSet &QBarSet::operator << (qreal value)
506{
507 append(value);
508 return *this;
509}
510
511/*!
512 Returns the value of the bar set specified by \a index.
513 If the index is out of bounds, 0.0 is returned.
514*/
515qreal QBarSet::operator [](qsizetype index) const
516{
517 return at(index);
518}
519
520/*!
521 Returns the fill color for the bar set.
522*/
523QColor QBarSet::color() const
524{
525 Q_D(const QBarSet);
526 return d->m_color;
527}
528
529/*!
530 Sets the fill color for the bar set to \a color.
531*/
532void QBarSet::setColor(QColor color)
533{
534 Q_D(QBarSet);
535 if (d->m_color != color) {
536 d->m_color = color;
537 emit update();
538 emit colorChanged(color);
539 }
540}
541
542/*!
543 Returns the line color for the bar set.
544*/
545QColor QBarSet::borderColor() const
546{
547 Q_D(const QBarSet);
548 return d->m_borderColor;
549}
550
551/*!
552 Sets the line color for the bar set to \a color.
553*/
554void QBarSet::setBorderColor(QColor color)
555{
556 Q_D(QBarSet);
557 if (d->m_borderColor != color) {
558 d->m_borderColor = color;
559 emit update();
560 emit borderColorChanged(color);
561 }
562}
563
564/*!
565 Returns the text color for the bar set.
566*/
567QColor QBarSet::labelColor() const
568{
569 Q_D(const QBarSet);
570 return d->m_labelColor;
571}
572
573/*!
574 Sets the text color for the bar set to \a color.
575*/
576void QBarSet::setLabelColor(QColor color)
577{
578 Q_D(QBarSet);
579 if (d->m_labelColor != color) {
580 d->m_labelColor = color;
581 emit update();
582 emit labelColorChanged(color);
583 }
584}
585
586/*!
587 Returns the color of the selected bars.
588
589 This is the fill (brush) color of bars marked as selected. If not specified,
590 value of QBarSet::color is used as default.
591 \sa color
592*/
593QColor QBarSet::selectedColor() const
594{
595 Q_D(const QBarSet);
596 return d->m_selectedColor;
597}
598
599/*!
600 Sets the \a color of the selected bars.
601 \sa selectedColor
602*/
603void QBarSet::setSelectedColor(QColor color)
604{
605 Q_D(QBarSet);
606 if (d->m_selectedColor != color) {
607 d->m_selectedColor = color;
608 d->setLabelsDirty(true);
609 emit update();
610 emit updatedBars();
611 emit selectedColorChanged(color);
612 }
613}
614
615
616qreal QBarSet::borderWidth() const
617{
618 Q_D(const QBarSet);
619 return d->m_borderWidth;
620}
621
622void QBarSet::setBorderWidth(qreal width)
623{
624 Q_D(QBarSet);
625 width = qMax(a: 0.0, b: width);
626 if (!qFuzzyCompare(p1: d->m_borderWidth, p2: width)) {
627 d->m_borderWidth = width;
628 emit update();
629 emit borderWidthChanged(width);
630 }
631}
632
633QVariantList QBarSet::values() const
634{
635 QVariantList values;
636 for (qsizetype i(0); i < count(); i++)
637 values.append(t: QVariant(QBarSet::at(index: i)));
638 return values;
639}
640
641void QBarSet::setValues(const QVariantList &values)
642{
643 bool valuesUpdated = false;
644 // See if we can replace values instead of remove & add all.
645 // This way e.g. selections remain.
646 const bool doReplace = count() == values.size();
647
648 if (!doReplace) {
649 while (count())
650 remove(index: count() - 1);
651 valuesUpdated = true;
652 }
653
654 if (values.size() > 0 && values.at(i: 0).canConvert<QPoint>()) {
655 // Create list of values for appending if the first item is Qt.point
656 int maxValue = 0;
657 for (int i = 0; i < values.size(); i++) {
658 if (values.at(i).canConvert<QPoint>() &&
659 values.at(i).toPoint().x() > maxValue) {
660 maxValue = values.at(i).toPoint().x();
661 }
662 }
663
664 QList<qreal> indexValueList;
665 indexValueList.resize(size: maxValue + 1);
666
667 for (int i = 0; i < values.size(); i++) {
668 if (values.at(i).canConvert<QPoint>())
669 indexValueList.replace(i: values.at(i).toPoint().x(), t: values.at(i).toPointF().y());
670 }
671
672 for (int i = 0; i < indexValueList.size(); i++) {
673 if (doReplace)
674 QBarSet::replace(index: i, value: indexValueList.at(i));
675 else
676 QBarSet::append(value: indexValueList.at(i));
677 valuesUpdated = true;
678 }
679
680 } else {
681 for (int i(0); i < values.size(); i++) {
682 if (values.at(i).canConvert<double>()) {
683 if (doReplace)
684 QBarSet::replace(index: i, value: values[i].toDouble());
685 else
686 QBarSet::append(value: values[i].toDouble());
687 valuesUpdated = true;
688 }
689 }
690 }
691 emit update();
692 if (valuesUpdated)
693 emit valuesChanged();
694}
695
696
697/*!
698 \qmlmethod bool BarSet::isBarSelected(int index)
699 Returns \c true if the bar at the given \a index is among selected bars and \c false otherwise.
700 \note Selected bars are drawn using the selected color if it was specified using BarSet::setSelectedColor.
701 \sa selectedBars, setBarSelected(), selectedColor
702 */
703/*!
704 Returns \c true if the bar at the given \a index is among selected bars and \c false otherwise.
705 \note Selected bars are drawn using the selected color if it was specified using QBarSet::setSelectedColor.
706 \sa selectedBars(), setBarSelected(), setSelectedColor()
707 */
708bool QBarSet::isBarSelected(qsizetype index) const
709{
710 Q_D(const QBarSet);
711 return d->isBarSelected(index);
712}
713
714/*!
715 \qmlmethod BarSet::selectBar(int index)
716 Marks the bar at \a index as selected.
717 \note Emits BarSet::selectedBarsChanged.
718 \sa setBarSelected()
719 */
720/*!
721 Marks the bar at \a index as selected.
722 \note Emits QBarSet::selectedBarsChanged.
723 \sa setBarSelected()
724 */
725void QBarSet::selectBar(qsizetype index)
726{
727 setBarSelected(index, selected: true);
728}
729
730/*!
731 \qmlmethod BarSet::deselectBar(int index)
732 Deselects the bar at \a index.
733 \note Emits BarSet::selectedBarsChanged.
734 \sa setBarSelected()
735 */
736/*!
737 Deselects the bar at \a index.
738 \note Emits QBarSet::selectedBarsChanged.
739 \sa setBarSelected()
740 */
741void QBarSet::deselectBar(qsizetype index)
742{
743 setBarSelected(index, selected: false);
744}
745
746/*!
747 \qmlmethod BarSet::setBarSelected(int index, bool selected)
748 Marks the bar at \a index as either selected or deselected as specified by \a selected.
749 \note Selected bars are drawn using the selected color if it was specified. Emits BarSet::selectedBarsChanged.
750 \sa selectedColor
751 */
752/*!
753 Marks the bar at \a index as either selected or deselected as specified by \a selected.
754 \note Selected bars are drawn using the selected color if it was specified. Emits QBarSet::selectedBarsChanged.
755 \sa setSelectedColor()
756 */
757void QBarSet::setBarSelected(qsizetype index, bool selected)
758{
759 Q_D(QBarSet);
760 bool callSignal = false;
761 d->setBarSelected(index, selected, callSignal);
762
763 if (callSignal)
764 emit selectedBarsChanged(indexes: selectedBars());
765 emit update();
766}
767
768/*!
769 \qmlmethod BarSet::selectAllBars()
770 Marks all bars in the set as selected.
771 \note Emits BarSet::selectedBarsChanged.
772 \sa setBarSelected()
773 */
774/*!
775 Marks all bars in the set as selected.
776 \note Emits QBarSet::selectedBarsChanged.
777 \sa setBarSelected()
778 */
779void QBarSet::selectAllBars()
780{
781 Q_D(QBarSet);
782 bool callSignal = false;
783 for (int i = 0; i < d->m_values.size(); ++i)
784 d->setBarSelected(index: i, selected: true, callSignal);
785
786 if (callSignal)
787 emit selectedBarsChanged(indexes: selectedBars());
788 emit update();
789}
790
791/*!
792 \qmlmethod BarSet::deselectAllBars()
793 Deselects all bars in the set.
794 \note Emits BarSet::selectedBarsChanged.
795 \sa setBarSelected()
796 */
797/*!
798 Deselects all bars in the set.
799 \note Emits QBarSet::selectedBarsChanged.
800 \sa setBarSelected()
801 */
802void QBarSet::deselectAllBars()
803{
804 Q_D(QBarSet);
805 bool callSignal = false;
806 for (int i = 0; i < d->m_values.size(); ++i)
807 d->setBarSelected(index: i, selected: false, callSignal);
808
809 if (callSignal)
810 emit selectedBarsChanged(indexes: selectedBars());
811 emit update();
812}
813
814/*!
815 \qmlmethod BarSet::selectBars(list<int> indexes)
816 Marks multiple bars passed in an \a indexes list as selected.
817 \note Emits BarSet::selectedBarsChanged.
818 \sa setBarSelected()
819 */
820/*!
821 Marks multiple bars passed in an \a indexes list as selected.
822 \note Emits QBarSet::selectedBarsChanged.
823 \sa setBarSelected()
824 */
825void QBarSet::selectBars(const QList<qsizetype> &indexes)
826{
827 Q_D(QBarSet);
828 bool callSignal = false;
829 for (const qsizetype &index : indexes)
830 d->setBarSelected(index, selected: true, callSignal);
831
832 if (callSignal)
833 emit selectedBarsChanged(indexes: selectedBars());
834 emit update();
835}
836
837/*!
838 \qmlmethod BarSet::deselectBars(list<int> indexes)
839 Marks multiple bars passed in an \a indexes list as deselected.
840 \note Emits BarSet::selectedBarsChanged.
841 \sa setBarSelected()
842 */
843/*!
844 Marks multiple bars passed in an \a indexes list as deselected.
845 \note Emits QBarSet::selectedBarsChanged.
846 \sa setBarSelected()
847 */
848void QBarSet::deselectBars(const QList<qsizetype> &indexes)
849{
850 Q_D(QBarSet);
851 bool callSignal = false;
852 for (const qsizetype &index : indexes)
853 d->setBarSelected(index, selected: false, callSignal);
854
855 if (callSignal)
856 emit selectedBarsChanged(indexes: selectedBars());
857 emit update();
858}
859
860/*!
861 \qmlmethod BarSet::toggleSelection(list<int> indexes)
862 Changes the selection state of bars at the given \a indexes to the opposite one.
863 \note Emits BarSet::selectedBarsChanged.
864 \sa setBarSelected()
865 */
866/*!
867 Changes the selection state of bars at the given \a indexes to the opposite one.
868 \note Emits QBarSet::selectedBarsChanged.
869 \sa setBarSelected()
870 */
871void QBarSet::toggleSelection(const QList<qsizetype> &indexes)
872{
873 Q_D(QBarSet);
874 bool callSignal = false;
875 for (const qsizetype &index : indexes)
876 d->setBarSelected(index, selected: !isBarSelected(index), callSignal);
877
878 if (callSignal)
879 emit selectedBarsChanged(indexes: selectedBars());
880 emit update();
881}
882
883/*!
884 Returns a list of bars marked as selected.
885 \sa setBarSelected()
886 */
887QList<qsizetype> QBarSet::selectedBars() const
888{
889 Q_D(const QBarSet);
890 return QList<qsizetype>(d->m_selectedBars.begin(), d->m_selectedBars.end());
891}
892
893////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
894
895QBarSetPrivate::QBarSetPrivate(const QString &label)
896 : m_label(label)
897 , m_visualsDirty(true)
898{}
899
900QBarSetPrivate::~QBarSetPrivate() {}
901
902void QBarSetPrivate::append(QPointF value)
903{
904 if (isValidValue(point: value)) {
905 Q_Q(QBarSet);
906 m_values.append(t: value);
907 emit q->valueAdded(index: m_values.size() - 1, count: 1);
908 }
909}
910
911void QBarSetPrivate::append(const QList<QPointF> &values)
912{
913 qsizetype originalIndex = m_values.size();
914 for (const auto &value : values) {
915 if (isValidValue(point: value))
916 m_values.append(t: value);
917 }
918 Q_Q(QBarSet);
919 emit q->valueAdded(index: originalIndex, count: values.size());
920}
921
922void QBarSetPrivate::append(const QList<qreal> &values)
923{
924 qsizetype originalIndex = m_values.size();
925 qsizetype index = originalIndex;
926 for (const auto value : values) {
927 if (isValidValue(value)) {
928 m_values.append(t: QPointF(index, value));
929 index++;
930 }
931 }
932 Q_Q(QBarSet);
933 emit q->valueAdded(index: originalIndex, count: values.size());
934}
935
936void QBarSetPrivate::insert(qsizetype index, qreal value)
937{
938 m_values.insert(i: index, t: QPointF(index, value));
939 Q_Q(QBarSet);
940 emit q->valueAdded(index, count: 1);
941}
942
943void QBarSetPrivate::insert(qsizetype index, QPointF value)
944{
945 m_values.insert(i: index, t: value);
946 Q_Q(QBarSet);
947 emit q->valueAdded(index, count: 1);
948}
949
950qsizetype QBarSetPrivate::remove(qsizetype index, qsizetype count)
951{
952 qsizetype removeCount = count;
953
954 if ((index < 0) || (m_values.size() == 0))
955 return 0; // Invalid index or not values in list, remove nothing.
956 else if ((index + count) > m_values.size())
957 removeCount = m_values.size() - index; // Trying to remove more items than list has. Limit amount to be removed.
958
959 int c = 0;
960 while (c < removeCount) {
961 m_values.removeAt(i: index);
962 c++;
963 }
964
965 bool callSignal = false;
966 if (!m_selectedBars.empty()) {
967 QSet<qsizetype> selectedAfterRemoving;
968
969 for (const qsizetype &selectedBarIndex : std::as_const(t&: m_selectedBars)) {
970 if (selectedBarIndex < index) {
971 selectedAfterRemoving << selectedBarIndex;
972 } else if (selectedBarIndex >= index + removeCount) {
973 selectedAfterRemoving << selectedBarIndex - removeCount;
974 callSignal = true;
975 } else {
976 callSignal = true;
977 }
978 }
979
980 m_selectedBars = selectedAfterRemoving;
981 }
982 Q_Q(QBarSet);
983 emit q->valueRemoved(index, count: removeCount);
984 if (callSignal)
985 emit q->selectedBarsChanged(indexes: q->selectedBars());
986
987 return removeCount;
988}
989
990void QBarSetPrivate::replace(qsizetype index, qreal value)
991{
992 if (index < 0 || index >= m_values.size())
993 return;
994
995 m_values.replace(i: index, t: QPointF(index, value));
996}
997
998qreal QBarSetPrivate::pos(qsizetype index) const
999{
1000 if (index < 0 || index >= m_values.size())
1001 return 0;
1002 return m_values.at(i: index).x();
1003}
1004
1005qreal QBarSetPrivate::value(qsizetype index) const
1006{
1007 if (index < 0 || index >= m_values.size())
1008 return 0;
1009 return m_values.at(i: index).y();
1010}
1011
1012void QBarSetPrivate::setBarSelected(qsizetype index, bool selected, bool &callSignal)
1013{
1014 if (index < 0 || index > m_values.size() - 1)
1015 return;
1016
1017 if (selected) {
1018 if (!isBarSelected(index)) {
1019 m_selectedBars << index;
1020 callSignal = true;
1021 }
1022 } else {
1023 if (isBarSelected(index)) {
1024 m_selectedBars.remove(value: index);
1025 callSignal = true;
1026 }
1027 }
1028
1029 if (callSignal)
1030 setVisualsDirty(true);
1031}
1032
1033bool QBarSetPrivate::isBarSelected(qsizetype index) const
1034{
1035 return m_selectedBars.contains(value: index);
1036}
1037
1038QT_END_NAMESPACE
1039
1040#include "moc_qbarset.cpp"
1041

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtgraphs/src/graphs2d/barchart/qbarset.cpp