File ErrorBarSeries.hpp¶
File List > QAccelPlot > src > QAccelPlot > series > ErrorBarSeries.hpp
Go to the documentation of this file
//
// SPDX-FileCopyrightText: 2026 Michal Grabarczyk
// SPDX-License-Identifier: GPL-3.0-only WITH Universal-FOSS-exception-1.0
//
// This file is also available under a separate commercial license.
// See COMMERCIAL-LICENSING.md for contact information.
//
#pragma once
#include "QAccelPlot/series/PlotSeries.hpp"
#include "QAccelPlot/series/SpatialGrid.hpp"
#include "QAccelPlot/transitions/DataTransition.hpp"
#include <QColor>
#include <QList>
#include <QVariantMap>
#if __has_include(<QtQmlIntegration/qqmlintegration.h>)
#include <QtQmlIntegration/qqmlintegration.h>
#else
#include <QtQml/qqmlregistration.h>
#endif
#include <cstdint>
#include <memory>
#include <optional>
#include <vector>
class QSGGeometryNode;
namespace QAccelPlot {
class ErrorBarMaterial;
class TransitionRunner;
class ErrorBarSeries : public PlotSeries {
Q_OBJECT
QML_NAMED_ELEMENT(ErrorBarSeries)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged)
Q_PROPERTY(qreal capLength READ capLength WRITE setCapLength NOTIFY capLengthChanged)
Q_PROPERTY(qreal offset READ offset WRITE setOffset NOTIFY offsetChanged)
Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor NOTIFY hoverColorChanged)
Q_PROPERTY(qreal hoverRadius READ hoverRadius WRITE setHoverRadius NOTIFY hoverRadiusChanged)
Q_PROPERTY(DataTransition* transition READ transition WRITE setTransition NOTIFY transitionChanged)
Q_PROPERTY(int hoveredIndex READ hoveredIndex NOTIFY hoveredIndexChanged)
public:
explicit ErrorBarSeries(QQuickItem* parent = nullptr);
~ErrorBarSeries() override;
Qt::Orientation orientation() const;
void setOrientation(Qt::Orientation orientation);
QColor color() const;
void setColor(const QColor& color);
qreal lineWidth() const;
void setLineWidth(qreal width);
qreal capLength() const;
void setCapLength(qreal length);
qreal offset() const;
void setOffset(qreal offset);
QColor hoverColor() const;
void setHoverColor(const QColor& color);
qreal hoverRadius() const;
void setHoverRadius(qreal radius);
DataTransition* transition() const;
void setTransition(DataTransition* transition);
int hoveredIndex() const;
Q_INVOKABLE void appendData(qreal x, qreal y, qreal low, qreal high);
Q_INVOKABLE void setData(const QList<qreal>& xs, const QList<qreal>& ys, const QList<qreal>& lows, const QList<qreal>& highs);
void setData(const std::vector<double>& xs, const std::vector<double>& ys, const std::vector<double>& lows, const std::vector<double>& highs);
// The PlotSeries overloads take interleaved (x, y, low, high) quadruples, as doubles or floats.
using PlotSeries::setData;
using PlotSeries::setDataF;
Q_INVOKABLE void appendErrorData(qreal x, qreal y, qreal error);
Q_INVOKABLE void appendErrorData(qreal x, qreal y, qreal minus, qreal plus);
Q_INVOKABLE void setErrorData(const QList<qreal>& xs, const QList<qreal>& ys, const QList<qreal>& errors);
Q_INVOKABLE void setErrorData(const QList<qreal>& xs, const QList<qreal>& ys, const QList<qreal>& minuses, const QList<qreal>& pluses);
void setErrorData(const std::vector<double>& xs, const std::vector<double>& ys, const std::vector<double>& errors);
void setErrorData(const std::vector<double>& xs, const std::vector<double>& ys, const std::vector<double>& minuses, const std::vector<double>& pluses);
Q_INVOKABLE void clearData() override;
Q_INVOKABLE QVariantMap errorBarAt(int index) const;
Q_INVOKABLE int errorBarIndexAt(const QPointF& position) const;
bool contains(const QPointF& point) const override;
signals:
void orientationChanged();
void colorChanged();
void lineWidthChanged();
void capLengthChanged();
void offsetChanged();
void hoverColorChanged();
void hoverRadiusChanged();
void transitionChanged();
void hoveredIndexChanged();
protected:
bool recordInspectionSupported() const override;
InspectionRecord inspectionRecord(int index) const override;
InspectionRecord inspectionRecordAt(const QPointF& position) const override;
QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData) override;
void hoverEnterEvent(QHoverEvent* event) override;
void hoverMoveEvent(QHoverEvent* event) override;
void hoverLeaveEvent(QHoverEvent* event) override;
void applyDataPoints(DataPointInput&& input) override;
void onAxisScaleChanged() override;
void onDataPointsChanged(DataChange change, int previousCount) override;
private:
// A drawn error bar in data coordinates: its position across the bounds, shifted by the offset,
// and its ends along them. A NaN bound is replaced by the value and has no cap.
struct DataBar {
double position;
double start;
double end;
bool startCapped;
bool endCapped;
};
bool isHorizontal() const;
double component(int index, int column) const;
// Returns error bar \a index of \a dataPoints as drawn, or nullopt when it is not drawn.
std::optional<DataBar> dataBar(const DataPointStore::View& dataPoints, int index) const;
// Pixel distance from \a position to the line and caps of drawn error bar \a index, or nullopt when it is not drawn.
std::optional<qreal> pixelDistance(int index, const QPointF& position) const;
void applyInterleavedData(std::vector<double>&& data);
void applyDoubleData(std::vector<double>&& data, int dataPointCount);
// Starts animating from the \a drawnCount error bars in \a drawn to the stored ones.
void startTransition(const std::vector<double>& drawn, int drawnCount);
void advanceTransition();
// Shows the stored data points at once, when a transition was drawing others.
void endTransition();
void discardTransition();
void setHoveredIndex(int index);
void onGeometryChanged();
void ensureSpatialGrid() const;
void updateVertices(QSGGeometryNode& node, int drawnCount) const;
void updateMaterial(ErrorBarMaterial& material, int drawnCount) const;
Qt::Orientation orientation_{Qt::Vertical};
QColor color_;
qreal lineWidth_{1.5};
qreal capLength_{8.0};
qreal offset_{0.0};
QColor hoverColor_;
qreal hoverRadius_{6.0};
int hoveredIndex_{-1};
std::unique_ptr<TransitionRunner> transition_;
// Frame buffer of the animation, recycled from frame to frame.
std::vector<double> frameBuffer_;
// Render revision of the data points last uploaded to the GPU.
std::uint64_t uploadedRevision_{0};
// Data-space rectangles of the error bars that bound the hover candidates.
mutable std::vector<double> hitRects_;
mutable SpatialGrid spatialGrid_;
mutable bool spatialGridValid_{false};
};
} // namespace QAccelPlot