File indexing completed on 2024-10-06 03:40:53

0001 /*
0002  * This file is part of KQuickCharts
0003  * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006  */
0007 
0008 #ifndef PIECHART_H
0009 #define PIECHART_H
0010 
0011 #include <memory>
0012 
0013 #include "Chart.h"
0014 #include "RangeGroup.h"
0015 
0016 /**
0017  * An item to render a pie chart.
0018  *
0019  * This item will render a Pie chart based on the [valueSources] supplied to it.
0020  * By default it will set [indexingMode] to [IndexSourceValues], meaning that it
0021  * will use the individual values of the valueSources to render sections of the
0022  * chart.
0023  *
0024  * [valueSources]: \ref Chart::valueSources
0025  * [indexingMode]: \ref Chart::indexingMode
0026  * [IndexSourceValues]: \ref Chart::IndexingMode
0027  *
0028  * ### Usage example
0029  *
0030  * \snippet snippets/piechart.qml example
0031  *
0032  * \image html piechart.png "The resulting pie chart."
0033  *
0034  * ### Multiple Value Sources
0035  *
0036  * Multiple valueSources are rendered as consecutive pie charts in the same
0037  * item. The first valueSource will become the outermost circle and consecutive
0038  * valueSources will be rendered as continuously smaller circles. When rendering
0039  * multiple value sources, [filled] will only affect the last value source. All
0040  * other value sources will be rendered according to [thickness], with [spacing]
0041  * amount of space between them.
0042  *
0043  * [filled]: \ref PieChart::filled
0044  * [thickness]: \ref PieChart::thickness
0045  * [spacing]: \ref PieChart::spacing
0046  *
0047  */
0048 class QUICKCHARTS_EXPORT PieChart : public Chart
0049 {
0050     Q_OBJECT
0051     QML_ELEMENT
0052 
0053 public:
0054     explicit PieChart(QQuickItem *parent = nullptr);
0055 
0056     /**
0057      * The range of values to display in this PieChart.
0058      *
0059      * When set to "automatic", the values will be divided across the entire
0060      * chart.
0061      *
0062      * \sa RangeGroup
0063      */
0064     Q_PROPERTY(RangeGroup *range READ range CONSTANT)
0065     RangeGroup *range() const;
0066     /**
0067      * Whether to use a filled pie or not.
0068      *
0069      * If true, the last pie rendered will be rendered as a filled circle.
0070      * The default is false.
0071      */
0072     Q_PROPERTY(bool filled READ filled WRITE setFilled NOTIFY filledChanged)
0073     bool filled() const;
0074     void setFilled(bool newFilled);
0075     Q_SIGNAL void filledChanged();
0076     /**
0077      * The thickness of an individual pie, in pixels.
0078      *
0079      * If filled is set, this is ignored for the last pie. The default is 10px.
0080      */
0081     Q_PROPERTY(qreal thickness READ thickness WRITE setThickness NOTIFY thicknessChanged)
0082     qreal thickness() const;
0083     void setThickness(qreal newThickness);
0084     Q_SIGNAL void thicknessChanged();
0085     /**
0086      * The amount of spacing between pies when rendering multiple value sources.
0087      *
0088      * The default is 0.
0089      */
0090     Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
0091     qreal spacing() const;
0092     void setSpacing(qreal newSpacing);
0093     Q_SIGNAL void spacingChanged();
0094     /**
0095      * Sets a colour to use to fill remaining space on the pie.
0096      *
0097      * The default is transparent.
0098      */
0099     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
0100     QColor backgroundColor() const;
0101     void setBackgroundColor(const QColor &color);
0102     Q_SIGNAL void backgroundColorChanged();
0103     /**
0104      * The starting angle of the arc used for the entire pie.
0105      *
0106      * When set, instead of rendering a full circle, the pie will be rendered as
0107      * an arc. The default is 0.
0108      */
0109     Q_PROPERTY(qreal fromAngle READ fromAngle WRITE setFromAngle NOTIFY fromAngleChanged)
0110     qreal fromAngle() const;
0111     void setFromAngle(qreal newFromAngle);
0112     Q_SIGNAL void fromAngleChanged();
0113     /**
0114      * The end angle of the arc used for the entire pie. When set, instead of
0115      * rendering a full circle, the pie will be rendered as an arc. The default
0116      * is 360.
0117      */
0118     Q_PROPERTY(qreal toAngle READ toAngle WRITE setToAngle NOTIFY toAngleChanged)
0119     qreal toAngle() const;
0120     void setToAngle(qreal newToAngle);
0121     Q_SIGNAL void toAngleChanged();
0122     /**
0123      * Smooth the ends of pie sections.
0124      *
0125      * When true, this will try to smooth the ends of sections. This works best
0126      * when [filled] is false. The default is false.
0127      *
0128      * [filled]: \ref PieChart::filled
0129      */
0130     Q_PROPERTY(bool smoothEnds READ smoothEnds WRITE setSmoothEnds NOTIFY smoothEndsChanged)
0131     bool smoothEnds() const;
0132     void setSmoothEnds(bool newSmoothEnds);
0133     Q_SIGNAL void smoothEndsChanged();
0134 
0135 protected:
0136     /**
0137      * Reimplemented from QQuickItem.
0138      */
0139     QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override;
0140     /**
0141      * Reimplemented from Chart.
0142      */
0143     void onDataChanged() override;
0144 
0145 private:
0146     std::unique_ptr<RangeGroup> m_range;
0147     bool m_filled = false;
0148     qreal m_thickness = 10.0;
0149     qreal m_spacing = 0.0;
0150     QColor m_backgroundColor = Qt::transparent;
0151     qreal m_fromAngle = 0.0;
0152     qreal m_toAngle = 360.0;
0153     bool m_smoothEnds = false;
0154 
0155     QList<QList<qreal>> m_sections;
0156     QList<QList<QColor>> m_colors;
0157 };
0158 
0159 #endif // PIECHART_H