File indexing completed on 2024-04-21 15:02:55

0001 /*
0002  * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #ifndef BARCHART_H
0008 #define BARCHART_H
0009 
0010 #include "XYChart.h"
0011 
0012 struct Bar;
0013 
0014 /**
0015  * An item to render a bar chart.
0016  *
0017  * This chart renders
0018  *
0019  * ## Usage example
0020  *
0021  * \snippet snippets/barchart.qml example
0022  *
0023  * \image html barchart.png "The resulting bar chart."
0024  */
0025 class BarChart : public XYChart
0026 {
0027     Q_OBJECT
0028 
0029 public:
0030     /**
0031      * Helper enum to provide an easy way to set barWidth to auto.
0032      */
0033     enum WidthMode { AutoWidth = -2 };
0034     Q_ENUM(WidthMode)
0035 
0036     enum Orientation {
0037         HorizontalOrientation = Qt::Horizontal, ///< Bars are oriented horizontally, with low values left and high values right.
0038         VerticalOrientation = Qt::Vertical ///< Bars are oriented vertically, with low values at the bottom and high values at the top.
0039     };
0040     Q_ENUM(Orientation)
0041 
0042     explicit BarChart(QQuickItem *parent = nullptr);
0043 
0044     /**
0045      * The spacing between bars for each value source.
0046      *
0047      * Note that spacing between each X axis value is determined automatically
0048      * based on barWidth, spacing and total chart width. The default is 0.
0049      */
0050     Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
0051     qreal spacing() const;
0052     void setSpacing(qreal newSpacing);
0053     Q_SIGNAL void spacingChanged();
0054 
0055     /**
0056      * The width of individual bars in the chart.
0057      *
0058      * If set to WidthMode::AutoWidth (also the default), the width will be
0059      * calculated automatically based on total chart width and item count.
0060      */
0061     Q_PROPERTY(qreal barWidth READ barWidth WRITE setBarWidth NOTIFY barWidthChanged)
0062     qreal barWidth() const;
0063     void setBarWidth(qreal newBarWidth);
0064     Q_SIGNAL void barWidthChanged();
0065 
0066     /**
0067      * The radius of the ends of bars in the chart in pixels.
0068      *
0069      * By default this is 0, which means no rounding will be done.
0070      */
0071     Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
0072     qreal radius() const;
0073     void setRadius(qreal newRadius);
0074     Q_SIGNAL void radiusChanged();
0075 
0076     /**
0077      * The orientation of bars in the chart.
0078      *
0079      * By default this is Vertical.
0080      */
0081     Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
0082     Orientation orientation() const;
0083     void setOrientation(Orientation newOrientation);
0084     Q_SIGNAL void orientationChanged();
0085 
0086     /**
0087      * The background color of bars in the chart.
0088      *
0089      * By default this is Qt::transparent. If set to something non-transparent,
0090      * the chart will render backgrounds for the bars. These backgrounds will
0091      * have the same width as the bars but stretch the full height.
0092      */
0093     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
0094     QColor backgroundColor() const;
0095     void setBackgroundColor(const QColor &newBackgroundColor);
0096     Q_SIGNAL void backgroundColorChanged();
0097 
0098 protected:
0099     /**
0100      * Reimplemented from QQuickItem.
0101      */
0102     QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *) override;
0103     /**
0104      * Reimplemented from Chart.
0105      */
0106     void onDataChanged() override;
0107 
0108 private:
0109     QVector<Bar> calculateBars();
0110 
0111     qreal m_spacing = 0.0;
0112     qreal m_barWidth = AutoWidth;
0113     qreal m_radius = 0.0;
0114     Orientation m_orientation = VerticalOrientation;
0115     bool m_orientationChanged = false;
0116     struct BarData {
0117         qreal value = 0;
0118         QColor color;
0119     };
0120     QVector<QVector<BarData>> m_barDataItems;
0121     QColor m_backgroundColor = Qt::transparent;
0122 };
0123 
0124 #endif // BARCHART_H