Blackchirp Plot Curve Classes
This page documents the five curve classes that form the plot-curve hierarchy
used by ZoomPanPlot and its subclasses. All five are defined in
src/gui/plot/blackchirpplotcurve.h.
BlackchirpPlotCurveBase — abstract root of the hierarchy.
BlackchirpPlotCurve — concrete, general-purpose point-cloud curve.
BCEvenSpacedCurveBase — abstract base for uniformly-spaced data.
BlackchirpFTCurve — concrete curve for Fourier-transform spectra.
BlackchirpFIDCurve — concrete curve for free-induction decay waveforms.
Curve objects are created exclusively through CurveFactory, which
injects the appropriate storage backend. The appearance fields of every curve
(color, line style, thickness, marker, visibility, autoscale, y-axis) are
bundled into CurveAppearanceWidget::CurveAppearance and surfaced
for editing via CurveAppearanceWidget embedded in the
ZoomPanPlot context menu.
Curve hierarchy
QwtPlotCurve
└── BlackchirpPlotCurveBase (abstract)
├── BlackchirpPlotCurve (concrete — arbitrary x spacing)
└── BCEvenSpacedCurveBase (abstract — uniform x spacing)
├── BlackchirpFTCurve (concrete — Ft spectrum)
└── BlackchirpFIDCurve (concrete — FID waveform)
Storage backend abstraction
BlackchirpPlotCurveBase does not inherit from SettingsStorage directly.
Instead, it owns a std::unique_ptr<CurveStorageInterface> that is injected
at construction by CurveFactory. Two concrete backends are
provided in curvefactory.h:
SettingsStorageWrapper — wraps
SettingsStorage(QSettings-backed) so that appearance settings persist across sessions under the curve’s key. Used for standard curves that live on persistent plots (FT view, tracking plots, etc.).OverlayMetadataStorage — stores appearance settings as metadata inside an
OverlayBaseobject. Used for overlay curves; settings travel with the overlay rather than being written to the global settings file.
The StorageType enum (Settings or OverlayMetadata) is detected
automatically at construction by dynamic-casting the injected storage pointer.
Callers that need to retrieve the associated overlay can call
getOverlay(), which returns a std::shared_ptr<OverlayBase> or
nullptr for Settings-backend curves.
This indirection keeps the curve classes free of knowledge about where their
settings live; only CurveFactory and the overlay system need to
reason about which backend to use.
Settings keys
The following keys are stored in the curve’s active CurveStorageInterface
backend.
Key |
Type |
Description |
|---|---|---|
|
QColor |
Pen and symbol color. |
|
int (QwtPlotCurve::CurveStyle) |
Drawing mode (Lines, Dots, Sticks, etc.). |
|
int (Qt::PenStyle) |
Pen dash pattern. |
|
double |
Pen width in pixels (default 1.0). |
|
int (QwtSymbol::Style) |
Point-marker shape. |
|
int |
Marker diameter in pixels (default 5). |
|
int (QwtPlot::Axis) |
X axis assignment (default xBottom). |
|
int (QwtPlot::Axis) |
Y axis assignment (default yLeft). |
|
bool |
Curve visibility (default true). |
|
bool |
Whether the curve participates in autoscale (default true). |
|
int |
Index of the ZoomPanPlot panel that owns this curve (default -1). |
Setter family and visibility persistence
BlackchirpPlotCurveBase provides two overlapping ways to control visibility.
The setCurve* family (setCurveVisible, setCurveAutoscale,
setCurveAxisX, setCurveAxisY, setCurvePlotIndex) writes to the
CurveStorageInterface backend so the curve’s state is restored across
sessions, whereas the inherited QwtPlotItem::setVisible() and the
lower-level appearance setters (setColor, etc.) are for transient changes
that do not need to survive a restart. See the setCurveVisible note in the
rendered API below for details.
Attaching and detaching curves
QwtPlotItem::attach and QwtPlotItem::detach are made private
inside BlackchirpPlotCurveBase via using-declarations. Calling
curve->attach(plot) or curve->detach() from anywhere outside
ZoomPanPlot (the only friend) is a hard compile error.
The supported entry points are ZoomPanPlot::attachCurve and
ZoomPanPlot::detachCurve, which drain the asynchronous filter
worker before mutating the plot’s curve registry. See the Curve registry
and thread safety section of ZoomPanPlot for the full rationale.
Curves held in std::unique_ptr do not need an explicit
detachCurve before destruction. ~BlackchirpPlotCurveBase calls
ZoomPanPlot::_unregisterCurve (a private helper friended to this
class) which drains the worker and removes the pointer from the registry
before ~QwtPlotItem performs its own detach. This makes container
clearing patterns such as d_overlayCurves.clear() and
unique_ptr::reset() safe with respect to the worker.
Downsampling filter
BlackchirpPlotCurveBase::filter() is called from a QtConcurrent
worker dispatched by ZoomPanPlot whenever the x range changes. The
worker iterates an immutable snapshot of the plot’s curve registry that
was built under the plot’s mutex; it never touches the live registry, the
QwtPlot item list, or any widget state. filter() delegates to the
protected pure-virtual _filter(int w, const QwtScaleMap map) and
stores the result in the Qwt sample buffer under a mutex so that the
paint thread always reads a consistent snapshot.
Each implementation compresses the visible portion of the data to at most \(2w\) points using min/max compression per pixel column: for each pixel column, if more than one data point maps to that column, both the minimum and maximum y values are emitted so that vertical features (peaks, noise spikes) are preserved at all zoom levels.
BlackchirpPlotCurve::_filter iterates over the QVector<QPointF>
data. BCEvenSpacedCurveBase::_filter (sealed final) computes pixel
boundaries analytically from xFirst(), spacing(), and the scale map,
avoiding a linear search.
curveData() and boundingRect() are the two pure-virtual methods that
every concrete class must implement:
curveData()returns the full (non-downsampled) data asQVector<QPointF>; used for CSV export and context-menu Export XY.boundingRect()returns the data extent in plot coordinates; used byZoomPanPlot::replot()for autoscale. Return an invalid rect (width < 0 or height < 0) when no data is available.
BCEvenSpacedCurveBase extension hooks
Subclasses of BCEvenSpacedCurveBase implement four protected methods to
describe their data:
xFirst()— x coordinate of the first data point.spacing()— uniform x increment between consecutive points.numPoints()— total number of data points.yData()— y values asQVector<double>; called once per filter pass and should return a detached copy so the filter loop can read without holding a lock.
The _filter implementation in BCEvenSpacedCurveBase is declared
final to prevent accidental re-overriding in leaf classes.
API Reference
-
class BlackchirpPlotCurveBase : public QwtPlotCurve
Abstract base class for all Blackchirp plot curves.
BlackchirpPlotCurveBase extends QwtPlotCurve with a storage-backend abstraction (CurveStorageInterface) that persists appearance settings to either QSettings (via SettingsStorageWrapper) or overlay metadata (via OverlayMetadataStorage). The concrete storage object is injected at construction by CurveFactory, keeping the curve classes independent of the persistence mechanism.
Subclasses must implement curveData(), boundingRect(), and the protected _filter() template method. The base class calls _filter() asynchronously (from ZoomPanPlot’s filter pass) and marshals the result into the Qwt sample buffer under a mutex.
Subclassed by BCEvenSpacedCurveBase, BlackchirpPlotCurve
Public Types
-
enum class StorageType
Selects which storage backend the curve uses.
Values:
-
enumerator Settings
Appearance settings are stored in QSettings via SettingsStorageWrapper.
-
enumerator OverlayMetadata
Appearance settings are stored as metadata in an OverlayBase object.
-
enumerator Settings
Public Functions
-
BlackchirpPlotCurveBase(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
Constructs the curve with an injected storage backend.
If
titleis empty, the curve’s Qwt title is set tokey. Default appearance values are written to storage only when no existing value is found for that key.- Parameters:
storage – Heap-allocated storage backend; ownership is transferred.
key – Unique identifier for this curve within its storage namespace.
title – Display title (shown in legends and menus).
defaultLineStyle – Initial Qt::PenStyle if not already in storage.
defaultMarker – Initial QwtSymbol::Style if not already in storage.
defaultStyle – Initial QwtPlotCurve::CurveStyle if not already in storage.
-
virtual ~BlackchirpPlotCurveBase()
-
void setColor(const QColor c)
Sets the curve color and updates both the pen and the symbol brush.
- Parameters:
c – New color; persisted to storage.
-
void setCurveStyle(CurveStyle s)
Sets the Qwt drawing style (Lines, Dots, Sticks, etc.) and persists it.
- Parameters:
s – New QwtPlotCurve::CurveStyle value.
-
void setLineThickness(double t)
Sets the pen line width and persists it.
- Parameters:
t – Line width in pixels.
-
void setLineStyle(Qt::PenStyle s)
Sets the pen dash pattern and persists it.
- Parameters:
s – Qt::PenStyle value.
-
void setMarkerStyle(QwtSymbol::Style s)
Sets the point-marker symbol shape and persists it.
- Parameters:
s – QwtSymbol::Style value.
-
void setMarkerSize(int s)
Sets the point-marker diameter and persists it.
- Parameters:
s – Diameter in pixels.
-
void setName(const QString &t)
Sets the curve’s display title (shown in legends and context menus).
- Parameters:
t – New title string.
-
inline QString name() const
Returns the curve’s display title.
-
inline QString key() const
Returns the storage key passed at construction.
-
inline StorageType getStorageType() const
Returns which storage backend this curve uses.
-
std::shared_ptr<OverlayBase> getOverlay() const
Returns the associated OverlayBase when the storage type is OverlayMetadata, or nullptr.
-
virtual QVector<QPointF> curveData() const = 0
Returns the full curve data as a point vector.
The returned vector reflects the canonical data set before any downsampling; it is used for CSV export and bounding-rect calculations.
-
void setCurveVisible(bool v)
Sets curve visibility and persists the state to storage.
Note
Use QwtPlotItem::setVisible() directly if persistence is not desired (for example when temporarily hiding a curve in a view-only context). This method is intended for user-driven visibility changes on tracking and logging plots where the setting should survive a session restart.
- Parameters:
v –
trueto show the curve.
-
void setCurveAutoscale(bool enabled)
Enables or disables autoscale participation and persists the choice.
A curve with autoscale disabled contributes to the legend but its bounding rect is excluded from ZoomPanPlot’s axis range calculations.
- Parameters:
enabled –
trueto include in autoscale.
-
void setCurveAxisX(QwtPlot::Axis a)
Sets the x axis and persists the assignment.
- Parameters:
a – QwtPlot::Axis value (xBottom or xTop).
-
void setCurveAxisY(QwtPlot::Axis a)
Sets the y axis and persists the assignment.
- Parameters:
a – QwtPlot::Axis value (yLeft or yRight).
-
void setCurvePlotIndex(int i)
Sets the owning plot-panel index and persists it.
The plot index identifies which ZoomPanPlot panel this curve belongs to when a view holds multiple panels (e.g. the rolling-data view).
- Parameters:
i – Zero-based panel index; -1 means unassigned.
-
int plotIndex() const
Returns the stored plot-panel index, or -1 if not set.
-
void updateFromSettings()
Re-applies all appearance settings from storage to the Qwt curve.
Call after a storage backend is refreshed externally (e.g. when an overlay’s metadata is reloaded from disk).
-
void filter(int w, const QwtScaleMap map)
Computes a downsampled sample set and stores it in the Qwt sample buffer.
Called by ZoomPanPlot’s concurrent filter pass. The canvas width
wand scale mapmapare used to limit the rendered sample count to approximately 2×wpoints via min/max compression per pixel column.- Parameters:
w – Canvas width in pixels.
map – Current x-axis scale map.
-
virtual QRectF boundingRect() const override = 0
Returns the data bounding rect in plot coordinates.
Must reflect the full (non-downsampled) data range so that ZoomPanPlot can compute correct autoscale limits. Return an invalid rect (width < 0 or height < 0) when no data is available.
-
void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const override
Protected Functions
-
virtual QVector<QPointF> _filter(int w, const QwtScaleMap map) = 0
Produces a downsampled point vector for the current view.
Called by filter(). Implementations should return at most 2×
wpoints, using min/max compression to preserve peak fidelity when multiple data points map to the same pixel column.- Parameters:
w – Canvas width in pixels.
map – Current x-axis scale map used to determine pixel boundaries.
- Returns:
Downsampled point vector to pass to the Qwt sample buffer.
Private Functions
-
void configurePen()
-
void configureSymbol()
-
void configureCurveStyle()
-
void setSamples(const QVector<QPointF> d)
Private Members
-
std::unique_ptr<CurveStorageInterface> d_storage
-
const QString d_key
-
QMutex *p_samplesMutex
-
StorageType d_storageType
-
OverlayMetadataStorage *p_overlayMetadataStorage
Friends
- friend class ZoomPanPlot
-
enum class StorageType
-
class BlackchirpPlotCurve : public BlackchirpPlotCurveBase
Concrete BlackchirpPlotCurveBase for arbitrary (x, y) point-cloud data.
BlackchirpPlotCurve stores its data as a QVector<QPointF> and supports both bulk replacement (setCurveData()) and incremental appending (appendPoint()). It is the general-purpose curve type used for tracking plots, aux-data traces, and any other non-uniform x-spacing data.
Public Functions
-
BlackchirpPlotCurve(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
Constructs the curve with an injected storage backend.
-
~BlackchirpPlotCurve()
-
void setCurveData(const QVector<QPointF> d)
Replaces the stored data and recomputes the bounding rect.
- Parameters:
d – New point vector; the bounding rect height is computed from all y values.
-
void setCurveData(const QVector<QPointF> d, double min, double max)
Replaces the stored data with a pre-computed bounding rect height.
Use this overload when the caller already knows the y-range to avoid a second pass over the data.
- Parameters:
d – New point vector.
min – Minimum y value (bounding rect top).
max – Maximum y value (bounding rect bottom).
-
void appendPoint(const QPointF p)
Appends a single point and extends the bounding rect.
- Parameters:
p – Point to append.
-
virtual QRectF boundingRect() const override
Returns the data bounding rect in plot coordinates.
Must reflect the full (non-downsampled) data range so that ZoomPanPlot can compute correct autoscale limits. Return an invalid rect (width < 0 or height < 0) when no data is available.
-
virtual QVector<QPointF> curveData() const override
Returns the full curve data as a point vector.
The returned vector reflects the canonical data set before any downsampling; it is used for CSV export and bounding-rect calculations.
Protected Functions
-
virtual QVector<QPointF> _filter(int w, const QwtScaleMap map) override
Produces a downsampled point vector for the current view.
Called by filter(). Implementations should return at most 2×
wpoints, using min/max compression to preserve peak fidelity when multiple data points map to the same pixel column.- Parameters:
w – Canvas width in pixels.
map – Current x-axis scale map used to determine pixel boundaries.
- Returns:
Downsampled point vector to pass to the Qwt sample buffer.
Private Functions
-
void calcBoundingRectHeight()
-
BlackchirpPlotCurve(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
-
class BCEvenSpacedCurveBase : public BlackchirpPlotCurveBase
Abstract base for evenly spaced curves (constant x increment).
BCEvenSpacedCurveBase provides a closed-form _filter() implementation that avoids iterating over all data points to find pixel boundaries — it computes array indices directly from
xFirst(),spacing(), and the scale map. Subclasses supply the three geometric hooks and the y-data vector; the filter logic is sealed (final) and cannot be further overridden.Subclassed by BlackchirpEvenSpacedCurve, BlackchirpFIDCurve, BlackchirpFTCurve
Public Functions
-
BCEvenSpacedCurveBase(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
Constructs the curve with an injected storage backend.
-
virtual ~BCEvenSpacedCurveBase()
-
double xVal(int i) const
Returns the x coordinate of data point
i.- Parameters:
i – Zero-based data index.
-
int indexBefore(double xVal) const
Returns the index of the last data point with x <
xVal.- Parameters:
xVal – X coordinate to search for.
Protected Functions
-
virtual double xFirst() const = 0
Returns the x coordinate of the first data point.
-
virtual double spacing() const = 0
Returns the uniform x spacing between consecutive data points.
-
virtual int numPoints() const = 0
Returns the total number of data points.
-
virtual QVector<double> yData() = 0
Returns the y-data vector; called once per filter pass.
Implementations should return a detached (copy-on-write) vector so the filter loop can read without holding a lock.
-
virtual QVector<QPointF> _filter(int w, const QwtScaleMap map) final override
Sealed min/max-compression filter exploiting uniform x spacing.
-
BCEvenSpacedCurveBase(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
-
class BlackchirpFTCurve : public BCEvenSpacedCurveBase
Curve for displaying a Fourier transform (Ft) spectrum.
BlackchirpFTCurve wraps an Ft object and exposes its frequency axis (minFreqMHz / xSpacing) and y-data through the BCEvenSpacedCurveBase hooks. The Ft is set atomically under a mutex so the filter thread always reads a consistent snapshot.
Public Functions
-
BlackchirpFTCurve(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
Constructs the curve with an injected storage backend.
-
~BlackchirpFTCurve()
-
void setCurrentFt(const Ft f)
Replaces the displayed Ft spectrum.
Thread-safe: the Ft is stored under the internal mutex and the next filter pass picks up the new data.
- Parameters:
f – New Ft object to display.
-
virtual QRectF boundingRect() const override
Returns the data bounding rect in plot coordinates.
Must reflect the full (non-downsampled) data range so that ZoomPanPlot can compute correct autoscale limits. Return an invalid rect (width < 0 or height < 0) when no data is available.
-
virtual QVector<QPointF> curveData() const override
Returns the full curve data as a point vector.
The returned vector reflects the canonical data set before any downsampling; it is used for CSV export and bounding-rect calculations.
Private Functions
-
virtual double xFirst() const override
Returns the x coordinate of the first data point.
-
virtual double spacing() const override
Returns the uniform x spacing between consecutive data points.
-
virtual int numPoints() const override
Returns the total number of data points.
-
virtual QVector<double> yData() override
Returns the y-data vector; called once per filter pass.
Implementations should return a detached (copy-on-write) vector so the filter loop can read without holding a lock.
-
BlackchirpFTCurve(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
-
class BlackchirpFIDCurve : public BCEvenSpacedCurveBase
Curve for displaying a free-induction decay (FID) waveform.
BlackchirpFIDCurve stores raw FID samples as a QVector<double> with a uniform time spacing. The x axis starts at 0 and extends to
spacing* numPoints. Y bounds are supplied explicitly when setCurrentFid() is called to avoid a full-vector scan.Public Functions
-
BlackchirpFIDCurve(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)
Constructs the curve with an injected storage backend.
-
~BlackchirpFIDCurve()
-
void setCurrentFid(const QVector<double> d, double spacing = 1.0, double min = 0.0, double max = 0.0)
Replaces the displayed FID waveform.
Thread-safe: all fields are updated under the internal mutex.
- Parameters:
d – Y-value samples.
spacing – Uniform time step between samples (in the plot’s x-axis unit).
min – Minimum y value; used directly as the bounding rect top.
max – Maximum y value; used directly as the bounding rect bottom.
-
virtual QRectF boundingRect() const override
Returns the data bounding rect in plot coordinates.
Must reflect the full (non-downsampled) data range so that ZoomPanPlot can compute correct autoscale limits. Return an invalid rect (width < 0 or height < 0) when no data is available.
-
virtual QVector<QPointF> curveData() const override
Returns the full curve data as a point vector.
The returned vector reflects the canonical data set before any downsampling; it is used for CSV export and bounding-rect calculations.
Protected Functions
-
virtual double xFirst() const override
Returns the x coordinate of the first data point.
-
virtual double spacing() const override
Returns the uniform x spacing between consecutive data points.
-
virtual int numPoints() const override
Returns the total number of data points.
-
virtual QVector<double> yData() override
Returns the y-data vector; called once per filter pass.
Implementations should return a detached (copy-on-write) vector so the filter loop can read without holding a lock.
-
BlackchirpFIDCurve(std::unique_ptr<CurveStorageInterface> storage, const QString key, const QString title = QString(""), Qt::PenStyle defaultLineStyle = Qt::SolidLine, QwtSymbol::Style defaultMarker = QwtSymbol::NoSymbol, QwtPlotCurve::CurveStyle defaultStyle = QwtPlotCurve::Lines)