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 | |
8 | QT_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 | |
282 | QBarSet::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 | */ |
289 | QBarSet::QBarSet(const QString &label, QObject *parent) |
290 | : QObject(*(new QBarSetPrivate(label)), parent) |
291 | {} |
292 | |
293 | /*! |
294 | Removes the bar set. |
295 | */ |
296 | QBarSet::~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 | */ |
304 | void 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 | */ |
318 | QString 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 | */ |
331 | void 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 | */ |
352 | void 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 | */ |
374 | void 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 | */ |
412 | void 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 | */ |
430 | void 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 | */ |
449 | qreal 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 | */ |
464 | qsizetype 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 | */ |
477 | qreal 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 | */ |
493 | void 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 | */ |
505 | QBarSet &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 | */ |
515 | qreal QBarSet::operator [](qsizetype index) const |
516 | { |
517 | return at(index); |
518 | } |
519 | |
520 | /*! |
521 | Returns the fill color for the bar set. |
522 | */ |
523 | QColor 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 | */ |
532 | void 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 | */ |
545 | QColor 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 | */ |
554 | void 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 | */ |
567 | QColor 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 | */ |
576 | void 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 | */ |
593 | QColor 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 | */ |
603 | void 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 | |
616 | qreal QBarSet::borderWidth() const |
617 | { |
618 | Q_D(const QBarSet); |
619 | return d->m_borderWidth; |
620 | } |
621 | |
622 | void 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 | |
633 | QVariantList 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 | |
641 | void 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 | */ |
708 | bool 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 | */ |
725 | void 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 | */ |
741 | void 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 | */ |
757 | void 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 | */ |
779 | void 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 | */ |
802 | void 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 | */ |
825 | void 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 | */ |
848 | void 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 | */ |
871 | void 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 | */ |
887 | QList<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 | |
895 | QBarSetPrivate::QBarSetPrivate(const QString &label) |
896 | : m_label(label) |
897 | , m_visualsDirty(true) |
898 | {} |
899 | |
900 | QBarSetPrivate::~QBarSetPrivate() {} |
901 | |
902 | void 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 | |
911 | void 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 | |
922 | void 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 | |
936 | void 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 | |
943 | void 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 | |
950 | qsizetype 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 | |
990 | void 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 | |
998 | qreal 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 | |
1005 | qreal 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 | |
1012 | void 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 | |
1033 | bool QBarSetPrivate::isBarSelected(qsizetype index) const |
1034 | { |
1035 | return m_selectedBars.contains(value: index); |
1036 | } |
1037 | |
1038 | QT_END_NAMESPACE |
1039 | |
1040 | #include "moc_qbarset.cpp" |
1041 |
Definitions
- QBarSet
- QBarSet
- ~QBarSet
- setLabel
- label
- append
- append
- insert
- remove
- replace
- at
- count
- sum
- clear
- operator <<
- operator []
- color
- setColor
- borderColor
- setBorderColor
- labelColor
- setLabelColor
- selectedColor
- setSelectedColor
- borderWidth
- setBorderWidth
- values
- setValues
- isBarSelected
- selectBar
- deselectBar
- setBarSelected
- selectAllBars
- deselectAllBars
- selectBars
- deselectBars
- toggleSelection
- selectedBars
- QBarSetPrivate
- ~QBarSetPrivate
- append
- append
- append
- insert
- insert
- remove
- replace
- pos
- value
- setBarSelected
Learn to use CMake with our Intro Training
Find out more