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