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