Class ACurve
- Direct Known Subclasses:
Curve,HistoCurve,StripChartCurve
Responsibilities
- State: name, visibility, style, drawing method, per-curve fit “order” knob.
- Computed artifacts: fit results/evaluator and spline cache.
- Notifications: curve-level change events for data/style/fit.
- Batching: coalescing multiple changes into a single notification burst.
Thread-safety policy
This library is Swing-based. Curve change notifications commonly lead
(directly or indirectly) to repaint() on a plot canvas. Swing
requires UI updates to occur on the Event Dispatch Thread (EDT).
Therefore:
- All methods that notify listeners must be called on the EDT.
- Data integrity within a curve is typically protected by
lockin subclasses, butlockdoes not make Swing notifications thread-safe by itself.
For streaming / DAQ scenarios, the recommended pattern is:
producer threads → enqueue points (lock-free queue) → EDT drains → curve.add(...)
Dirty flag and cache invalidation
The curve may cache computed artifacts such as a FitResult or
CubicSpline. When data or relevant rendering parameters change, those
artifacts must be invalidated and the curve marked dirty.
Use:
markDataChanged()when the underlying data values have changed.markStyleChanged()when appearance or drawing configuration has changed.markFitChanged()when a fit result has been updated (e.g., afterdoFit(boolean)).
- Author:
- heddle
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static final classA reusable pending-queue helper for streaming/DAQ scenarios. -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionfinal voidaddCurveChangeListener(CurveChangeListener listener) Add a curve change listener.final voidBegin batching curve change notifications.abstract voidClear all data from this curve and fire a DATA change event.protected IFitterHook: subclasses may override to provide an appropriate fitter for the current drawing method and per-curve knobs.final voidNotify listeners that data has changed (EDT-only).abstract voiddoFit(boolean force) Perform a curve fit (or compute derived artifacts like splines), depending on the configured curve drawing method.final voidEnd batching curve change notifications.protected final voidNotify listeners of a curve change.protected FitResultfitWithOptionalWeights(IFitter fitter, FitVectors v) Common pattern: if weights exist, call the weighted fit overload; otherwise call fit(x,y).intGet the per-curve order/count knob for fit methods that need an integer order.final EvaluatorGet the cached fit evaluator y(x) for the current fit.getStyle()protected voidInitialize style with a unique style ID.booleanisDirty()booleanConvenience method to determine if this curve is a histogram curve.booleanConvenience method to determine if this curve is a strip chart curve.booleanbooleanConvenience method to determine if this curve is an XY curve.abstract intlength()Get curve length (number of points or effective points in the data columns).protected final voidMark data changed: invalidate computed artifacts and notify listeners.protected final voidMark fit changed: notify listeners.protected final voidMark style/configuration changed: invalidate computed artifacts and notify listeners.final Stringname()final voidremoveCurveChangeListener(CurveChangeListener listener) Remove a curve change listener.protected static voidrequireEdt(String operation) Ensure that the current thread is the Swing EDT.protected final voidscheduleDrainOnce(Runnable drainOnEdt) Schedule a drain operation to run later on the Swing EDT, coalescing multiple requests into a single posted runnable.voidsetCubicSpline(CubicSpline cubicSpline) Set cached cubic spline.voidSet curve drawing method.voidsetDirty(boolean dirty) Set dirty flag.voidsetFitOrder(int order) Set the per-curve order/count knob for fit methods that need an integer order.final voidsetFitResult(FitResult fitResult) Set the fit result and notify listeners that the fit has changed.final voidSet curve name.voidSet the curve style.voidsetVisible(boolean visible) Set curve visibility.abstract Snapshotsnapshot()Obtain a consistent snapshot of the current data, suitable for plotting without locking.final voidNotify listeners that style has changed (EDT-only).toString()abstract doublexMax()abstract doublexMin()abstract doubleyMax()abstract doubleyMin()
-
Field Details
-
lock
Lock object intended for subclasses to synchronize data mutation and snapshot creation.This lock is about data consistency (e.g., keeping x/y arrays aligned). It does not automatically make Swing notifications safe; notifications are enforced to be EDT-only.
-
-
Constructor Details
-
ACurve
Create a curve with the given name.- Parameters:
name- curve name (legend label)
-
-
Method Details
-
doFit
public abstract void doFit(boolean force) Perform a curve fit (or compute derived artifacts like splines), depending on the configured curve drawing method.- Parameters:
force- true to force a refit even if not dirty
-
length
public abstract int length()Get curve length (number of points or effective points in the data columns).- Returns:
- curve length
-
clearData
public abstract void clearData()Clear all data from this curve and fire a DATA change event.Thread-safe: may be called from any thread. If called off the EDT, the clear is performed later on the EDT and coalesced with other scheduled drains.
Note: this also clears any queued (not-yet-applied) points so the curve truly becomes empty.
-
createFitterForCurrentMethod
Hook: subclasses may override to provide an appropriate fitter for the current drawing method and per-curve knobs.- Returns:
- a fitter for the current method, or null if not applicable
-
name
- Returns:
- the curve name (legend label)
-
setName
Set curve name.This is a UI/style-affecting change. Must be called on the EDT.
- Parameters:
name- curve name
-
isVisible
public boolean isVisible()- Returns:
- true if visible
-
setVisible
public void setVisible(boolean visible) Set curve visibility.This is a UI/style-affecting change. Must be called on the EDT.
- Parameters:
visible- visibility flag
-
fitResult
- Returns:
- the current fit result (may be null)
-
getFitValueGetter
Get the cached fit evaluator y(x) for the current fit.- Returns:
- evaluator for the current fit, or null if none
-
setFitResult
Set the fit result and notify listeners that the fit has changed.Must be called on the EDT.
- Parameters:
fitResult- fit result (may be null)
-
getStyle
- Returns:
- the curve style
-
setStyle
Set the curve style.This is a UI/style-affecting change. Must be called on the EDT.
- Parameters:
style- new style
-
isDirty
public boolean isDirty()- Returns:
- true if curve is dirty
-
setDirty
public void setDirty(boolean dirty) Set dirty flag.This method does not notify listeners. Prefer
markDataChanged()ormarkStyleChanged()when you want notifications.- Parameters:
dirty- dirty flag
-
getCubicSpline
- Returns:
- cached cubic spline (may be null)
-
setCubicSpline
Set cached cubic spline.This does not notify listeners; it is typically called during
doFit(boolean).- Parameters:
cubicSpline- cubic spline to cache (may be null)
-
getCurveDrawingMethod
- Returns:
- curve drawing method
-
isHistogram
public boolean isHistogram()Convenience method to determine if this curve is a histogram curve.- Returns:
- true if histogram curve
-
isStripChart
public boolean isStripChart()Convenience method to determine if this curve is a strip chart curve.- Returns:
- true if strip chart curve
-
isXYCurve
public boolean isXYCurve()Convenience method to determine if this curve is an XY curve.- Returns:
- true if XY curve
-
setCurveDrawingMethod
Set curve drawing method.This is a style/configuration change and invalidates computed artifacts. Must be called on the EDT.
- Parameters:
method- method (null treated as NONE)
-
getFitOrder
public int getFitOrder()Get the per-curve order/count knob for fit methods that need an integer order.- Returns:
- per-curve order/count (>= 1)
-
setFitOrder
public void setFitOrder(int order) Set the per-curve order/count knob for fit methods that need an integer order.This affects fitting/drawing behavior, so it is treated as a style/config change and invalidates computed artifacts. Must be called on the EDT.
- Parameters:
order- per-curve order/count (>= 1)
-
fitWithOptionalWeights
Common pattern: if weights exist, call the weighted fit overload; otherwise call fit(x,y).This utility performs small sanity checks on
FitVectorsbefore delegating to the fitter. -
markDataChanged
protected final void markDataChanged()Mark data changed: invalidate computed artifacts and notify listeners.Must be called on the EDT (notifications typically lead to repaint).
-
dataChanged
public final void dataChanged()Notify listeners that data has changed (EDT-only). -
markStyleChanged
protected final void markStyleChanged()Mark style/configuration changed: invalidate computed artifacts and notify listeners.Must be called on the EDT. Style/config changes may affect derived artifacts (fit/spline), so this method clears computed artifacts as well.
-
styleChanged
public final void styleChanged()Notify listeners that style has changed (EDT-only). -
markFitChanged
protected final void markFitChanged()Mark fit changed: notify listeners.Must be called on the EDT.
-
beginUpdate
public final void beginUpdate()Begin batching curve change notifications.While batching (depth > 0), calls to
fireCurveChanged(CurveChangeType)do not notify listeners immediately; instead they set pending flags. WhenendUpdate()returns the depth to 0, pending flags are flushed.Must be called on the EDT.
-
endUpdate
public final void endUpdate()End batching curve change notifications.When the batch depth returns to 0, pending changes are flushed. Must be called on the EDT.
-
xMin
public abstract double xMin()- Returns:
- the minimum x value for this curve
-
xMax
public abstract double xMax()- Returns:
- the maximum x value for this curve
-
yMin
public abstract double yMin()- Returns:
- the minimum y value for this curve
-
yMax
public abstract double yMax()- Returns:
- the maximum y value for this curve
-
addCurveChangeListener
Add a curve change listener.- Parameters:
listener- listener to add (ignored if null)
-
removeCurveChangeListener
Remove a curve change listener.- Parameters:
listener- listener to remove (ignored if null)
-
fireCurveChanged
Notify listeners of a curve change.This method assumes EDT usage; higher-level methods enforce EDT. When batching is active (updateDepth > 0), the change is recorded as pending.
- Parameters:
type- change type (ignored if null)
-
initStyle
protected void initStyle()Initialize style with a unique style ID. -
getFitSummary
- Returns:
- single-line summary of the current fit result, or null if none
-
snapshot
Obtain a consistent snapshot of the current data, suitable for plotting without locking.Subclasses should return copies of their internal primitive arrays (or equivalent immutable state), typically while synchronizing on
lock.- Returns:
- snapshot of plot-ready data
-
toString
-
requireEdt
Ensure that the current thread is the Swing EDT.- Parameters:
operation- operation name used in the exception message- Throws:
IllegalStateException- if not on EDT
-
scheduleDrainOnce
Schedule a drain operation to run later on the Swing EDT, coalescing multiple requests into a single posted runnable.This is intended for curves whose
add(...)methods are safe to call from any thread: background calls enqueue data, then call this method to ensure the queued data is applied on the EDT.If many threads call this repeatedly, only the first call posts a runnable; subsequent calls are coalesced until the posted runnable begins execution.
- Parameters:
drainOnEdt- code that must execute on the EDT (typically callsdrainPendingOnEDT(...)in the subclass)
-