1 | // Copyright (C) 2023 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <QtGraphs/qabstractseries.h> |
5 | #include <QtGraphs/qbarseries.h> |
6 | #include <QtGraphs/qbarset.h> |
7 | #include <private/qabstractseries_p.h> |
8 | #include <private/qbarseries_p.h> |
9 | #include <private/qbarset_p.h> |
10 | #include <private/qgraphsview_p.h> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | /*! |
15 | \class QBarSeries |
16 | \inmodule QtGraphs |
17 | \ingroup graphs_2D |
18 | \brief The QBarSeries class presents data in bar graphs. |
19 | |
20 | This class draws data by default as a series of bars grouped by category, |
21 | with one bar per category from each bar set added to the series. |
22 | It also supports horizontal bars and grouping bars as stacked. |
23 | |
24 | A bar series needs the GraphsView x-axis to be set to a BarCategoryAxis and |
25 | the y-axis set to ValueAxis. |
26 | |
27 | \sa QBarSet, QAbstractSeries |
28 | */ |
29 | /*! |
30 | \qmltype BarSeries |
31 | \nativetype QBarSeries |
32 | \inqmlmodule QtGraphs |
33 | \ingroup graphs_qml_2D |
34 | \inherits AbstractSeries |
35 | |
36 | \brief Presents data in bar graphs. |
37 | |
38 | Draws data by default as a series of bars grouped by category, |
39 | with one bar per category from each bar set added to the series. |
40 | It also supports horizontal bars and grouping bars as stacked. |
41 | */ |
42 | |
43 | /*! |
44 | \property QBarSeries::barWidth |
45 | \brief The width of the bars of the series. |
46 | |
47 | The unit of width is the unit of the x-axis. The minimum width for bars is zero, and negative |
48 | values are treated as zero. Setting the width to zero means that the width of the bar on the |
49 | screen is one pixel regardless of the scale of the x-axis. Bars wider than zero are scaled |
50 | using the x-axis scale. |
51 | |
52 | By default, the barWidth is 0.5 (bars will take 50% of the available width). |
53 | The valid values range from 0.0 (0%) to 1.0 (100%). |
54 | |
55 | \note When used with QBarSeries, this value specifies the width of a group of bars instead of |
56 | that of a single bar. |
57 | \sa QBarSeries |
58 | */ |
59 | |
60 | /*! |
61 | \enum QBarSeries::BarsType |
62 | |
63 | This enum value describes the type of the bar series: |
64 | |
65 | \value Groups Bar sets are grouped by category. |
66 | \value Stacked Bar sets are stacked after each other by category. |
67 | \value StackedPercent Bar sets are stacked after each other by category. |
68 | The segment size corresponds to the percentage of the segment value |
69 | compared with the total value of all segments in the stack. |
70 | */ |
71 | /*! |
72 | \property QBarSeries::barsType |
73 | \brief The type of the bar series. |
74 | */ |
75 | /*! |
76 | \qmlproperty enumeration BarSeries::barsType |
77 | |
78 | The type of the bar series: |
79 | |
80 | \value BarSeries.BarsType.Groups |
81 | Bar sets are grouped by category. This is the default value. |
82 | \value BarSeries.BarsType.Stacked |
83 | Bar sets are stacked after each other by category. |
84 | \value BarSeries.BarsType.StackedPercent |
85 | Bar sets are stacked after each other by category. The segment size corresponds |
86 | to the percentage of the segment value compared with the total value of all |
87 | segments in the stack. |
88 | */ |
89 | |
90 | /*! |
91 | \qmlproperty real BarSeries::barWidth |
92 | The unit of width is the unit of the x-axis. The minimum width for bars is zero, and negative |
93 | values are treated as zero. Setting the width to zero means that the width of the bar on the |
94 | screen is one pixel regardless of the scale of the x-axis. Bars wider than zero are scaled |
95 | using the x-axis scale. |
96 | |
97 | By default, the barWidth is 0.5 (bars will take 50% of the available width). |
98 | The valid values range from 0.0 (0%) to 1.0 (100%). |
99 | |
100 | \note When used with the BarSeries type, this value specifies the width of a group of bars |
101 | instead of that of a single bar. |
102 | */ |
103 | |
104 | /*! |
105 | \property QBarSeries::count |
106 | \brief The number of bar sets in a bar series. |
107 | */ |
108 | /*! |
109 | \qmlproperty int BarSeries::count |
110 | The number of bar sets in a bar series. |
111 | */ |
112 | |
113 | /*! |
114 | \property QBarSeries::labelsVisible |
115 | \brief The visibility of the labels in a bar series. |
116 | The default label visibility is \c false. |
117 | */ |
118 | /*! |
119 | \qmlproperty bool BarSeries::labelsVisible |
120 | The visibility of the labels in a bar series. |
121 | The default label visibility is \c false. |
122 | */ |
123 | |
124 | /*! |
125 | \property QBarSeries::labelsFormat |
126 | \brief The format used for showing labels in a bar series. |
127 | |
128 | QBarSeries supports the following format tag: |
129 | \table |
130 | \row |
131 | \li @value \li The value of the bar |
132 | \endtable |
133 | |
134 | For example, the following usage of the format tags would produce labels that show the value |
135 | followed by the unit (u): |
136 | \code |
137 | series->setLabelsFormat("@value u"); |
138 | \endcode |
139 | |
140 | By default, the labels show the value of the bar. For the percent bar series, \e % is added |
141 | after the value. The labels are shown on the plot area, if the bars are close to each other, |
142 | the labels may overlap. |
143 | |
144 | \sa labelsVisible, labelsPosition, labelsPrecision |
145 | */ |
146 | /*! |
147 | \qmlproperty string BarSeries::labelsFormat |
148 | The format used for showing labels in a bar series. |
149 | |
150 | \sa QBarSeries::labelsFormat, labelsVisible, labelsPosition |
151 | */ |
152 | |
153 | /*! |
154 | \enum QBarSeries::LabelsPosition |
155 | |
156 | This enum value describes the position of the data value labels: |
157 | |
158 | \value Center Label is located in the center of the bar. |
159 | \value InsideEnd Label is located inside the bar at the top. |
160 | \value InsideBase Label is located inside the bar at the bottom. |
161 | \value OutsideEnd Label is located outside the bar at the top. |
162 | */ |
163 | |
164 | /*! |
165 | \property QBarSeries::labelsPosition |
166 | \brief The position of value labels. |
167 | |
168 | \sa labelsVisible, labelsFormat |
169 | */ |
170 | /*! |
171 | \qmlproperty enumeration BarSeries::labelsPosition |
172 | |
173 | The position of the data value labels: |
174 | |
175 | \value BarSeries.LabelsPosition.Center |
176 | Label is located in the center of the bar. |
177 | \value BarSeries.LabelsPosition.InsideEnd |
178 | Label is located inside the bar at the top. |
179 | \value BarSeries.LabelsPosition.InsideBase |
180 | Label is located inside the bar at the bottom. |
181 | \value BarSeries.LabelsPosition.OutsideEnd |
182 | Label is located outside the bar at the top. |
183 | |
184 | \sa labelsVisible, labelsFormat |
185 | */ |
186 | |
187 | /*! |
188 | \property QBarSeries::labelsMargin |
189 | \brief The margin of the value labels in pixels. |
190 | |
191 | This margin from side is used when \l labelsPosition is set to something else |
192 | than \c LabelsPosition.Center. The default value is \c 0. |
193 | */ |
194 | /*! |
195 | \qmlproperty real BarSeries::labelsMargin |
196 | The margin of the value labels in pixels. |
197 | |
198 | This margin from side is used when \l labelsPosition is set to something else |
199 | than \c LabelsPosition.Center. The default value is \c 0. |
200 | */ |
201 | |
202 | /*! |
203 | \property QBarSeries::labelsAngle |
204 | \brief The angle of the value labels in degrees. |
205 | */ |
206 | /*! |
207 | \qmlproperty real BarSeries::labelsAngle |
208 | The angle of the value labels in degrees. |
209 | */ |
210 | |
211 | /*! |
212 | \property QBarSeries::labelsPrecision |
213 | \brief The maximum amount of significant digits shown in value labels. |
214 | |
215 | Default value is 6. |
216 | */ |
217 | /*! |
218 | \qmlproperty real BarSeries::labelsPrecision |
219 | The maximum amount of significant digits shown in value labels. |
220 | |
221 | Default value is 6. |
222 | */ |
223 | |
224 | /*! |
225 | \property QBarSeries::barDelegate |
226 | \brief A custom QML component used for visualizing each of the bars. |
227 | Instance of this component is created for each of the bar. |
228 | When this is not defined, a default rectangle visualization for bars is used. |
229 | |
230 | The dynamic properties available for this component are: |
231 | |
232 | \table |
233 | \header |
234 | \li Type |
235 | \li Name |
236 | \li Description |
237 | \row |
238 | \li QColor |
239 | \li barColor |
240 | \li The fill color of the bar. This value comes either from the \l QGraphsTheme |
241 | or from \l{QBarSet::color} if the \l QBarSet overrides the color. |
242 | \row |
243 | \li QColor |
244 | \li barBorderColor |
245 | \li The border color of the bar. This value comes either from the \l QGraphsTheme |
246 | or from \l{QBarSet::borderColor} if the \l QBarSet overrides the color. |
247 | \row |
248 | \li qreal |
249 | \li barBorderWidth |
250 | \li The width of the bar border. This value comes either from the \l QGraphsTheme |
251 | or from \l{QBarSet::borderWidth} if the \l QBarSet overrides the width. |
252 | \row |
253 | \li qreal |
254 | \li barValue |
255 | \li The value of the bar. This value comes from the \l{QBarSet::values}. |
256 | \row |
257 | \li QString |
258 | \li barLabel |
259 | \li The label of the bar. This value comes from the \l{QBarSet::label}. |
260 | \row |
261 | \li bool |
262 | \li barSelected |
263 | \li This value is true when the bar is selected, meaning that the bar index |
264 | is in \l{QBarSet::selectedBars}. |
265 | \endtable |
266 | |
267 | To use any of these, add property with the defined name into your custom component. |
268 | For example \c{"property color barColor"} and \c{"property real barValue"}. |
269 | */ |
270 | /*! |
271 | \qmlproperty Component BarSeries::barDelegate |
272 | A custom QML component used for visualizing each of the bars. |
273 | Instance of this component is created for each of the bar. |
274 | When this is not defined, a default rectangle visualization for bars is used. |
275 | |
276 | The dynamic properties available for this component are: |
277 | |
278 | \table |
279 | \header |
280 | \li Type |
281 | \li Name |
282 | \li Description |
283 | \row |
284 | \li color |
285 | \li barColor |
286 | \li The fill color of the bar. This value comes either from the \l GraphsTheme |
287 | or from \l{BarSet::color} if the \l BarSet overrides the color. |
288 | \row |
289 | \li color |
290 | \li barBorderColor |
291 | \li The border color of the bar. This value comes either from the \l GraphsTheme |
292 | or from \l{BarSet::borderColor} if the \l BarSet overrides the color. |
293 | \row |
294 | \li real |
295 | \li barBorderWidth |
296 | \li The width of the bar border. This value comes either from the \l GraphsTheme |
297 | or from \l{BarSet::borderWidth} if the \l BarSet overrides the width. |
298 | \row |
299 | \li real |
300 | \li barValue |
301 | \li The value of the bar. This value comes from the \l{BarSet::values}. |
302 | \row |
303 | \li string |
304 | \li barLabel |
305 | \li The label of the bar. This value comes from the \l{BarSet::label}. |
306 | \row |
307 | \li bool |
308 | \li barSelected |
309 | \li This value is true when the bar is selected, meaning that the bar index |
310 | is in \l{BarSet::selectedBars}. |
311 | \endtable |
312 | |
313 | To use any of these, add property with the defined name into your custom component. |
314 | For example \c{"property color barColor"} and \c{"property real barValue"}. |
315 | */ |
316 | |
317 | /*! |
318 | \property QBarSeries::barSets |
319 | \brief A list of sets added to the series. |
320 | */ |
321 | /*! |
322 | \qmlproperty list<BarSet> BarSeries::barSets |
323 | A list of sets added to the series. |
324 | */ |
325 | |
326 | /*! |
327 | \fn void QBarSeries::updatedBars() |
328 | This signal is emitted when bars are updated. |
329 | */ |
330 | |
331 | /*! |
332 | \fn void QBarSeries::labelsVisibleChanged(bool visible) |
333 | This signal is emitted when the labels' visibility changes to \a visible. |
334 | \sa labelsVisible(), setLabelsVisible() |
335 | */ |
336 | |
337 | /*! |
338 | \fn void QBarSeries::barsetsAdded(const QList<QBarSet *> &sets) |
339 | This signal is emitted when the bar sets specified by \a sets are added to the series. |
340 | \sa append(), insert() |
341 | */ |
342 | /*! |
343 | \qmlsignal BarSeries::barsetsAdded() |
344 | This signal is emitted when bar sets are added to the series. |
345 | */ |
346 | |
347 | /*! |
348 | \fn void QBarSeries::barsetsRemoved(const QList<QBarSet *> &sets) |
349 | This signal is emitted when the bar sets specified by \a sets are removed from the series. |
350 | \sa remove() |
351 | */ |
352 | /*! |
353 | \qmlsignal BarSeries::barsetsRemoved() |
354 | This signal is emitted when bar sets are removed from the series. |
355 | */ |
356 | |
357 | /*! |
358 | \fn void QBarSeries::setValueChanged(qsizetype index, QBarSet *barset) |
359 | This signal is emitted when a barset's value is changed. \a index is the index of |
360 | the barset in the series. The \a barset is a pointer to the changed set. |
361 | */ |
362 | /*! |
363 | \fn void QBarSeries::setValueAdded(qsizetype index, qsizetype count, QBarSet *barset) |
364 | This signal is emitted when a barset's value is changed. \a index is the index of |
365 | the barset in the series. The number of the added values is indicated \a count. |
366 | The \a barset is a pointer to the changed set. |
367 | */ |
368 | /*! |
369 | \fn void QBarSeries::setValueRemoved(qsizetype index, qsizetype count, QBarSet *barset) |
370 | This signal is emitted when a barset's value is changed. \a index is the index of |
371 | the barset in the series. The number of the removed values is indicated \a count. |
372 | The \a barset is a pointer to the changed set. |
373 | */ |
374 | |
375 | /*! |
376 | \qmlmethod BarSet BarSeries::at(int index) |
377 | Returns the bar set at \a index. Returns null if the index is not valid. |
378 | */ |
379 | |
380 | /*! |
381 | \qmlmethod BarSet BarSeries::insert(int index, string label, VariantList values) |
382 | Adds a new bar set with \a label and \a values to \a index. \a values can be a list |
383 | of real values or a list of XYPoint types. |
384 | |
385 | If the index value is equal to or less than zero, the new bar set is prepended to the bar |
386 | series. If the index value is equal to or greater than the number of bar sets in the bar |
387 | series, the new bar set is appended to the bar series. |
388 | |
389 | \sa append() |
390 | */ |
391 | |
392 | /*! |
393 | \qmlmethod bool BarSeries::remove(BarSet barset) |
394 | Removes the bar set specified by \a barset from the series. Returns \c true if successful, |
395 | \c false otherwise. |
396 | */ |
397 | |
398 | /*! |
399 | \qmlmethod BarSeries::clear() |
400 | Removes all bar sets from the series. |
401 | */ |
402 | |
403 | /*! |
404 | \qmlmethod bool BarSeries::replace(int index, BarSet barset) |
405 | Replaces the bar set at the position specified by \a index from the series and replaces it |
406 | with \a barset. Returns \c true if successful, \c false otherwise. |
407 | */ |
408 | |
409 | /*! |
410 | \qmlmethod Barset BarSeries::at(int index) |
411 | Returns the bar set specified by \a index from the series. Returns \c null otherwise. |
412 | */ |
413 | |
414 | /*! |
415 | \qmlmethod int BarSeries::find(BarSet barset) |
416 | Returns the index of the bar set specified by \a barset from the series. Returns \c -1 if |
417 | not found. |
418 | */ |
419 | |
420 | /*! |
421 | \qmlmethod BarSeries::removeMultiple(int index, int count) |
422 | Removes a range of bar sets as specified by the \a index and \a count. The call |
423 | traverses over all sets even if removal of one fails. |
424 | */ |
425 | |
426 | /*! |
427 | \qmlmethod bool BarSeries::remove(int index) |
428 | Removes the bar set specified by \a index from the series. Returns \c true if the |
429 | removal was successful, \c false otherwise. |
430 | */ |
431 | |
432 | /*! |
433 | \qmlmethod bool BarSeries::replace(BarSet oldSet, BarSet newSet) |
434 | Replaces the bar set specified by \a oldSet with newSet. Returns \c true if the |
435 | removal was successful, \c false otherwise. \a oldSet is destroyed if this |
436 | is successful. |
437 | */ |
438 | |
439 | /*! |
440 | \qmlmethod bool BarSeries::replace(list<BarSet> sets) |
441 | Completely replaces all current bar set with \a sets. The size does not need |
442 | to match. Returns false if any of the bar set in \a sets are invalid. |
443 | */ |
444 | |
445 | /*! |
446 | \internal |
447 | */ |
448 | |
449 | /*! |
450 | Constructs an empty bar series that is a QObject and a child of \a parent. |
451 | */ |
452 | QBarSeries::QBarSeries(QObject *parent) |
453 | : QAbstractSeries(*(new QBarSeriesPrivate()), parent) |
454 | {} |
455 | |
456 | QBarSeries::~QBarSeries() {} |
457 | |
458 | QBarSeries::QBarSeries(QBarSeriesPrivate &dd, QObject *parent) |
459 | : QAbstractSeries(dd, parent) |
460 | {} |
461 | |
462 | /*! |
463 | Returns the bar series. |
464 | */ |
465 | QAbstractSeries::SeriesType QBarSeries::type() const |
466 | { |
467 | return QAbstractSeries::SeriesType::Bar; |
468 | } |
469 | |
470 | /*! |
471 | \property QBarSeries::seriesColors |
472 | \brief The list of base colors to be used for all the objects in the series. |
473 | |
474 | If there are more series than colors, the color list wraps and starts again |
475 | with the first color in the list. If this is not set (default), colors |
476 | from the \l{QGraphsTheme::seriesColors} will be used. |
477 | */ |
478 | /*! |
479 | \qmlproperty list<color> BarSeries::seriesColors |
480 | The list of base colors to be used for all the objects in the series. |
481 | |
482 | If there are more series than colors, the color list wraps and starts again |
483 | with the first color in the list. If this is not set (default), colors |
484 | from the \l{GraphsTheme::seriesColors} will be used. |
485 | */ |
486 | QList<QColor> QBarSeries::seriesColors() const |
487 | { |
488 | Q_D(const QBarSeries); |
489 | return d->m_seriesColors; |
490 | } |
491 | |
492 | void QBarSeries::setSeriesColors(const QList<QColor> &newSeriesColors) |
493 | { |
494 | Q_D(QBarSeries); |
495 | if (d->m_seriesColors == newSeriesColors) |
496 | return; |
497 | d->m_seriesColors = newSeriesColors; |
498 | emit seriesColorsChanged(); |
499 | emit update(); |
500 | } |
501 | |
502 | /*! |
503 | \property QBarSeries::borderColors |
504 | \brief The list of border colors to be used for all the objects in the series. |
505 | |
506 | If there are more series than colors, the color list wraps and starts again |
507 | with the first color in the list. If this is not set (default), colors |
508 | from the \l{QGraphsTheme::borderColors} will be used. |
509 | */ |
510 | /*! |
511 | \qmlproperty list<color> BarSeries::borderColors |
512 | The list of border colors to be used for all the objects in the series. |
513 | |
514 | If there are more series than colors, the color list wraps and starts again |
515 | with the first color in the list. If this is not set (default), colors |
516 | from the \l{GraphsTheme::borderColors} will be used. |
517 | */ |
518 | QList<QColor> QBarSeries::borderColors() const |
519 | { |
520 | Q_D(const QBarSeries); |
521 | return d->m_borderColors; |
522 | } |
523 | |
524 | void QBarSeries::setBorderColors(const QList<QColor> &newBorderColors) |
525 | { |
526 | Q_D(QBarSeries); |
527 | if (d->m_borderColors == newBorderColors) |
528 | return; |
529 | d->m_borderColors = newBorderColors; |
530 | emit borderColorsChanged(); |
531 | emit update(); |
532 | } |
533 | |
534 | void QBarSeries::setBarsType(QBarSeries::BarsType type) |
535 | { |
536 | Q_D(QBarSeries); |
537 | if (d->m_barsType != type) { |
538 | d->m_barsType = type; |
539 | emit barsTypeChanged(type); |
540 | emit update(); |
541 | } |
542 | } |
543 | |
544 | QBarSeries::BarsType QBarSeries::barsType() const |
545 | { |
546 | Q_D(const QBarSeries); |
547 | return d->m_barsType; |
548 | } |
549 | |
550 | /*! |
551 | Sets the width of the bars of the series to \a width. |
552 | */ |
553 | void QBarSeries::setBarWidth(qreal width) |
554 | { |
555 | Q_D(QBarSeries); |
556 | if (d->barWidth() != width) { |
557 | d->setBarWidth(width); |
558 | emit barWidthChanged(); |
559 | } |
560 | } |
561 | |
562 | /*! |
563 | Returns the width of the bars of the series. |
564 | \sa setBarWidth() |
565 | */ |
566 | qreal QBarSeries::barWidth() const |
567 | { |
568 | Q_D(const QBarSeries); |
569 | return d->barWidth(); |
570 | } |
571 | |
572 | /*! |
573 | Adds a set of bars specified by \a set to the bar series and takes ownership of it. If the set |
574 | is null or it already belongs to the series, it will not be appended. |
575 | Returns \c true if appending succeeded. |
576 | */ |
577 | bool QBarSeries::append(QBarSet *set) |
578 | { |
579 | Q_D(QBarSeries); |
580 | bool success = d->append(set); |
581 | if (success) { |
582 | QList<QBarSet *> sets; |
583 | sets.append(t: set); |
584 | set->setParent(this); |
585 | QObject::connect(sender: set, signal: &QBarSet::update, context: this, slot: &QBarSeries::update); |
586 | emit barsetsAdded(sets); |
587 | emit countChanged(); |
588 | emit update(); |
589 | } |
590 | return success; |
591 | } |
592 | |
593 | /*! |
594 | Removes the bar set specified by \a set from the series and permanently deletes it if |
595 | the removal succeeds. Returns \c true if the set was removed. |
596 | */ |
597 | bool QBarSeries::remove(QBarSet *set) |
598 | { |
599 | Q_D(QBarSeries); |
600 | bool success = d->remove(set); |
601 | if (success) { |
602 | QList<QBarSet *> sets; |
603 | sets.append(t: set); |
604 | set->setParent(0); |
605 | QObject::disconnect(sender: set, signal: &QBarSet::update, receiver: this, slot: &QBarSeries::update); |
606 | emit barsetsRemoved(sets); |
607 | emit countChanged(); |
608 | emit update(); |
609 | delete set; |
610 | set = 0; |
611 | } |
612 | return success; |
613 | } |
614 | |
615 | /*! |
616 | Takes a single \a set from the series. Does not delete the bar set object. |
617 | \note The series remains the barset's parent object. You must set the |
618 | parent object to take full ownership. |
619 | |
620 | Returns \c true if the take operation succeeds. |
621 | */ |
622 | bool QBarSeries::take(QBarSet *set) |
623 | { |
624 | Q_D(QBarSeries); |
625 | bool success = d->remove(set); |
626 | if (success) { |
627 | QList<QBarSet *> sets; |
628 | sets.append(t: set); |
629 | QObject::disconnect(sender: set, signal: &QBarSet::update, receiver: this, slot: &QBarSeries::update); |
630 | emit barsetsRemoved(sets); |
631 | emit countChanged(); |
632 | emit update(); |
633 | } |
634 | return success; |
635 | } |
636 | |
637 | /*! |
638 | Adds a list of bar sets specified by \a sets to a bar series and takes ownership of the sets. |
639 | Returns \c true if all sets were appended successfully. If any of the sets is null or was |
640 | previously appended to the series, nothing is appended and this function returns \c false. |
641 | If any of the sets appears in the list more than once, nothing is appended and this function |
642 | returns \c false. |
643 | */ |
644 | bool QBarSeries::append(const QList<QBarSet *> &sets) |
645 | { |
646 | Q_D(QBarSeries); |
647 | if (!d->append(sets)) |
648 | return false; |
649 | |
650 | for (auto *set : sets) { |
651 | set->setParent(this); |
652 | QObject::connect(sender: set, signal: &QBarSet::update, context: this, slot: &QBarSeries::update); |
653 | } |
654 | |
655 | emit barsetsAdded(sets); |
656 | emit countChanged(); |
657 | emit update(); |
658 | return true; |
659 | } |
660 | |
661 | /*! |
662 | Inserts a bar set specified by \a set to a series at the position specified by \a index |
663 | and takes ownership of the set. If the set is null or already belongs to the series, it will |
664 | not be appended. Returns \c true if inserting succeeds. |
665 | */ |
666 | bool QBarSeries::insert(qsizetype index, QBarSet *set) |
667 | { |
668 | Q_D(QBarSeries); |
669 | bool success = d->insert(index, set); |
670 | if (success) { |
671 | QList<QBarSet *> sets; |
672 | sets.append(t: set); |
673 | QObject::connect(sender: set, signal: &QBarSet::update, context: this, slot: &QBarSeries::update); |
674 | emit barsetsAdded(sets); |
675 | emit countChanged(); |
676 | emit update(); |
677 | } |
678 | return success; |
679 | } |
680 | |
681 | /*! |
682 | Removes all bar sets from the series and permanently deletes them. |
683 | */ |
684 | void QBarSeries::clear() |
685 | { |
686 | Q_D(QBarSeries); |
687 | const QList<QBarSet *> sets = barSets(); |
688 | bool success = d->remove(sets); |
689 | if (success) { |
690 | emit barsetsRemoved(sets); |
691 | emit countChanged(); |
692 | for (QBarSet *set : sets) { |
693 | QObject::disconnect(sender: set, signal: &QBarSet::update, receiver: this, slot: &QBarSeries::update); |
694 | set->deleteLater(); |
695 | } |
696 | emit update(); |
697 | } |
698 | } |
699 | |
700 | /*! |
701 | Replaces the BarSet which is present at \a index with \a set. |
702 | The original BarSet will be permanently deleted. |
703 | */ |
704 | void QBarSeries::replace(qsizetype index, QBarSet *set) |
705 | { |
706 | Q_D(QBarSeries); |
707 | |
708 | if (d->m_barSets.size() <= index) |
709 | return; |
710 | if (!set) |
711 | return; |
712 | if (index < 0) |
713 | index = 0; |
714 | |
715 | remove(set: d->m_barSets[index]); |
716 | d->insert(index, set); |
717 | |
718 | QList<QBarSet *> sets; |
719 | sets.append(t: set); |
720 | QObject::connect(sender: set, signal: &QBarSet::update, context: this, slot: &QBarSeries::update); |
721 | emit barsetsReplaced(sets); |
722 | } |
723 | |
724 | /*! |
725 | Retrieves the BarSet specified at the location \a index. |
726 | Returns null if no BarSet was found. |
727 | */ |
728 | QBarSet *QBarSeries::at(qsizetype index) |
729 | { |
730 | Q_D(QBarSeries); |
731 | |
732 | if (d->m_barSets.size() <= index) |
733 | return nullptr; |
734 | if (index < 0) |
735 | return nullptr; |
736 | |
737 | return d->m_barSets[index]; |
738 | } |
739 | |
740 | /*! |
741 | Returns the index of the first BarSet found as defined by \a set. Returns -1 if no BarSet was found. |
742 | */ |
743 | qsizetype QBarSeries::find(QBarSet *set) const |
744 | { |
745 | Q_D(const QBarSeries); |
746 | |
747 | for (qsizetype i = 0; i < d->m_barSets.size(); ++i) { |
748 | if (set == d->m_barSets[i]) |
749 | return i; |
750 | } |
751 | |
752 | return -1; |
753 | } |
754 | |
755 | /*! |
756 | Removes multiple BarSets from the series starting from \a index to a number of \a count. |
757 | The BarSets will be permanently deleted. |
758 | */ |
759 | void QBarSeries::removeMultiple(qsizetype index, qsizetype count) |
760 | { |
761 | Q_D(QBarSeries); |
762 | |
763 | if (index + count >= d->m_barSets.size()) |
764 | return; |
765 | if (index < 0 || count < 0) |
766 | return; |
767 | |
768 | for (qsizetype i = index; i < index + count; ++i) |
769 | remove(set: d->m_barSets[index]); |
770 | } |
771 | |
772 | /*! |
773 | Removes the BarSet at the location \a index. The BarSet will be permanently deleted. |
774 | */ |
775 | bool QBarSeries::remove(qsizetype index) |
776 | { |
777 | Q_D(QBarSeries); |
778 | |
779 | if (index >= d->m_barSets.size()) |
780 | return false; |
781 | if (index < 0) |
782 | return false; |
783 | |
784 | return remove(set: d->m_barSets[index]); |
785 | } |
786 | |
787 | /*! |
788 | Replaces the BarSet specified by \a oldValue with the one in \a newValue. The BarSet |
789 | in \a oldValue will be permanently deleted if found inside the series. Returns \c true if |
790 | the replace is successful. |
791 | */ |
792 | bool QBarSeries::replace(QBarSet *oldValue, QBarSet *newValue) |
793 | { |
794 | Q_D(QBarSeries); |
795 | |
796 | if (!oldValue || !newValue) |
797 | return false; |
798 | if (oldValue == newValue) |
799 | return false; |
800 | |
801 | for (qsizetype i = 0; i < d->m_barSets.size(); ++i) { |
802 | if (d->m_barSets[i] == oldValue) { |
803 | remove(set: d->m_barSets[i]); |
804 | d->insert(index: i, set: newValue); |
805 | |
806 | QList<QBarSet *> sets; |
807 | sets.append(t: newValue); |
808 | QObject::connect(sender: newValue, signal: &QBarSet::update, context: this, slot: &QBarSeries::update); |
809 | emit barsetsReplaced(sets); |
810 | return true; |
811 | } |
812 | } |
813 | |
814 | return false; |
815 | } |
816 | |
817 | /*! |
818 | Replaces the entire BarSet list inside of this BarSeries with the BarSets specified by \a sets. |
819 | All of the original BarSets will be permanently deleted. Returns \c true if all BarSets are replaced. |
820 | */ |
821 | bool QBarSeries::replace(const QList<QBarSet *> &sets) |
822 | { |
823 | Q_D(QBarSeries); |
824 | |
825 | for (const auto set : sets) { |
826 | if (!set) |
827 | return false; |
828 | } |
829 | |
830 | for (const auto set : d->m_barSets) { |
831 | remove(set); |
832 | } |
833 | |
834 | for (const auto set : sets) { |
835 | QObject::connect(sender: set, signal: &QBarSet::update, context: this, slot: &QBarSeries::update); |
836 | } |
837 | |
838 | d->append(sets); |
839 | emit barsetsReplaced(sets); |
840 | |
841 | return true; |
842 | } |
843 | |
844 | /*! |
845 | Returns the number of bar sets in a bar series. |
846 | */ |
847 | qsizetype QBarSeries::count() const |
848 | { |
849 | Q_D(const QBarSeries); |
850 | return d->m_barSets.size(); |
851 | } |
852 | |
853 | /*! |
854 | Returns a list of bar sets in a bar series. Keeps the ownership of the bar sets. |
855 | */ |
856 | QList<QBarSet *> QBarSeries::barSets() const |
857 | { |
858 | Q_D(const QBarSeries); |
859 | return d->m_barSets; |
860 | } |
861 | |
862 | /*! |
863 | Sets the visibility of labels in a bar series to \a visible. |
864 | */ |
865 | void QBarSeries::setLabelsVisible(bool visible) |
866 | { |
867 | Q_D(QBarSeries); |
868 | if (d->m_labelsVisible != visible) { |
869 | d->setLabelsVisible(visible); |
870 | emit labelsVisibleChanged(visible); |
871 | emit update(); |
872 | } |
873 | } |
874 | |
875 | /*! |
876 | Returns the visibility of labels. |
877 | */ |
878 | bool QBarSeries::labelsVisible() const |
879 | { |
880 | Q_D(const QBarSeries); |
881 | return d->m_labelsVisible; |
882 | } |
883 | |
884 | void QBarSeries::setLabelsFormat(const QString &format) |
885 | { |
886 | Q_D(QBarSeries); |
887 | if (d->m_labelsFormat != format) { |
888 | d->m_labelsFormat = format; |
889 | d->setLabelsDirty(true); |
890 | emit labelsFormatChanged(format); |
891 | emit update(); |
892 | } |
893 | } |
894 | |
895 | QString QBarSeries::labelsFormat() const |
896 | { |
897 | Q_D(const QBarSeries); |
898 | return d->m_labelsFormat; |
899 | } |
900 | |
901 | void QBarSeries::setLabelsMargin(qreal margin) |
902 | { |
903 | Q_D(QBarSeries); |
904 | if (d->m_labelsMargin != margin) { |
905 | d->m_labelsMargin = margin; |
906 | d->setLabelsDirty(true); |
907 | emit labelsMarginChanged(margin); |
908 | emit update(); |
909 | } |
910 | } |
911 | |
912 | qreal QBarSeries::labelsMargin() const |
913 | { |
914 | Q_D(const QBarSeries); |
915 | return d->m_labelsMargin; |
916 | } |
917 | |
918 | void QBarSeries::setLabelsAngle(qreal angle) |
919 | { |
920 | Q_D(QBarSeries); |
921 | if (d->m_labelsAngle != angle) { |
922 | d->m_labelsAngle = angle; |
923 | d->setLabelsDirty(true); |
924 | emit labelsAngleChanged(angle); |
925 | emit update(); |
926 | } |
927 | } |
928 | |
929 | qreal QBarSeries::labelsAngle() const |
930 | { |
931 | Q_D(const QBarSeries); |
932 | return d->m_labelsAngle; |
933 | } |
934 | |
935 | void QBarSeries::setLabelsPosition(QBarSeries::LabelsPosition position) |
936 | { |
937 | Q_D(QBarSeries); |
938 | if (d->m_labelsPosition != position) { |
939 | d->m_labelsPosition = position; |
940 | emit labelsPositionChanged(position); |
941 | emit update(); |
942 | } |
943 | } |
944 | |
945 | QBarSeries::LabelsPosition QBarSeries::labelsPosition() const |
946 | { |
947 | Q_D(const QBarSeries); |
948 | return d->m_labelsPosition; |
949 | } |
950 | |
951 | void QBarSeries::setLabelsPrecision(int precision) |
952 | { |
953 | Q_D(QBarSeries); |
954 | if (d->m_labelsPrecision != precision) { |
955 | d->m_labelsPrecision = precision; |
956 | d->setLabelsDirty(true); |
957 | emit labelsPrecisionChanged(precision); |
958 | emit update(); |
959 | } |
960 | } |
961 | |
962 | int QBarSeries::labelsPrecision() const |
963 | { |
964 | Q_D(const QBarSeries); |
965 | return d->m_labelsPrecision; |
966 | } |
967 | |
968 | QQmlComponent *QBarSeries::barDelegate() const |
969 | { |
970 | Q_D(const QBarSeries); |
971 | return d->m_barDelegate; |
972 | } |
973 | |
974 | void QBarSeries::setBarDelegate(QQmlComponent *newBarDelegate) |
975 | { |
976 | Q_D(QBarSeries); |
977 | if (d->m_barDelegate == newBarDelegate) |
978 | return; |
979 | d->m_barDelegate = newBarDelegate; |
980 | d->m_barDelegateDirty = true; |
981 | emit barDelegateChanged(); |
982 | emit update(); |
983 | } |
984 | |
985 | // Select all the elements in the series |
986 | void QBarSeries::selectAll() |
987 | { |
988 | Q_D(QBarSeries); |
989 | for (auto s : d->m_barSets) { |
990 | s->selectAllBars(); |
991 | } |
992 | } |
993 | |
994 | // Deselect all the elements in the series |
995 | void QBarSeries::deselectAll() |
996 | { |
997 | Q_D(QBarSeries); |
998 | for (auto s : d->m_barSets) { |
999 | s->deselectAllBars(); |
1000 | } |
1001 | } |
1002 | |
1003 | void QBarSeries::componentComplete() |
1004 | { |
1005 | for (auto *child : children()) { |
1006 | if (auto bs = qobject_cast<QBarSet *>(object: child)) |
1007 | append(set: bs); |
1008 | } |
1009 | QAbstractSeries::componentComplete(); |
1010 | } |
1011 | |
1012 | void QBarSeries::handleSetValueChange(qsizetype index) |
1013 | { |
1014 | QBarSet *set = qobject_cast<QBarSet *>(object: sender()); |
1015 | if (set) |
1016 | emit setValueChanged(index, barset: set); |
1017 | emit update(); |
1018 | } |
1019 | |
1020 | void QBarSeries::handleSetValueAdd(qsizetype index, qsizetype count) |
1021 | { |
1022 | QBarSet *set = qobject_cast<QBarSet *>(object: sender()); |
1023 | if (set) |
1024 | emit setValueAdded(index, count, barset: set); |
1025 | emit update(); |
1026 | } |
1027 | |
1028 | void QBarSeries::handleSetValueRemove(qsizetype index, qsizetype count) |
1029 | { |
1030 | QBarSet *set = qobject_cast<QBarSet *>(object: sender()); |
1031 | if (set) |
1032 | emit setValueRemoved(index, count, barset: set); |
1033 | emit update(); |
1034 | } |
1035 | |
1036 | bool QBarSeries::barDelegateDirty() const |
1037 | { |
1038 | Q_D(const QBarSeries); |
1039 | return d->m_barDelegateDirty; |
1040 | } |
1041 | |
1042 | void QBarSeries::setBarDelegateDirty(bool dirty) |
1043 | { |
1044 | Q_D(QBarSeries); |
1045 | d->m_barDelegateDirty = dirty; |
1046 | } |
1047 | |
1048 | QBarSeriesPrivate::QBarSeriesPrivate() |
1049 | : m_barWidth(0.5) // Default value is 50% of category width |
1050 | , m_labelsVisible(false) |
1051 | , m_visible(true) |
1052 | , m_blockBarUpdate(false) |
1053 | , m_labelsFormat() |
1054 | , m_labelsMargin(0) |
1055 | , m_labelsAngle(0) |
1056 | , m_labelsPrecision(6) |
1057 | , m_labelsDirty(true) |
1058 | , m_barDelegateDirty(false) |
1059 | { |
1060 | } |
1061 | |
1062 | qsizetype QBarSeriesPrivate::categoryCount() const |
1063 | { |
1064 | // No categories defined. return count of longest set. |
1065 | qsizetype count = 0; |
1066 | for (qsizetype i = 0; i < m_barSets.size(); i++) { |
1067 | if (m_barSets.at(i)->count() > count) |
1068 | count = m_barSets.at(i)->count(); |
1069 | } |
1070 | |
1071 | return count; |
1072 | } |
1073 | |
1074 | void QBarSeriesPrivate::setBarWidth(qreal width) |
1075 | { |
1076 | Q_Q(QBarSeries); |
1077 | width = std::clamp<qreal>(val: width, lo: 0.0, hi: 1.0); |
1078 | if (!qFuzzyCompare(p1: width, p2: m_barWidth)) { |
1079 | m_barWidth = width; |
1080 | q->update(); |
1081 | } |
1082 | } |
1083 | |
1084 | qreal QBarSeriesPrivate::barWidth() const |
1085 | { |
1086 | return m_barWidth; |
1087 | } |
1088 | |
1089 | QBarSet *QBarSeriesPrivate::barsetAt(qsizetype index) |
1090 | { |
1091 | return m_barSets.at(i: index); |
1092 | } |
1093 | |
1094 | void QBarSeriesPrivate::setVisible(bool visible) |
1095 | { |
1096 | Q_Q(QBarSeries); |
1097 | m_visible = visible; |
1098 | emit q->visibleChanged(); |
1099 | } |
1100 | |
1101 | void QBarSeriesPrivate::setLabelsVisible(bool visible) |
1102 | { |
1103 | m_labelsVisible = visible; |
1104 | } |
1105 | |
1106 | qreal QBarSeriesPrivate::min() |
1107 | { |
1108 | if (m_barSets.size() <= 0) |
1109 | return 0; |
1110 | |
1111 | qreal min = INT_MAX; |
1112 | |
1113 | for (int i = 0; i < m_barSets.size(); i++) { |
1114 | qsizetype categoryCount = m_barSets.at(i)->count(); |
1115 | for (qsizetype j = 0; j < categoryCount; j++) { |
1116 | qreal temp = m_barSets.at(i)->at(index: j); |
1117 | if (temp < min) |
1118 | min = temp; |
1119 | } |
1120 | } |
1121 | return min; |
1122 | } |
1123 | |
1124 | qreal QBarSeriesPrivate::max() |
1125 | { |
1126 | if (m_barSets.size() <= 0) |
1127 | return 0; |
1128 | |
1129 | qreal max = INT_MIN; |
1130 | |
1131 | for (int i = 0; i < m_barSets.size(); i++) { |
1132 | qsizetype categoryCount = m_barSets.at(i)->count(); |
1133 | for (qsizetype j = 0; j < categoryCount; j++) { |
1134 | qreal temp = m_barSets.at(i)->at(index: j); |
1135 | if (temp > max) |
1136 | max = temp; |
1137 | } |
1138 | } |
1139 | |
1140 | return max; |
1141 | } |
1142 | |
1143 | qreal QBarSeriesPrivate::valueAt(int set, int category) |
1144 | { |
1145 | if ((set < 0) || (set >= m_barSets.size())) |
1146 | return 0; // No set, no value. |
1147 | else if ((category < 0) || (category >= m_barSets.at(i: set)->count())) |
1148 | return 0; // No category, no value. |
1149 | |
1150 | return m_barSets.at(i: set)->at(index: category); |
1151 | } |
1152 | |
1153 | qreal QBarSeriesPrivate::percentageAt(int set, int category) |
1154 | { |
1155 | if ((set < 0) || (set >= m_barSets.size())) |
1156 | return 0; // No set, no value. |
1157 | else if ((category < 0) || (category >= m_barSets.at(i: set)->count())) |
1158 | return 0; // No category, no value. |
1159 | |
1160 | qreal value = m_barSets.at(i: set)->at(index: category); |
1161 | qreal sum = categorySum(category); |
1162 | if (qFuzzyCompare(p1: sum, p2: 0)) |
1163 | return 0; |
1164 | |
1165 | return value / sum; |
1166 | } |
1167 | |
1168 | qreal QBarSeriesPrivate::categorySum(qsizetype category) |
1169 | { |
1170 | qreal sum(0); |
1171 | qsizetype count = m_barSets.size(); // Count sets |
1172 | for (qsizetype set = 0; set < count; set++) { |
1173 | if (category < m_barSets.at(i: set)->count()) |
1174 | sum += m_barSets.at(i: set)->at(index: category); |
1175 | } |
1176 | return sum; |
1177 | } |
1178 | |
1179 | qreal QBarSeriesPrivate::absoluteCategorySum(int category) |
1180 | { |
1181 | qreal sum(0); |
1182 | qsizetype count = m_barSets.size(); // Count sets |
1183 | for (qsizetype set = 0; set < count; set++) { |
1184 | if (category < m_barSets.at(i: set)->count()) |
1185 | sum += qAbs(t: m_barSets.at(i: set)->at(index: category)); |
1186 | } |
1187 | return sum; |
1188 | } |
1189 | |
1190 | qreal QBarSeriesPrivate::maxCategorySum() |
1191 | { |
1192 | qreal max = INT_MIN; |
1193 | qsizetype count = categoryCount(); |
1194 | for (qsizetype i = 0; i < count; i++) { |
1195 | qreal sum = categorySum(category: i); |
1196 | if (sum > max) |
1197 | max = sum; |
1198 | } |
1199 | return max; |
1200 | } |
1201 | |
1202 | qreal QBarSeriesPrivate::minX() |
1203 | { |
1204 | if (m_barSets.size() <= 0) |
1205 | return 0; |
1206 | |
1207 | qreal min = INT_MAX; |
1208 | |
1209 | for (int i = 0; i < m_barSets.size(); i++) { |
1210 | qsizetype categoryCount = m_barSets.at(i)->count(); |
1211 | for (qsizetype j = 0; j < categoryCount; j++) { |
1212 | qreal temp = m_barSets.at(i)->d_func()->m_values.at(i: j).x(); |
1213 | if (temp < min) |
1214 | min = temp; |
1215 | } |
1216 | } |
1217 | return min; |
1218 | } |
1219 | |
1220 | qreal QBarSeriesPrivate::maxX() |
1221 | { |
1222 | if (m_barSets.size() <= 0) |
1223 | return 0; |
1224 | |
1225 | qreal max = INT_MIN; |
1226 | |
1227 | for (int i = 0; i < m_barSets.size(); i++) { |
1228 | qsizetype categoryCount = m_barSets.at(i)->count(); |
1229 | for (qsizetype j = 0; j < categoryCount; j++) { |
1230 | qreal temp = m_barSets.at(i)->d_func()->m_values.at(i: j).x(); |
1231 | if (temp > max) |
1232 | max = temp; |
1233 | } |
1234 | } |
1235 | |
1236 | return max; |
1237 | } |
1238 | |
1239 | qreal QBarSeriesPrivate::categoryTop(qsizetype category) |
1240 | { |
1241 | // Returns top (sum of all positive values) of category. |
1242 | // Returns 0, if all values are negative |
1243 | qreal top(0); |
1244 | qsizetype count = m_barSets.size(); |
1245 | for (qsizetype set = 0; set < count; set++) { |
1246 | if (category < m_barSets.at(i: set)->count()) { |
1247 | qreal temp = m_barSets.at(i: set)->at(index: category); |
1248 | if (temp > 0) { |
1249 | top += temp; |
1250 | } |
1251 | } |
1252 | } |
1253 | return top; |
1254 | } |
1255 | |
1256 | qreal QBarSeriesPrivate::categoryBottom(qsizetype category) |
1257 | { |
1258 | // Returns bottom (sum of all negative values) of category |
1259 | // Returns 0, if all values are positive |
1260 | qreal bottom(0); |
1261 | qsizetype count = m_barSets.size(); |
1262 | for (qsizetype set = 0; set < count; set++) { |
1263 | if (category < m_barSets.at(i: set)->count()) { |
1264 | qreal temp = m_barSets.at(i: set)->at(index: category); |
1265 | if (temp < 0) { |
1266 | bottom += temp; |
1267 | } |
1268 | } |
1269 | } |
1270 | return bottom; |
1271 | } |
1272 | qreal QBarSeriesPrivate::top() |
1273 | { |
1274 | // Returns top of all categories |
1275 | qreal top(0); |
1276 | qsizetype count = categoryCount(); |
1277 | for (qsizetype i = 0; i < count; i++) { |
1278 | qreal temp = categoryTop(category: i); |
1279 | if (temp > top) |
1280 | top = temp; |
1281 | } |
1282 | return top; |
1283 | } |
1284 | |
1285 | qreal QBarSeriesPrivate::bottom() |
1286 | { |
1287 | // Returns bottom of all categories |
1288 | qreal bottom(0); |
1289 | qsizetype count = categoryCount(); |
1290 | for (qsizetype i = 0; i < count; i++) { |
1291 | qreal temp = categoryBottom(category: i); |
1292 | if (temp < bottom) |
1293 | bottom = temp; |
1294 | } |
1295 | return bottom; |
1296 | } |
1297 | |
1298 | bool QBarSeriesPrivate::blockBarUpdate() |
1299 | { |
1300 | return m_blockBarUpdate; |
1301 | } |
1302 | |
1303 | bool QBarSeriesPrivate::append(QBarSet *set) |
1304 | { |
1305 | if ((m_barSets.contains(t: set)) || (set == 0)) |
1306 | return false; // Fail if set is already in list or set is null. |
1307 | |
1308 | m_barSets.append(t: set); |
1309 | Q_Q(QBarSeries); |
1310 | QObject::connect(sender: set, signal: &QBarSet::updatedBars, context: q, slot: &QBarSeries::updatedBars); |
1311 | QObject::connect(sender: set, signal: &QBarSet::valueChanged, context: q, slot: &QBarSeries::handleSetValueChange); |
1312 | QObject::connect(sender: set, signal: &QBarSet::valueAdded, context: q, slot: &QBarSeries::handleSetValueAdd); |
1313 | QObject::connect(sender: set, signal: &QBarSet::valueRemoved, context: q, slot: &QBarSeries::handleSetValueRemove); |
1314 | QObject::connect(sender: set, signal: &QBarSet::selectedBarsChanged, context: q, slot: &QBarSeries::updatedBars); |
1315 | |
1316 | return true; |
1317 | } |
1318 | |
1319 | bool QBarSeriesPrivate::remove(QBarSet *set) |
1320 | { |
1321 | if (!m_barSets.contains(t: set)) |
1322 | return false; // Fail if set is not in list |
1323 | |
1324 | m_barSets.removeOne(t: set); |
1325 | Q_Q(QBarSeries); |
1326 | QObject::disconnect(sender: set, signal: &QBarSet::updatedBars, receiver: q, slot: &QBarSeries::updatedBars); |
1327 | QObject::disconnect(sender: set, signal: &QBarSet::valueChanged, receiver: q, slot: &QBarSeries::handleSetValueChange); |
1328 | QObject::disconnect(sender: set, signal: &QBarSet::valueAdded, receiver: q, slot: &QBarSeries::handleSetValueAdd); |
1329 | QObject::disconnect(sender: set, signal: &QBarSet::valueRemoved, receiver: q, slot: &QBarSeries::handleSetValueRemove); |
1330 | QObject::disconnect(sender: set, signal: &QBarSet::selectedBarsChanged, receiver: q, slot: &QBarSeries::updatedBars); |
1331 | |
1332 | return true; |
1333 | } |
1334 | |
1335 | bool QBarSeriesPrivate::append(const QList<QBarSet *> &sets) |
1336 | { |
1337 | for (auto *set : sets) { |
1338 | if ((set == 0) || (m_barSets.contains(t: set))) |
1339 | return false; // Fail if any of the sets is null or is already appended. |
1340 | if (sets.count(t: set) != 1) |
1341 | return false; // Also fail if same set is more than once in given list. |
1342 | } |
1343 | |
1344 | Q_Q(QBarSeries); |
1345 | for (auto *set : sets) { |
1346 | m_barSets.append(t: set); |
1347 | QObject::connect(sender: set, signal: &QBarSet::updatedBars, context: q, slot: &QBarSeries::updatedBars); |
1348 | QObject::connect(sender: set, signal: &QBarSet::valueChanged, context: q, slot: &QBarSeries::handleSetValueChange); |
1349 | QObject::connect(sender: set, signal: &QBarSet::valueAdded, context: q, slot: &QBarSeries::handleSetValueAdd); |
1350 | QObject::connect(sender: set, signal: &QBarSet::valueRemoved, context: q, slot: &QBarSeries::handleSetValueRemove); |
1351 | QObject::connect(sender: set, signal: &QBarSet::selectedBarsChanged, context: q, slot: &QBarSeries::updatedBars); |
1352 | } |
1353 | |
1354 | return true; |
1355 | } |
1356 | |
1357 | bool QBarSeriesPrivate::remove(const QList<QBarSet *> &sets) |
1358 | { |
1359 | if (sets.size() == 0) |
1360 | return false; |
1361 | |
1362 | for (QBarSet *set : sets) { |
1363 | if ((set == 0) || (!m_barSets.contains(t: set))) |
1364 | return false; // Fail if any of the sets is null or is not in series |
1365 | if (sets.count(t: set) != 1) |
1366 | return false; // Also fail if same set is more than once in given list. |
1367 | } |
1368 | |
1369 | Q_Q(QBarSeries); |
1370 | for (QBarSet *set : sets) { |
1371 | m_barSets.removeOne(t: set); |
1372 | QObject::disconnect(sender: set, signal: &QBarSet::updatedBars, receiver: q, slot: &QBarSeries::updatedBars); |
1373 | QObject::disconnect(sender: set, |
1374 | signal: &QBarSet::valueChanged, |
1375 | receiver: q, |
1376 | slot: &QBarSeries::handleSetValueChange); |
1377 | QObject::disconnect(sender: set, signal: &QBarSet::valueAdded, receiver: q, slot: &QBarSeries::handleSetValueAdd); |
1378 | QObject::disconnect(sender: set, |
1379 | signal: &QBarSet::valueRemoved, |
1380 | receiver: q, |
1381 | slot: &QBarSeries::handleSetValueRemove); |
1382 | QObject::disconnect(sender: set, signal: &QBarSet::selectedBarsChanged, receiver: q, slot: &QBarSeries::updatedBars); |
1383 | } |
1384 | |
1385 | return true; |
1386 | } |
1387 | |
1388 | bool QBarSeriesPrivate::insert(qsizetype index, QBarSet *set) |
1389 | { |
1390 | if ((m_barSets.contains(t: set)) || (set == 0)) |
1391 | return false; // Fail if set is already in list or set is null. |
1392 | |
1393 | m_barSets.insert(i: index, t: set); |
1394 | Q_Q(QBarSeries); |
1395 | QObject::connect(sender: set, signal: &QBarSet::updatedBars, context: q, slot: &QBarSeries::updatedBars); |
1396 | QObject::connect(sender: set, signal: &QBarSet::valueChanged, context: q, slot: &QBarSeries::handleSetValueChange); |
1397 | QObject::connect(sender: set, signal: &QBarSet::valueAdded, context: q, slot: &QBarSeries::handleSetValueAdd); |
1398 | QObject::connect(sender: set, signal: &QBarSet::valueRemoved, context: q, slot: &QBarSeries::handleSetValueRemove); |
1399 | QObject::disconnect(sender: set, signal: &QBarSet::selectedBarsChanged, receiver: q, slot: &QBarSeries::updatedBars); |
1400 | |
1401 | return true; |
1402 | } |
1403 | |
1404 | QT_END_NAMESPACE |
1405 | |
1406 | #include "moc_qbarseries.cpp" |
1407 |
Definitions
- QBarSeries
- ~QBarSeries
- QBarSeries
- type
- seriesColors
- setSeriesColors
- borderColors
- setBorderColors
- setBarsType
- barsType
- setBarWidth
- barWidth
- append
- remove
- take
- append
- insert
- clear
- replace
- at
- find
- removeMultiple
- remove
- replace
- replace
- count
- barSets
- setLabelsVisible
- labelsVisible
- setLabelsFormat
- labelsFormat
- setLabelsMargin
- labelsMargin
- setLabelsAngle
- labelsAngle
- setLabelsPosition
- labelsPosition
- setLabelsPrecision
- labelsPrecision
- barDelegate
- setBarDelegate
- selectAll
- deselectAll
- componentComplete
- handleSetValueChange
- handleSetValueAdd
- handleSetValueRemove
- barDelegateDirty
- setBarDelegateDirty
- QBarSeriesPrivate
- categoryCount
- setBarWidth
- barWidth
- barsetAt
- setVisible
- setLabelsVisible
- min
- max
- valueAt
- percentageAt
- categorySum
- absoluteCategorySum
- maxCategorySum
- minX
- maxX
- categoryTop
- categoryBottom
- top
- bottom
- blockBarUpdate
- append
- remove
- append
- remove
Start learning QML with our Intro Training
Find out more