1/*
2 * This file is part of KQuickCharts
3 * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8#ifndef LINECHART_H
9#define LINECHART_H
10
11#include <memory>
12
13#include <qqmlregistration.h>
14
15#include "XYChart.h"
16
17class LineChartNode;
18
19/*
20 * An attached property that is exposed to point delegates created in line charts.
21 */
22class LineChartAttached : public QObject
23{
24 Q_OBJECT
25 QML_ANONYMOUS
26
27public:
28 LineChartAttached(QObject *parent = nullptr);
29
30 /*!
31 * \qmlattachedproperty var LineChart::value
32 * The value at the current point.
33 */
34 Q_PROPERTY(QVariant value READ value NOTIFY valueChanged)
35 QVariant value() const;
36 void setValue(const QVariant &value);
37 Q_SIGNAL void valueChanged();
38
39 /*!
40 * \qmlattachedproperty color LineChart::color
41 * The color at the current point.
42 */
43 Q_PROPERTY(QColor color READ color NOTIFY colorChanged)
44 QColor color() const;
45 void setColor(const QColor &color);
46 Q_SIGNAL void colorChanged();
47
48 /*!
49 * \qmlattachedproperty string LineChart::name
50 * The name at the current point.
51 */
52 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
53 QString name() const;
54 void setName(const QString &newName);
55 Q_SIGNAL void nameChanged();
56
57 /*!
58 * \qmlattachedproperty string LineChart::shortName
59 * The short name at the current point.
60 */
61 Q_PROPERTY(QString shortName READ shortName NOTIFY shortNameChanged)
62 QString shortName() const;
63 void setShortName(const QString &newShortName);
64 Q_SIGNAL void shortNameChanged();
65
66private:
67 QVariant m_value;
68 QColor m_color;
69 QString m_name;
70 QString m_shortName;
71};
72
73/*!
74 * \qmltype LineChart
75 * \inherits XYChart
76 * \inqmlmodule org.kde.quickcharts
77 *
78 * \brief A line chart.
79 *
80 * \section1 Usage example
81 *
82 * \snippet linechart.qml example
83 *
84 * \image linechart.png The resulting line chart.
85 */
86class QUICKCHARTS_EXPORT LineChart : public XYChart
87{
88 Q_OBJECT
89 QML_ELEMENT
90 QML_ATTACHED(LineChartAttached)
91
92public:
93 explicit LineChart(QQuickItem *parent = nullptr);
94
95 /*!
96 * \qmlproperty bool LineChart::interpolate
97 * Interpolate the values in the chart so that the lines become smoothed.
98 */
99 Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate NOTIFY interpolateChanged)
100 bool interpolate() const;
101 void setInterpolate(bool newInterpolate);
102 Q_SIGNAL void interpolateChanged();
103 /*!
104 * \qmlproperty real LineChart::lineWidth
105 * The width of a line in the chart.
106 */
107 Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged)
108 qreal lineWidth() const;
109 void setLineWidth(qreal width);
110 Q_SIGNAL void lineWidthChanged();
111 /*!
112 * \qmlproperty real LineChart::fillOpacity
113 * \brief The opacity of the area below a line.
114 *
115 * The default is 0.0. Note that if fillColorSource is set, this value is
116 * ignored.
117 */
118 Q_PROPERTY(qreal fillOpacity READ fillOpacity WRITE setFillOpacity NOTIFY fillOpacityChanged)
119 qreal fillOpacity() const;
120 void setFillOpacity(qreal opacity);
121 Q_SIGNAL void fillOpacityChanged();
122 /*!
123 * \qmlproperty ChartDataSource LineChart::fillColorSource
124 * \brief A data source that supplies color values for the line charts' fill area.
125 *
126 * If this is not set (the default), the normal color source will be used,
127 * with the fillOpacity used as its opacity.
128 */
129 Q_PROPERTY(ChartDataSource *fillColorSource READ fillColorSource WRITE setFillColorSource NOTIFY fillColorSourceChanged)
130 ChartDataSource *fillColorSource() const;
131 void setFillColorSource(ChartDataSource *newFillColorSource);
132 Q_SIGNAL void fillColorSourceChanged();
133 /*!
134 * \qmlproperty Component LineChart::pointDelegate
135 * \brief A delegate that will be placed at each line chart point.
136 *
137 * When this is not null, the specified component will be used to
138 * instantiate an object for each point in the chart. These objects will
139 * then be placed centered at positions corresponding to the points on the
140 * chart. Each instance will have access to the attached properties of
141 * LineChartAttached through LineChart attached object.
142 *
143 * \note The component assigned to this property is expected to create a
144 * QQuickItem, since the created object needs to be positioned.
145 */
146 Q_PROPERTY(QQmlComponent *pointDelegate READ pointDelegate WRITE setPointDelegate NOTIFY pointDelegateChanged)
147 QQmlComponent *pointDelegate() const;
148 void setPointDelegate(QQmlComponent *newPointDelegate);
149 Q_SIGNAL void pointDelegateChanged();
150
151 static LineChartAttached *qmlAttachedProperties(QObject *object)
152 {
153 return new LineChartAttached(object);
154 }
155
156protected:
157 void updatePolish() override;
158 QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data) override;
159 void onDataChanged() override;
160 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
161
162private:
163 void updateLineNode(LineChartNode *node, ChartDataSource *valueSource, const QColor &lineColor, const QColor &fillColor, qreal lineWidth);
164 void createPointDelegates(const QList<QVector2D> &values, int sourceIndex);
165 void updatePointDelegate(QQuickItem *delegate, const QVector2D &position, const QVariant &value, int sourceIndex);
166
167 bool m_interpolate = false;
168 qreal m_lineWidth = 1.0;
169 qreal m_fillOpacity = 0.0;
170 bool m_rangeInvalid = true;
171 ChartDataSource *m_fillColorSource = nullptr;
172 QHash<ChartDataSource *, QList<QVector2D>> m_values;
173 QQmlComponent *m_pointDelegate = nullptr;
174 QHash<ChartDataSource *, QList<QQuickItem *>> m_pointDelegates;
175};
176
177#endif // LINECHART_H
178

source code of kquickcharts/src/LineChart.h