#ifndef HISTOGRAMCHART_H #define HISTOGRAMCHART_H #include #include #include #include struct Statistics { qreal sum = 0; qreal sumSquares = 0; int count = 0; void add(qreal v) { sum += v; sumSquares += v*v; count++; } void clear() { sum = 0; sumSquares = 0; count = 0; } int getCount() const { return count; } qreal getMean() const { return sum / static_cast(count); } qreal getStdDev() const { const qreal x = sumSquares / static_cast(count); const qreal e = getMean(); return std::sqrt(x - (e*e)); } }; class HistogramChart : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(qreal binWidth READ binWidth WRITE setBinWidth) Q_PROPERTY(qreal mean READ mean) Q_PROPERTY(qreal stdDev READ stdDev) Q_PROPERTY(int totalCount READ totalCount) Q_PROPERTY(qreal maxBinValue READ maxBinValue) public: HistogramChart(QQuickItem* parent = nullptr); QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } QColor color() const { return m_color; } void setColor(const QColor& color) { m_color = color; } qreal binWidth() const { return _binWidth; } void setBinWidth(qreal newBinWidth) { _binWidth = newBinWidth; reset(); } qreal mean() const { return stats.getMean(); } qreal stdDev() const { return stats.getStdDev(); } int totalCount() const { return stats.getCount(); } qreal maxBinValue() const { return minValue + (maxBinIndex * binWidth()); } void paint(QPainter *painter); Q_INVOKABLE void pushData(qreal value); Q_INVOKABLE void clear(); // soft reset Q_INVOKABLE void reset(); // hard reset public: int numberOfBins() const; int binIndex(qreal value) const; private: QString m_name; QColor m_color; std::vector _histogram; qreal _binWidth = 100; qreal minValue = std::numeric_limits::quiet_NaN(); qreal maxValue = std::numeric_limits::quiet_NaN(); size_t lastUpdatedBinIndex = 0; int maxBinCount = 0; int maxBinIndex = 0; // Satistics Statistics stats; }; #endif // HISTOGRAMCHART_H