1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Charts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QtCharts/QBarSet>
31#include <private/qbarset_p.h>
32#include <private/charthelpers_p.h>
33#include <private/qchart_p.h>
34
35QT_CHARTS_BEGIN_NAMESPACE
36
37/*!
38 \class QBarSet
39 \inmodule QtCharts
40 \brief The QBarSet class represents one set of bars in a bar chart.
41
42 A bar set contains one data value for each category. The first value of a set is assumed to
43 belong to the first category, the second one to the second category, and so on. If the set has
44 fewer values than there are categories, the missing values are assumed to be located at the end
45 of the set. For missing values in the middle of a set, the numerical value of zero is used.
46 Labels for zero value sets are not shown.
47
48 \sa QAbstractBarSeries, QBarSeries, QStackedBarSeries, QPercentBarSeries
49 \sa QHorizontalBarSeries, QHorizontalStackedBarSeries, QHorizontalPercentBarSeries
50*/
51/*!
52 \qmltype BarSet
53 \instantiates QBarSet
54 \inqmlmodule QtCharts
55
56 \brief Represents one set of bars in a bar chart.
57
58 A bar set contains one data value for each category. The first value of a set is assumed to
59 belong to the first category, the second one to the second category, and so on. If the set has
60 fewer values than there are categories, the missing values are assumed to be located at the end
61 of the set. For missing values in the middle of a set, the numerical value of zero is used.
62 Labels for zero value sets are not shown.
63
64 \sa AbstractBarSeries, BarSeries, StackedBarSeries, PercentBarSeries
65 \sa HorizontalBarSeries, HorizontalStackedBarSeries, HorizontalPercentBarSeries
66
67*/
68
69/*!
70 \property QBarSet::label
71 \brief The label of the bar set.
72*/
73/*!
74 \qmlproperty string BarSet::label
75 The label of the bar set.
76*/
77
78/*!
79 \property QBarSet::pen
80 \brief The pen used to draw the lines of bars in the bar set.
81*/
82
83/*!
84 \property QBarSet::brush
85 \brief The brush used to fill the bars in the bar set.
86*/
87
88/*!
89 \qmlproperty string BarSet::brushFilename
90 The name of the file used as a brush for the set.
91*/
92
93/*!
94 \property QBarSet::labelBrush
95 \brief The brush used to draw the bar set's label.
96*/
97
98/*!
99 \property QBarSet::labelFont
100 \brief The font used to draw the bar set's label.
101*/
102
103/*!
104 \qmlproperty font BarSet::labelFont
105 The font used to draw the bar set's label.
106
107 For more information, see \l [QML]{font}.
108*/
109
110/*!
111 \property QBarSet::color
112 \brief The fill (brush) color of the bar set.
113*/
114/*!
115 \qmlproperty color BarSet::color
116 The fill (brush) color of the bar set.
117*/
118
119/*!
120 \property QBarSet::borderColor
121 \brief The line (pen) color of the bar set.
122*/
123/*!
124 \qmlproperty color BarSet::borderColor
125 The line (pen) color of the bar set.
126*/
127
128/*!
129 \qmlproperty real BarSet::borderWidth
130 The width of the border line. By default, the width is 2.0.
131*/
132
133/*!
134 \property QBarSet::labelColor
135 \brief The text (label) color of the bar set.
136*/
137/*!
138 \qmlproperty color BarSet::labelColor
139 The text (label) color of the bar set.
140*/
141
142/*!
143 \fn void QBarSet::clicked(int index)
144
145 This signal is emitted when the user clicks the bar specified by \a index in a bar set.
146*/
147
148/*!
149 \qmlmethod BarSet::clicked(int index)
150
151 This signal is emitted when the user clicks the bar specified by \a index
152 in a bar set.
153
154 The corresponding signal handler is \c onClicked.
155*/
156
157/*!
158 \fn void QBarSet::pressed(int index)
159
160 This signal is emitted when the user clicks the bar specified by \a index in a bar set
161 and holds down the mouse button.
162*/
163
164/*!
165 \qmlmethod BarSet::pressed(int index)
166
167 This signal is emitted when the user clicks the bar specified by \a index in
168 a bar set and holds down the mouse button.
169
170 The corresponding signal handler is \c onPressed.
171*/
172
173/*!
174 \fn void QBarSet::released(int index)
175
176 This signal is emitted when the user releases the mouse press on the bar specified by
177 \a index in a bar set.
178*/
179
180/*!
181 \qmlmethod BarSet::released(int index)
182
183 This signal is emitted when the user releases the mouse press on the bar
184 specified by \a index in a bar set.
185
186 The corresponding signal handler is \c onReleased.
187*/
188
189/*!
190 \fn void QBarSet::doubleClicked(int index)
191
192 This signal is emitted when the user double-clicks the bar specified by \a index in a bar set.
193*/
194
195/*!
196 \qmlmethod BarSet::doubleClicked(int index)
197
198 This signal is emitted when the user double-clicks the bar specified by
199 \a index in a bar set.
200
201 The corresponding signal handler is \c onDoubleClicked.
202*/
203
204/*!
205 \fn void QBarSet::hovered(bool status, int index)
206
207 This signal is emitted when a mouse is hovered over the bar specified by \a index in a bar set.
208 When the mouse moves over the bar, \a status turns \c true, and when the mouse moves away again,
209 it turns \c false.
210*/
211
212
213/*!
214 \fn void QBarSet::labelChanged()
215 This signal is emitted when the label of the bar set changes.
216 \sa label
217*/
218
219/*!
220 \fn void QBarSet::penChanged()
221 This signal is emitted when the pen used to draw the bar set changes.
222 \sa pen
223*/
224
225/*!
226 \fn void QBarSet::brushChanged()
227 This signal is emitted when the brush used to draw the bar set changes.
228 \sa brush
229*/
230
231/*!
232 \fn void QBarSet::labelBrushChanged()
233 This signal is emitted when the brush used to draw the bar set's label changes.
234 \sa labelBrush
235*/
236
237/*!
238 \fn void QBarSet::labelFontChanged()
239 This signal is emitted when the font of the bar set's label changes.
240 \sa labelBrush
241*/
242
243/*!
244 \fn void QBarSet::colorChanged(QColor)
245 This signal is emitted when the fill (brush) color of the bar set changes to \a color.
246*/
247
248/*!
249 \fn void QBarSet::borderColorChanged(QColor)
250 This signal is emitted when the line (pen) color of the bar set changes to \a color.
251*/
252
253/*!
254 \fn void QBarSet::labelColorChanged(QColor)
255 This signal is emitted when the text (label) color of the bar set changes to \a color.
256*/
257
258/*!
259 \fn void QBarSet::valuesAdded(int index, int count)
260 This signal is emitted when new values are added to the bar set.
261 \a index indicates the position of the first inserted value, and \a count is the number
262 of inserted values.
263 \sa append(), insert()
264*/
265/*!
266 \qmlsignal BarSet::valuesAdded(int index, int count)
267 This signal is emitted when new values are added to the bar set.
268 \a index indicates the position of the first inserted value, and \a count is the number
269 of inserted values.
270
271 The corresponding signal handler is \c onValuesAdded.
272*/
273
274/*!
275 \fn void QBarSet::valuesRemoved(int index, int count)
276 This signal is emitted when values are removed from the bar set.
277 \a index indicates the position of the first removed value, and \a count is the number
278 of removed values.
279 \sa remove()
280*/
281/*!
282 \qmlsignal BarSet::valuesRemoved(int index, int count)
283 This signal is emitted when values are removed from the bar set.
284 \a index indicates the position of the first removed value, and \a count is the number
285 of removed values.
286
287 The corresponding signal handler is \c onValuesRemoved.
288*/
289
290/*!
291 \fn void QBarSet::valueChanged(int index)
292 This signal is emitted when the value at the position specified by \a index is modified.
293 \sa at()
294*/
295/*!
296 \qmlsignal BarSet::valueChanged(int index)
297 This signal is emitted when the value at the position specified by \a index is modified.
298
299 The corresponding signal handler is \c onValueChanged.
300*/
301
302/*!
303 \qmlproperty int BarSet::count
304 The number of values in the bar set.
305*/
306
307/*!
308 \qmlproperty QVariantList BarSet::values
309 The values of the bar set. You can set a list of either \l [QML]{real} or \l [QML]{point}
310 types as values.
311
312 If you set a list of real types as values, they directly define the bar set values.
313
314 If you set a list of point types as values, the x-coordinate of the point specifies its
315 zero-based index in the bar set. The size of the bar set is the highest x-coordinate value + 1.
316 If a point is missing for any x-coordinate between zero and the highest value,
317 it gets the value zero.
318
319 For example, the following bar sets have equal values:
320 \code
321 myBarSet1.values = [5, 0, 1, 5];
322 myBarSet2.values = [Qt.point(0, 5), Qt.point(2, 1), Qt.point(3, 5)];
323 \endcode
324*/
325
326/*!
327 Constructs a bar set with the label \a label and the parent \a parent.
328*/
329QBarSet::QBarSet(const QString label, QObject *parent)
330 : QObject(parent),
331 d_ptr(new QBarSetPrivate(label, this))
332{
333}
334
335/*!
336 Removes the bar set.
337*/
338QBarSet::~QBarSet()
339{
340 // NOTE: d_ptr destroyed by QObject
341}
342
343/*!
344 Sets \a label as the new label for the bar set.
345*/
346void QBarSet::setLabel(const QString label)
347{
348 d_ptr->m_label = label;
349 d_ptr->setLabelsDirty(true);
350 emit labelChanged();
351}
352
353/*!
354 Returns the label of the bar set.
355*/
356QString QBarSet::label() const
357{
358 return d_ptr->m_label;
359}
360
361/*!
362 \qmlmethod BarSet::append(real value)
363 Appends the new value specified by \a value to the end of the bar set.
364*/
365
366/*!
367 Appends the new value specified by \a value to the end of the bar set.
368*/
369void QBarSet::append(const qreal value)
370{
371 // Convert to QPointF
372 int index = d_ptr->m_values.count();
373 d_ptr->append(value: QPointF(d_ptr->m_values.count(), value));
374 emit valuesAdded(index, count: 1);
375}
376
377/*!
378 Appends the list of real values specified by \a values to the end of the bar set.
379
380 \sa append()
381*/
382void QBarSet::append(const QList<qreal> &values)
383{
384 int index = d_ptr->m_values.count();
385 d_ptr->append(values);
386 emit valuesAdded(index, count: values.count());
387}
388
389/*!
390 A convenience operator for appending the real value specified by \a value to the end of the
391 bar set.
392
393 \sa append()
394*/
395QBarSet &QBarSet::operator << (const qreal &value)
396{
397 append(value);
398 return *this;
399}
400
401/*!
402 Inserts \a value in the position specified by \a index.
403 The values following the inserted value are moved up one position.
404
405 \sa remove()
406*/
407void QBarSet::insert(const int index, const qreal value)
408{
409 d_ptr->insert(index, value);
410 emit valuesAdded(index, count: 1);
411}
412
413/*!
414 \qmlmethod BarSet::remove(int index, int count)
415 Removes the number of values specified by \a count from the bar set starting
416 with the value specified by \a index.
417
418 If you leave out \a count, only the value specified by \a index is removed.
419*/
420
421/*!
422 Removes the number of values specified by \a count from the bar set starting with
423 the value specified by \a index.
424 \sa insert()
425*/
426void QBarSet::remove(const int index, const int count)
427{
428 int removedCount = d_ptr->remove(index, count);
429 if (removedCount > 0)
430 emit valuesRemoved(index, count: removedCount);
431 return;
432}
433
434/*!
435 \qmlmethod BarSet::replace(int index, real value)
436 Adds the value specified by \a value to the bar set at the position
437 specified by \a index.
438*/
439
440/*!
441 Adds the value specified by \a value to the bar set at the position specified by \a index.
442*/
443void QBarSet::replace(const int index, const qreal value)
444{
445 if (index >= 0 && index < d_ptr->m_values.count()) {
446 d_ptr->replace(index, value);
447 emit valueChanged(index);
448 }
449}
450
451/*!
452 \qmlmethod BarSet::at(int index)
453 Returns the value specified by \a index from the bar set.
454 If the index is out of bounds, 0.0 is returned.
455*/
456
457/*!
458 Returns the value specified by \a index from the bar set.
459 If the index is out of bounds, 0.0 is returned.
460*/
461qreal QBarSet::at(const int index) const
462{
463 if (index < 0 || index >= d_ptr->m_values.count())
464 return 0;
465 return d_ptr->m_values.at(i: index).y();
466}
467
468/*!
469 Returns the value of the bar set specified by \a index.
470 If the index is out of bounds, 0.0 is returned.
471*/
472qreal QBarSet::operator [](const int index) const
473{
474 return at(index);
475}
476
477/*!
478 Returns the number of values in a bar set.
479*/
480int QBarSet::count() const
481{
482 return d_ptr->m_values.count();
483}
484
485/*!
486 Returns the sum of all values in the bar set.
487*/
488qreal QBarSet::sum() const
489{
490 qreal total(0);
491 for (int i = 0; i < d_ptr->m_values.count(); i++)
492 total += d_ptr->m_values.at(i).y();
493 return total;
494}
495
496/*!
497 Sets the pen used to draw the lines in the bar set to \a pen.
498*/
499void QBarSet::setPen(const QPen &pen)
500{
501 if (d_ptr->m_pen != pen) {
502 d_ptr->m_pen = pen;
503 d_ptr->setVisualsDirty(true);
504 emit d_ptr->updatedBars();
505 emit penChanged();
506 }
507}
508
509/*!
510 Returns the pen used to draw the lines in the bar set.
511*/
512QPen QBarSet::pen() const
513{
514 if (d_ptr->m_pen == QChartPrivate::defaultPen())
515 return QPen();
516 else
517 return d_ptr->m_pen;
518}
519
520/*!
521 Sets the brush used to fill the bars in the bar set to \a brush.
522*/
523void QBarSet::setBrush(const QBrush &brush)
524{
525 if (d_ptr->m_brush != brush) {
526 d_ptr->m_brush = brush;
527 d_ptr->setVisualsDirty(true);
528 emit d_ptr->updatedBars();
529 emit brushChanged();
530 }
531}
532
533/*!
534 Returns the brush used to fill the bars in the bar set.
535*/
536QBrush QBarSet::brush() const
537{
538 if (d_ptr->m_brush == QChartPrivate::defaultBrush())
539 return QBrush();
540 else
541 return d_ptr->m_brush;
542}
543
544/*!
545 Sets the brush used to draw values on top of this bar set to \a brush.
546*/
547void QBarSet::setLabelBrush(const QBrush &brush)
548{
549 if (d_ptr->m_labelBrush != brush) {
550 d_ptr->m_labelBrush = brush;
551 d_ptr->setLabelsDirty(true);
552 emit d_ptr->updatedBars();
553 emit labelBrushChanged();
554 }
555}
556
557/*!
558 Returns the brush used to draw values on top of this bar set.
559*/
560QBrush QBarSet::labelBrush() const
561{
562 if (d_ptr->m_labelBrush == QChartPrivate::defaultBrush())
563 return QBrush();
564 else
565 return d_ptr->m_labelBrush;
566}
567
568/*!
569 Sets the font used to draw values on top of this bar set to \a font.
570*/
571void QBarSet::setLabelFont(const QFont &font)
572{
573 if (d_ptr->m_labelFont != font) {
574 d_ptr->m_labelFont = font;
575 d_ptr->setLabelsDirty(true);
576 emit d_ptr->updatedBars();
577 emit labelFontChanged();
578 }
579}
580
581/*!
582 Returns the pen used to draw values on top of this bar set.
583*/
584QFont QBarSet::labelFont() const
585{
586 return d_ptr->m_labelFont;
587}
588
589/*!
590 Returns the fill color for the bar set.
591*/
592QColor QBarSet::color()
593{
594 return brush().color();
595}
596
597/*!
598 Sets the fill color for the bar set to \a color.
599*/
600void QBarSet::setColor(QColor color)
601{
602 QBrush b = brush();
603 if ((b.color() != color) || (b.style() == Qt::NoBrush)) {
604 b.setColor(color);
605 if (b.style() == Qt::NoBrush) {
606 // Set tyle to Qt::SolidPattern. (Default is Qt::NoBrush)
607 // This prevents theme to override color defined in QML side:
608 // BarSet { label: "Bob"; color:"red"; values: [1,2,3] }
609 // The color must be obeyed, since user wanted it.
610 b.setStyle(Qt::SolidPattern);
611 }
612 setBrush(b);
613 emit colorChanged(color);
614 }
615}
616
617/*!
618 Returns the line color for the bar set.
619*/
620QColor QBarSet::borderColor()
621{
622 return pen().color();
623}
624
625/*!
626 Sets the line color for the bar set to \a color.
627*/
628void QBarSet::setBorderColor(QColor color)
629{
630 QPen p = pen();
631 if (p.color() != color) {
632 p.setColor(color);
633 setPen(p);
634 emit borderColorChanged(color);
635 }
636}
637
638/*!
639 Returns the text color for the bar set.
640*/
641QColor QBarSet::labelColor()
642{
643 return labelBrush().color();
644}
645
646/*!
647 Sets the text color for the bar set to \a color.
648*/
649void QBarSet::setLabelColor(QColor color)
650{
651 QBrush b = labelBrush();
652 if (b == QBrush())
653 b.setStyle(Qt::SolidPattern);
654
655 if (d_ptr->m_labelBrush.color() != color) {
656 b.setColor(color);
657 setLabelBrush(b);
658 emit labelColorChanged(color);
659 }
660}
661
662////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
663
664QBarSetPrivate::QBarSetPrivate(const QString label, QBarSet *parent) : QObject(parent),
665 q_ptr(parent),
666 m_label(label),
667 m_pen(QChartPrivate::defaultPen()),
668 m_brush(QChartPrivate::defaultBrush()),
669 m_labelBrush(QChartPrivate::defaultBrush()),
670 m_visualsDirty(true)
671{
672}
673
674QBarSetPrivate::~QBarSetPrivate()
675{
676}
677
678void QBarSetPrivate::append(QPointF value)
679{
680 if (isValidValue(point: value)) {
681 m_values.append(t: value);
682 emit valueAdded(index: m_values.size() - 1, count: 1);
683 }
684}
685
686void QBarSetPrivate::append(QList<QPointF> values)
687{
688 int originalIndex = m_values.count();
689 for (int i = 0; i < values.count(); i++) {
690 if (isValidValue(point: values.at(i)))
691 m_values.append(t: values.at(i));
692 }
693 emit valueAdded(index: originalIndex, count: values.size());
694}
695
696void QBarSetPrivate::append(QList<qreal> values)
697{
698 int originalIndex = m_values.count();
699 int index = originalIndex;
700 for (int i = 0; i < values.count(); i++) {
701 if (isValidValue(value: values.at(i))) {
702 m_values.append(t: QPointF(index, values.at(i)));
703 index++;
704 }
705 }
706 emit valueAdded(index: originalIndex, count: values.size());
707}
708
709void QBarSetPrivate::insert(const int index, const qreal value)
710{
711 m_values.insert(i: index, t: QPointF(index, value));
712 emit valueAdded(index, count: 1);
713}
714
715void QBarSetPrivate::insert(const int index, const QPointF value)
716{
717 m_values.insert(i: index, t: value);
718 emit valueAdded(index, count: 1);
719}
720
721int QBarSetPrivate::remove(const int index, const int count)
722{
723 int removeCount = count;
724
725 if ((index < 0) || (m_values.count() == 0))
726 return 0; // Invalid index or not values in list, remove nothing.
727 else if ((index + count) > m_values.count())
728 removeCount = m_values.count() - index; // Trying to remove more items than list has. Limit amount to be removed.
729
730 int c = 0;
731 while (c < removeCount) {
732 m_values.removeAt(i: index);
733 c++;
734 }
735 emit valueRemoved(index, count: removeCount);
736 return removeCount;
737}
738
739void QBarSetPrivate::replace(const int index, const qreal value)
740{
741 m_values.replace(i: index, t: QPointF(index, value));
742 emit valueChanged(index);
743}
744
745qreal QBarSetPrivate::pos(const int index)
746{
747 if (index < 0 || index >= m_values.count())
748 return 0;
749 return m_values.at(i: index).x();
750}
751
752qreal QBarSetPrivate::value(const int index)
753{
754 if (index < 0 || index >= m_values.count())
755 return 0;
756 return m_values.at(i: index).y();
757}
758
759QT_CHARTS_END_NAMESPACE
760
761#include "moc_qbarset.cpp"
762#include "moc_qbarset_p.cpp"
763

source code of qtcharts/src/charts/barchart/qbarset.cpp