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 HISTORYPROXYSOURCE_H
9#define HISTORYPROXYSOURCE_H
10
11#include <QList>
12#include <QTimer>
13#include <QVariant>
14#include <memory>
15
16#include "ChartDataSource.h"
17
18/*!
19 * \qmltype HistoryProxySource
20 * \inherits ChartDataSource
21 * \inqmlmodule org.kde.quickcharts
22 *
23 * \brief A data source that provides a history of a single item of a different data source.
24 *
25 * This data source will monitor a single item of another data source for changes
26 * and record them, exposing historical values as
27 */
28class QUICKCHARTS_EXPORT HistoryProxySource : public ChartDataSource
29{
30 Q_OBJECT
31 QML_ELEMENT
32
33public:
34 /*!
35 * \enum HistoryProxySource::FillMode
36 *
37 * The different fill modes.
38 *
39 * These determine the value returned by itemCount and what happens
40 * when requesting an item that does not have a value in the history.
41 *
42 * \value DoNotFill
43 * Do not fill with any items. The source's itemCount will be
44 * equal to the number of items in the history.
45 * \value FillFromStart
46 * Fill with empty values, starting at 0. The source's itemCount
47 * will be equal to \l maximumHistory. Items that do not have a value
48 * in the history will return a default-constructed value based on
49 * the first item of the source.
50 * \value FillFromEnd
51 * Fill with empty values, placing partial history at the end. This
52 * means that the first recorded history item will be shown at
53 * position \c{maximumHistory - 1}, the second at
54 * \c{maximumHistory - 2} and so on, until \l maximumHistory is
55 * reached, after which items will be discarded normally.
56 */
57 enum FillMode {
58 DoNotFill,
59 FillFromStart,
60 FillFromEnd
61 };
62 Q_ENUM(FillMode)
63
64 explicit HistoryProxySource(QObject *parent = nullptr);
65
66 /*!
67 * \qmlproperty ChartDataSource HistoryProxySource::source
68 * \brief The data source to read data from.
69 *
70 * This will use the item at \l item from the provided source and use that
71 * to fill the history of this source.
72 *
73 * \note Changing this property will clear the existing history.
74 */
75 Q_PROPERTY(ChartDataSource *source READ source WRITE setSource NOTIFY sourceChanged)
76 ChartDataSource *source() const;
77 void setSource(ChartDataSource *newSource);
78 Q_SIGNAL void sourceChanged();
79 /*!
80 * \qmlproperty int HistoryProxySource::item
81 * \brief The item of the data source to read data from.
82 *
83 * This item will be read either when the source's dataChanged has been
84 * emitted or on an interval if \l interval has been set.
85 *
86 * The default is 0.
87 *
88 * \note Changing this property will clear the existing history.
89 */
90 Q_PROPERTY(int item READ item WRITE setItem NOTIFY itemChanged)
91 int item() const;
92 void setItem(int newItem);
93 Q_SIGNAL void itemChanged();
94 /*!
95 * \qmlproperty int HistoryProxySource::maximumHistory
96 * \brief The maximum amount of history to keep.
97 *
98 * The default is 10.
99 */
100 Q_PROPERTY(int maximumHistory READ maximumHistory WRITE setMaximumHistory NOTIFY maximumHistoryChanged)
101 int maximumHistory() const;
102 void setMaximumHistory(int maximumHistory);
103 Q_SIGNAL void maximumHistoryChanged();
104 /*!
105 * \qmlproperty int HistoryProxySource::interval
106 * \brief The interval, in milliseconds, with which to query the data source.
107 *
108 * If set to a value <= 0, a new item will be added whenever \l source
109 * changes. Otherwise, source will be sampled every interval milliseconds
110 * and a new item will be added with whatever value it has at that point,
111 * even if it did not change.
112 *
113 * The default is 0.
114 */
115 Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged)
116 int interval() const;
117 void setInterval(int newInterval);
118 Q_SIGNAL void intervalChanged();
119 /*!
120 * \qmlproperty enumeration HistoryProxySource::fillMode
121 * \qmlenumeratorsfrom HistoryProxySource::FillMode
122 * \brief The fill mode.
123 *
124 * This determines what happens when there is not enough history yet.
125 *
126 * The default is DoNotFill.
127 *
128 * \note Changing this property will clear the existing history.
129 */
130 Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
131 FillMode fillMode() const;
132 void setFillMode(FillMode newFillMode);
133 Q_SIGNAL void fillModeChanged();
134
135 /**
136 * \qmlmethod HistoryProxySource::clear
137 * \brief Clear the entire history of this source.
138 */
139 Q_INVOKABLE void clear();
140
141 int itemCount() const override;
142 QVariant item(int index) const override;
143 QVariant minimum() const override;
144 QVariant maximum() const override;
145 QVariant first() const override;
146
147private:
148 void update();
149
150 ChartDataSource *m_dataSource = nullptr;
151 int m_item = 0;
152 int m_maximumHistory = 10;
153 FillMode m_fillMode = DoNotFill;
154 std::unique_ptr<QTimer> m_updateTimer;
155 QList<QVariant> m_history;
156};
157
158#endif // HISTORYPROXYSOURCE_H
159

source code of kquickcharts/src/datasource/HistoryProxySource.h