File indexing completed on 2024-05-05 07:58:32

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 HISTORYPROXYSOURCE_H
0009 #define HISTORYPROXYSOURCE_H
0010 
0011 #include <QList>
0012 #include <QTimer>
0013 #include <QVariant>
0014 #include <memory>
0015 
0016 #include "ChartDataSource.h"
0017 
0018 /**
0019  * A data source that provides a history of a single item of a different data source.
0020  *
0021  * This data source will monitor a single item of another data source for changes
0022  * and record them, exposing historical values as
0023  */
0024 class QUICKCHARTS_EXPORT HistoryProxySource : public ChartDataSource
0025 {
0026     Q_OBJECT
0027     QML_ELEMENT
0028 
0029 public:
0030     /**
0031      * The different fill modes.
0032      *
0033      * These determine the value returned by \ref itemCount and what happens
0034      * when requesting an item that does not have a value in the history.
0035      */
0036     enum FillMode {
0037         /**
0038          * Do not fill with any items. The source's \ref itemCount will be equal
0039          * to the number of items in the history.
0040          */
0041         DoNotFill,
0042         /**
0043          * Fill with empty values, starting at 0. The source's \ref itemCount
0044          * will be equal to \ref maximumHistory. Items that do not have a value
0045          * in the history will return a default-constructed value based on the
0046          * first item of the source.
0047          */
0048         FillFromStart,
0049         /**
0050          * Fill with empty values, placing partial history at the end. This
0051          * means that the first recorded history item will be shown at position
0052          * `maximumHistory - 1`, the second at `maximumHistory - 2` and so on,
0053          * until \ref maximumHistory is reached, after which items will be
0054          * discarded normally.
0055          */
0056         FillFromEnd
0057     };
0058     Q_ENUM(FillMode)
0059 
0060     explicit HistoryProxySource(QObject *parent = nullptr);
0061 
0062     /**
0063      * The data source to read data from.
0064      *
0065      * This will use the item at \ref item from the provided source and use that
0066      * to fill the history of this source.
0067      *
0068      * \note Changing this property will clear the existing history.
0069      */
0070     Q_PROPERTY(ChartDataSource *source READ source WRITE setSource NOTIFY sourceChanged)
0071     ChartDataSource *source() const;
0072     void setSource(ChartDataSource *newSource);
0073     Q_SIGNAL void sourceChanged();
0074     /**
0075      * The item of the data source to read data from.
0076      *
0077      * This item will be read either when the source's dataChanged has been
0078      * emitted or on an interval if \ref interval has been set.
0079      *
0080      * The default is 0.
0081      *
0082      * \note Changing this property will clear the existing history.
0083      */
0084     Q_PROPERTY(int item READ item WRITE setItem NOTIFY itemChanged)
0085     int item() const;
0086     void setItem(int newItem);
0087     Q_SIGNAL void itemChanged();
0088     /**
0089      * The maximum amount of history to keep.
0090      *
0091      * The default is 10.
0092      */
0093     Q_PROPERTY(int maximumHistory READ maximumHistory WRITE setMaximumHistory NOTIFY maximumHistoryChanged)
0094     int maximumHistory() const;
0095     void setMaximumHistory(int maximumHistory);
0096     Q_SIGNAL void maximumHistoryChanged();
0097     /**
0098      * The interval, in milliseconds, with which to query the data source.
0099      *
0100      * If set to a value <= 0, a new item will be added whenever \ref source
0101      * changes. Otherwise, source will be sampled every interval milliseconds
0102      * and a new item will be added with whatever value it has at that point,
0103      * even if it did not change.
0104      *
0105      * The default is 0.
0106      */
0107     Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged)
0108     int interval() const;
0109     void setInterval(int newInterval);
0110     Q_SIGNAL void intervalChanged();
0111     /**
0112      * The fill mode.
0113      *
0114      * This determines what happens when there is not enough history yet. See
0115      * \ref FillMode for which modes are available.
0116      *
0117      * The default is DoNotFill.
0118      *
0119      * \note Changing this property will clear the existing history.
0120      */
0121     Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
0122     FillMode fillMode() const;
0123     void setFillMode(FillMode newFillMode);
0124     Q_SIGNAL void fillModeChanged();
0125 
0126     /**
0127      * Clear the entire history of this source.
0128      */
0129     Q_INVOKABLE void clear();
0130 
0131     int itemCount() const override;
0132     QVariant item(int index) const override;
0133     QVariant minimum() const override;
0134     QVariant maximum() const override;
0135     QVariant first() const override;
0136 
0137 private:
0138     void update();
0139 
0140     ChartDataSource *m_dataSource = nullptr;
0141     int m_item = 0;
0142     int m_maximumHistory = 10;
0143     FillMode m_fillMode = DoNotFill;
0144     std::unique_ptr<QTimer> m_updateTimer;
0145     QList<QVariant> m_history;
0146 };
0147 
0148 #endif // HISTORYPROXYSOURCE_H