| 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 | */ |
| 28 | class QUICKCHARTS_EXPORT HistoryProxySource : public ChartDataSource |
| 29 | { |
| 30 | Q_OBJECT |
| 31 | QML_ELEMENT |
| 32 | |
| 33 | public: |
| 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 | |
| 147 | private: |
| 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 | |