heatmapscroll

package
v0.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 4 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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

type Filter c.FilterE

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.

ScrollDown — append top, scroll down; classical RF waterfall. Alias for c.OrientationScrollDownE.

ScrollLeft — append right, scroll left; classical audio spectrogram. Alias for c.OrientationScrollLeftE. See ADR-0058 SD8.

ScrollRight — append left, scroll right; mirror of ScrollLeft. Alias for c.OrientationScrollRightE.

ScrollUp — append bottom, scroll up; vertical sibling of ScrollLeft. Alias for c.OrientationScrollUpE.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL