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 LINECHART_H
0009 #define LINECHART_H
0010 
0011 #include <memory>
0012 
0013 #include <qqmlregistration.h>
0014 
0015 #include "XYChart.h"
0016 
0017 class LineChartNode;
0018 
0019 /**
0020  * An attached property that is exposed to point delegates created in line charts.
0021  *
0022  * \sa LineChart::pointDelegate
0023  */
0024 class LineChartAttached : public QObject
0025 {
0026     Q_OBJECT
0027     QML_ANONYMOUS
0028 
0029 public:
0030     LineChartAttached(QObject *parent = nullptr);
0031 
0032     /**
0033      * The value at the current point.
0034      */
0035     Q_PROPERTY(QVariant value READ value NOTIFY valueChanged)
0036     QVariant value() const;
0037     void setValue(const QVariant &value);
0038     Q_SIGNAL void valueChanged();
0039 
0040     /**
0041      * The color at the current point.
0042      */
0043     Q_PROPERTY(QColor color READ color NOTIFY colorChanged)
0044     QColor color() const;
0045     void setColor(const QColor &color);
0046     Q_SIGNAL void colorChanged();
0047 
0048     /**
0049      * The name at the current point.
0050      */
0051     Q_PROPERTY(QString name READ name NOTIFY nameChanged)
0052     QString name() const;
0053     void setName(const QString &newName);
0054     Q_SIGNAL void nameChanged();
0055 
0056     /**
0057      * The short name at the current point.
0058      */
0059     Q_PROPERTY(QString shortName READ shortName NOTIFY shortNameChanged)
0060     QString shortName() const;
0061     void setShortName(const QString &newShortName);
0062     Q_SIGNAL void shortNameChanged();
0063 
0064 private:
0065     QVariant m_value;
0066     QColor m_color;
0067     QString m_name;
0068     QString m_shortName;
0069 };
0070 
0071 /**
0072  * A line chart.
0073  *
0074  * ## Usage example
0075  *
0076  * \snippet snippets/linechart.qml example
0077  *
0078  * \image html linechart.png "The resulting line chart."
0079  */
0080 class QUICKCHARTS_EXPORT LineChart : public XYChart
0081 {
0082     Q_OBJECT
0083     QML_ELEMENT
0084     QML_ATTACHED(LineChartAttached)
0085 
0086 public:
0087     explicit LineChart(QQuickItem *parent = nullptr);
0088 
0089     /**
0090      * Interpolate the values in the chart so that the lines become smoothed.
0091      */
0092     Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate NOTIFY interpolateChanged)
0093     bool interpolate() const;
0094     void setInterpolate(bool newInterpolate);
0095     Q_SIGNAL void interpolateChanged();
0096     /**
0097      * The width of a line in the chart.
0098      */
0099     Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged)
0100     qreal lineWidth() const;
0101     void setLineWidth(qreal width);
0102     Q_SIGNAL void lineWidthChanged();
0103     /**
0104      * The opacity of the area below a line.
0105      *
0106      * The default is 0.0. Note that if fillColorSource is set, this value is
0107      * ignored.
0108      */
0109     Q_PROPERTY(qreal fillOpacity READ fillOpacity WRITE setFillOpacity NOTIFY fillOpacityChanged)
0110     qreal fillOpacity() const;
0111     void setFillOpacity(qreal opacity);
0112     Q_SIGNAL void fillOpacityChanged();
0113     /**
0114      * A data source that supplies color values for the line charts' fill area.
0115      *
0116      * If this is not set (the default), the normal color source will be used,
0117      * with the fillOpacity used as its opacity.
0118      */
0119     Q_PROPERTY(ChartDataSource *fillColorSource READ fillColorSource WRITE setFillColorSource NOTIFY fillColorSourceChanged)
0120     ChartDataSource *fillColorSource() const;
0121     void setFillColorSource(ChartDataSource *newFillColorSource);
0122     Q_SIGNAL void fillColorSourceChanged();
0123     /**
0124      * A delegate that will be placed at each line chart point.
0125      *
0126      * When this is not null, the specified component will be used to
0127      * instantiate an object for each point in the chart. These objects will
0128      * then be placed centered at positions corresponding to the points on the
0129      * chart. Each instance will have access to the attached properties of
0130      * LineChartAttached through LineChart attached object.
0131      *
0132      * \note The component assigned to this property is expected to create a
0133      *       QQuickItem, since the created object needs to be positioned.
0134      */
0135     Q_PROPERTY(QQmlComponent *pointDelegate READ pointDelegate WRITE setPointDelegate NOTIFY pointDelegateChanged)
0136     QQmlComponent *pointDelegate() const;
0137     void setPointDelegate(QQmlComponent *newPointDelegate);
0138     Q_SIGNAL void pointDelegateChanged();
0139 
0140     static LineChartAttached *qmlAttachedProperties(QObject *object)
0141     {
0142         return new LineChartAttached(object);
0143     }
0144 
0145 protected:
0146     void updatePolish() override;
0147     QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data) override;
0148     void onDataChanged() override;
0149     void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
0150 
0151 private:
0152     void updateLineNode(LineChartNode *node, const QColor &lineColor, const QColor &fillColor, ChartDataSource *valueSource);
0153     void createPointDelegates(const QList<QVector2D> &values, int sourceIndex);
0154     void updatePointDelegate(QQuickItem *delegate, const QVector2D &position, const QVariant &value, int sourceIndex);
0155 
0156     bool m_interpolate = false;
0157     qreal m_lineWidth = 1.0;
0158     qreal m_fillOpacity = 0.0;
0159     bool m_rangeInvalid = true;
0160     ChartDataSource *m_fillColorSource = nullptr;
0161     QHash<ChartDataSource *, QList<QVector2D>> m_values;
0162     QQmlComponent *m_pointDelegate = nullptr;
0163     QHash<ChartDataSource *, QList<QQuickItem *>> m_pointDelegates;
0164 };
0165 
0166 #endif // LINECHART_H