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

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 PieChart : public Chart
0049 {
0050     Q_OBJECT
0051 
0052     /**
0053      * The range of values to display in this PieChart.
0054      *
0055      * When set to "automatic", the values will be divided across the entire
0056      * chart.
0057      *
0058      * \sa RangeGroup
0059      */
0060     Q_PROPERTY(RangeGroup *range READ range CONSTANT)
0061     /**
0062      * Whether to use a filled pie or not.
0063      *
0064      * If true, the last pie rendered will be rendered as a filled circle.
0065      * The default is false.
0066      */
0067     Q_PROPERTY(bool filled READ filled WRITE setFilled NOTIFY filledChanged)
0068     /**
0069      * The thickness of an individual pie, in pixels.
0070      *
0071      * If filled is set, this is ignored for the last pie. The default is 10px.
0072      */
0073     Q_PROPERTY(qreal thickness READ thickness WRITE setThickness NOTIFY thicknessChanged)
0074     /**
0075      * The amount of spacing between pies when rendering multiple value sources.
0076      *
0077      * The default is 0.
0078      */
0079     Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
0080     /**
0081      * Sets a colour to use to fill remaining space on the pie.
0082      *
0083      * The default is transparent.
0084      */
0085     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
0086     /**
0087      * The starting angle of the arc used for the entire pie.
0088      *
0089      * When set, instead of rendering a full circle, the pie will be rendered as
0090      * an arc. The default is 0.
0091      */
0092     Q_PROPERTY(qreal fromAngle READ fromAngle WRITE setFromAngle NOTIFY fromAngleChanged)
0093     /**
0094      * The end angle of the arc used for the entire pie. When set, instead of
0095      * rendering a full circle, the pie will be rendered as an arc. The default
0096      * is 360.
0097      */
0098     Q_PROPERTY(qreal toAngle READ toAngle WRITE setToAngle NOTIFY toAngleChanged)
0099     /**
0100      * Smooth the ends of pie sections.
0101      *
0102      * When true, this will try to smooth the ends of sections. This works best
0103      * when [filled] is false. The default is false.
0104      *
0105      * [filled]: \ref PieChart::filled
0106      */
0107     Q_PROPERTY(bool smoothEnds READ smoothEnds WRITE setSmoothEnds NOTIFY smoothEndsChanged)
0108 
0109 public:
0110     explicit PieChart(QQuickItem *parent = nullptr);
0111 
0112     RangeGroup *range() const;
0113 
0114     bool filled() const;
0115     void setFilled(bool newFilled);
0116     Q_SIGNAL void filledChanged();
0117 
0118     qreal thickness() const;
0119     void setThickness(qreal newThickness);
0120     Q_SIGNAL void thicknessChanged();
0121 
0122     qreal spacing() const;
0123     void setSpacing(qreal newSpacing);
0124     Q_SIGNAL void spacingChanged();
0125 
0126     QColor backgroundColor() const;
0127     void setBackgroundColor(const QColor &color);
0128     Q_SIGNAL void backgroundColorChanged();
0129 
0130     qreal fromAngle() const;
0131     void setFromAngle(qreal newFromAngle);
0132     Q_SIGNAL void fromAngleChanged();
0133 
0134     qreal toAngle() const;
0135     void setToAngle(qreal newToAngle);
0136     Q_SIGNAL void toAngleChanged();
0137 
0138     bool smoothEnds() const;
0139     void setSmoothEnds(bool newSmoothEnds);
0140     Q_SIGNAL void smoothEndsChanged();
0141 
0142 protected:
0143     /**
0144      * Reimplemented from QQuickItem.
0145      */
0146     QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override;
0147     /**
0148      * Reimplemented from Chart.
0149      */
0150     void onDataChanged() override;
0151 
0152 private:
0153     std::unique_ptr<RangeGroup> m_range;
0154     bool m_filled = false;
0155     qreal m_thickness = 10.0;
0156     qreal m_spacing = 0.0;
0157     QColor m_backgroundColor = Qt::transparent;
0158     qreal m_fromAngle = 0.0;
0159     qreal m_toAngle = 360.0;
0160     bool m_smoothEnds = false;
0161 
0162     QVector<QVector<qreal>> m_sections;
0163     QVector<QVector<QColor>> m_colors;
0164 };
0165 
0166 #endif // PIECHART_H