Documentation
¶
Overview ¶
Package heatmapscroll composes the colormap package with the scrollingTexture widget (ADR-0058) into a single, opinionated wrapper for "streaming scalar → colour heatmap" use cases: audio spectrograms, RF waterfalls, thermal streams, rolling metrics heatmaps.
Ownership model ¶
- The caller owns the data stream: HeatmapScroll does not pull samples; it exposes PushColumn which the caller invokes with one column of heightSlots float32 samples per "time step".
- The wrapper owns the ring-buffer write cursor (head) and the per-frame staging buffer of freshly-mapped RGBA columns.
- The Rust widget owns the GPU TextureHandle (per ADR-0058 SD10, texture storage is encapsulated inside the scrollingTexture opcode; frame-LRU reaps it after 600 idle frames, or Release drops it immediately).
Per-frame loop ¶
hs := heatmapscroll.New(ids, "spectrogram", cfg, 512, 1024)
hs.SetOrientation(heatmapscroll.ScrollLeft)
// ... each frame:
for _, col := range columnsThisFrame {
stats := hs.PushColumn(col)
if stats.BadSamples > 0 { log.Warn(...) }
}
hs.Render()
if row, col, ok := hs.HoveredCell(); ok { ... }
if hs.Clicked() { ... }
Hover and click readouts are one frame behind the pixels that produced them, per ADR-0058 "Consequences / Negative" (FFFI r9/r10 databindings reset each Sync). Callers that need zero-lag readout should track the pointer themselves and index into the data ring they already own.
Index ¶
- Variables
- type Filter
- type HeatmapScroll
- func (inst *HeatmapScroll) Clicked() bool
- func (inst *HeatmapScroll) Head() uint32
- func (inst *HeatmapScroll) HoveredCell() (row uint32, col uint32, hovered bool)
- func (inst *HeatmapScroll) PushColumn(samples []float32) (stats colormap.ColumnStats)
- func (inst *HeatmapScroll) Release()
- func (inst *HeatmapScroll) Render()
- func (inst *HeatmapScroll) ResetTotalStats()
- func (inst *HeatmapScroll) SetConfig(cfg *colormap.Config)
- func (inst *HeatmapScroll) SetDisplaySize(widthPx, heightPx float32)
- func (inst *HeatmapScroll) SetFilter(f Filter)
- func (inst *HeatmapScroll) SetOrientation(o Orientation)
- func (inst *HeatmapScroll) Size() (widthSlots, heightSlots uint32)
- func (inst *HeatmapScroll) TotalStats() colormap.ColumnStats
- type Orientation
Constants ¶
This section is empty.
Variables ¶
var PackageProps = packageprops.Props{ WASMWASI: packageprops.WASMCompiles, WASMJS: packageprops.WASMCompiles, WASMFreestanding: packageprops.WASMCompiles, }
PackageProps records this package's curated properties (ADR-0080). Seeded by `boxer code analysis golang wasmsurvey props generate`; curate by hand. The same group's `props verify` reconciles it.
Functions ¶
This section is empty.
Types ¶
type Filter ¶
Filter mirrors c.FilterE so callers of HeatmapScroll don't need a second import for the texture-filter enum. Named type per CS008.
const FilterLinear Filter = Filter(c.FilterLinearE)
FilterLinear — bilinear sampling; blurs across neighbouring columns. See ADR-0058 SD3 for why the default is Nearest for scientific data.
const FilterNearest Filter = Filter(c.FilterNearestE)
FilterNearest — nearest-neighbour sampling; default. See ADR-0058 SD3.
type HeatmapScroll ¶
type HeatmapScroll struct {
// contains filtered or unexported fields
}
HeatmapScroll is a streaming-scalar heatmap widget. Construct once with New, push columns each frame with PushColumn, and call Render once per frame to emit the underlying scrollingTexture opcode.
Not goroutine-safe; expected to be used from the UI goroutine.
func New ¶
func New(ids *c.WidgetIdStack, scopeKey string, cfg *colormap.Config, widthSlots, heightSlots uint32) *HeatmapScroll
New constructs a HeatmapScroll with the given scope key, colormap configuration, and ring dimensions. Panics if widthSlots or heightSlots is zero, or if cfg is nil. scopeKey must be unique within the caller's current WidgetIdStack scope; it identifies the widget across frames so the Rust-side texture cache can key on it.
Defaults: ScrollLeft + FilterNearest (the scientific-visualisation defaults called out in ADR-0058 SD3).
func (*HeatmapScroll) Clicked ¶
func (inst *HeatmapScroll) Clicked() bool
Clicked reports whether egui registered a primary click on the widget rect on the previous frame. One-frame lag, same as HoveredCell.
func (*HeatmapScroll) Head ¶
func (inst *HeatmapScroll) Head() uint32
Head returns the current ring-buffer write cursor. Useful for callers maintaining a parallel retained sample ring — they can translate (ring_col) readouts back to (logical_time_step) using head.
func (*HeatmapScroll) HoveredCell ¶
func (inst *HeatmapScroll) HoveredCell() (row uint32, col uint32, hovered bool)
HoveredCell returns the data-index coordinates currently under the pointer, and whether the pointer is over the widget at all. Row is the bin index (0 .. heightSlots-1); col is the ring position (0 .. widthSlots-1). The value carries a one-frame lag.
func (*HeatmapScroll) PushColumn ¶
func (inst *HeatmapScroll) PushColumn(samples []float32) (stats colormap.ColumnStats)
PushColumn maps one column of heightSlots samples through the current colormap.Config and queues the result for the next Render. Returns the per-column stats (bad / underflow / overflow counts). Panics if len(samples) != heightSlots — a silent truncation would misalign the ring and corrupt later columns.
func (*HeatmapScroll) Release ¶
func (inst *HeatmapScroll) Release()
Release emits the scrollingTextureRelease opcode, dropping the Rust-side TextureHandle for this widget id immediately. Intended for predictable lifecycle callers (tab close, demo teardown); otherwise the frame-LRU reaps idle entries after ~10 s at 60 Hz (ADR-0058 SD7).
func (*HeatmapScroll) Render ¶
func (inst *HeatmapScroll) Render()
Render emits the scrollingTexture opcode with the columns queued by PushColumn since the last Render, binds the r9_u64 / r10 databindings, and advances head. Call once per frame, even if no columns were pushed (the widget still needs to render its current texture content).
Host starvation (StateManager.TextureStarved): the ring texture is (re)created host-side on first show, on a slot-shape change, and after the idle LRU evicted it while the widget went uninterpreted (a hidden dock tab — imztop's panels). Columns shipped in that window are gone; the host reports the id and Render resets head to 0 so the ring restarts honestly from a blank texture instead of desyncing around a gap.
func (*HeatmapScroll) ResetTotalStats ¶
func (inst *HeatmapScroll) ResetTotalStats()
ResetTotalStats zeroes the running stats counter. Does not affect already-mapped columns.
func (*HeatmapScroll) SetConfig ¶
func (inst *HeatmapScroll) SetConfig(cfg *colormap.Config)
SetConfig replaces the colormap configuration used by subsequent PushColumn calls. Does NOT re-map already-pushed columns: the live gradient-swap path described in ADR-0058 SD1 requires retaining the original f32 samples, which this wrapper does not do yet. If you need that today, Release and re-push from your retained source.
func (*HeatmapScroll) SetDisplaySize ¶
func (inst *HeatmapScroll) SetDisplaySize(widthPx, heightPx float32)
SetDisplaySize overrides the rendered pixel rect independently of the slot count: 0 along an axis keeps the historical slot-count default (1 slot = 1 px); a positive value stretches the texture to that pixel size via egui's painter sampler. Useful when the caller wants the heatmap to grow with its enclosing panel without re-allocating the underlying ring texture.
Hover (row, col) coordinates are converted back to slot units in the Rust widget, so display-size changes do not shift the ring readout. Takes effect on the next Render call.
func (*HeatmapScroll) SetFilter ¶
func (inst *HeatmapScroll) SetFilter(f Filter)
SetFilter selects GPU texture sampling (see ADR-0058 SD3). Takes effect on the next Render call.
func (*HeatmapScroll) SetOrientation ¶
func (inst *HeatmapScroll) SetOrientation(o Orientation)
SetOrientation selects one of the four scroll directions. Takes effect on the next Render call.
func (*HeatmapScroll) Size ¶
func (inst *HeatmapScroll) Size() (widthSlots, heightSlots uint32)
Size returns the widget's ring dimensions as given to New.
func (*HeatmapScroll) TotalStats ¶
func (inst *HeatmapScroll) TotalStats() colormap.ColumnStats
TotalStats returns the cumulative bad / under / over counts across all PushColumn calls since construction (or since ResetTotalStats).
type Orientation ¶
type Orientation c.OrientationE
Orientation mirrors c.OrientationE so callers of HeatmapScroll don't need a second import for the scroll-direction enum. A named type (not an alias) per CODINGSTANDARDS CS008; values cross to the binding layer via the uint8 conversion in Render.
const ScrollDown Orientation = Orientation(c.OrientationScrollDownE)
ScrollDown — append top, scroll down; classical RF waterfall. Alias for c.OrientationScrollDownE.
const ScrollLeft Orientation = Orientation(c.OrientationScrollLeftE)
ScrollLeft — append right, scroll left; classical audio spectrogram. Alias for c.OrientationScrollLeftE. See ADR-0058 SD8.
const ScrollRight Orientation = Orientation(c.OrientationScrollRightE)
ScrollRight — append left, scroll right; mirror of ScrollLeft. Alias for c.OrientationScrollRightE.
const ScrollUp Orientation = Orientation(c.OrientationScrollUpE)
ScrollUp — append bottom, scroll up; vertical sibling of ScrollLeft. Alias for c.OrientationScrollUpE.