Selkie--Widget--Heatmap

NAME

Selkie::Widget::Heatmap - Coloured grid for 2D numeric data

SYNOPSIS

use Selkie::Widget::Heatmap;
use Selkie::Sizing;

# A 4Ɨ4 grid of arbitrary numeric values. Each cell renders as a
# coloured block; colour comes from the viridis ramp by default.
my $h = Selkie::Widget::Heatmap.new(
    data => [
        [ 0.1, 0.3, 0.5, 0.7 ],
        [ 0.2, 0.4, 0.6, 0.8 ],
        [ 0.3, 0.5, 0.7, 0.9 ],
        [ 0.4, 0.6, 0.8, 1.0 ],
    ],
    sizing => Sizing.fixed(4),
);

# Custom ramp + explicit range (useful for diverging data around 0)
my $diverging = Selkie::Widget::Heatmap.new(
    data   => @correlation-matrix,
    ramp   => 'coolwarm',
    min    => -1.0,
    max    =>  1.0,
    sizing => Sizing.flex,
);

# Reactive
my $live = Selkie::Widget::Heatmap.new(
    store-path => <metrics utilization-grid>,
    sizing     => Sizing.flex,
);

DESCRIPTION

A heatmap renders a 2D grid of numeric values as a grid of coloured cells. Each cell is filled with ā–ˆ (full block); the foreground colour comes from a ramp lookup keyed by the cell's value normalised to [0, 1].

Colour ramps

Default ramp is viridis (perceptually uniform, colourblind-safe). Other ramps from Selkie::Plot::Palette:

  • viridis — purple → blue → teal → green → yellow

  • magma — black → purple → magenta → cream

  • plasma — deep blue → magenta → orange

  • coolwarm — diverging blue → white → red, useful for signed data centred on zero

  • grayscale — five steps of grey, accessibility fallback

Override per-widget with :ramp<name>.

Range

By default the range [min, max] auto-derives from the data extent. Pass explicit :min / :max to fix it (essential for the diverging coolwarm ramp, where 0 needs to map to the white midpoint regardless of data extent).

NaN values render with the text-dim theme slot so missing data is visually distinct from in-range zero.

Cell aspect ratio

Terminal cells are taller than they are wide (~2:1). Heatmaps don't compensate for this — each data cell renders as one terminal cell, so a 10Ɨ10 data grid looks tall and narrow on screen. To get a near-square render, double the columns (repeat each cell horizontally) by pre-processing the data.

EXAMPLES

A 2D function evaluation

my @grid = (^16).map: -> $r {
    (^16).map: -> $c {
        my $x = ($c - 8) / 8;
        my $y = ($r - 8) / 8;
        sin(sqrt($x*$x + $y*$y) * 5);
    }
};

my $heatmap = Selkie::Widget::Heatmap.new(
    data   => @grid,
    ramp   => 'viridis',
    sizing => Sizing.fixed(16),
);

A correlation matrix with a diverging ramp

Diverging ramps map 0 to white in the middle. Pin the range to keep the centre stable as data updates:

my $heatmap = Selkie::Widget::Heatmap.new(
    data   => @corr-matrix,         # values in [-1, 1]
    ramp   => 'coolwarm',
    min    => -1,
    max    =>  1,
    sizing => Sizing.fixed(@corr-matrix.elems),
);

Custom palette via theme override

The ramp comes from Selkie::Plot::Palette. To use a colour ramp not included in Palette, render a custom heatmap by subclassing this widget — or open a feature request to add the ramp to Palette upstream.

SEE ALSO

has Positional @.data

2D array of numeric values. Each row is one row of cells.

has Positional[Str] @.store-path

Reactive store path. Mutually exclusive with data.

has Str $.ramp

Named colour ramp from Selkie::Plot::Palette. Default: viridis.

has Real $.min

Optional explicit lower bound. Auto-derived from data when unset.

has Real $.max

Optional explicit upper bound. Auto-derived from data when unset.

has Str $.empty-message

Message rendered when there is no data. This is the expected startup state for monitoring dashboards. Set to the empty string to suppress.

method set-data

method set-data(
    @new
) returns Mu

Replace the heatmap's grid with a new array-of-rows. Each row is realised into an Array up-front because callers often pass Seqs from .map chains, and a long-lived TUI re-renders every frame — an exhausted Seq would produce an empty grid on subsequent renders. Throws when constructed in :store-path mode.

method on-store-attached

method on-store-attached(
    $store
) returns Mu

Hook called when the widget is attached to a store. Subscribes to :store-path so the heatmap re-renders on state changes. No-op in :data mode.

Selkie v0.10.0

High-level TUI framework built on Notcurses

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

Notcurses::Native:ver<0.4.0+>:auth<zef:apogee>

Test Dependencies

Provides

  • Selkie
  • Selkie::App
  • Selkie::App::Internal::Dispatch
  • Selkie::App::Internal::ErrorLog
  • Selkie::App::Internal::FocusTree
  • Selkie::App::Internal::HitTest
  • Selkie::App::Internal::IdleBudget
  • Selkie::App::Internal::OverlayTree
  • Selkie::App::Internal::RenderLoop
  • Selkie::App::Internal::ScreenModalLifecycle
  • Selkie::App::Internal::Terminal
  • Selkie::App::Internal::TerminalSequences
  • Selkie::Container
  • Selkie::EffectiveBounds
  • Selkie::Event
  • Selkie::Layout::Allocate
  • Selkie::Layout::HBox
  • Selkie::Layout::Split
  • Selkie::Layout::VBox
  • Selkie::Plot::Palette
  • Selkie::Plot::Scaler
  • Selkie::Plot::Ticks
  • Selkie::ScreenManager
  • Selkie::Sizing
  • Selkie::Store
  • Selkie::Style
  • Selkie::Test::Focus
  • Selkie::Test::Keys
  • Selkie::Test::Snapshot
  • Selkie::Test::Snapshot::Harness
  • Selkie::Test::Store
  • Selkie::Test::Supply
  • Selkie::Test::Tree
  • Selkie::Theme
  • Selkie::Trace
  • Selkie::Tree
  • Selkie::Widget
  • Selkie::Widget::Axis
  • Selkie::Widget::BarChart
  • Selkie::Widget::Border
  • Selkie::Widget::Button
  • Selkie::Widget::CardList
  • Selkie::Widget::Checkbox
  • Selkie::Widget::CommandPalette
  • Selkie::Widget::ConfirmModal
  • Selkie::Widget::FileBrowser
  • Selkie::Widget::FocusableByDefault
  • Selkie::Widget::Heatmap
  • Selkie::Widget::HelpOverlay
  • Selkie::Widget::Histogram
  • Selkie::Widget::Image
  • Selkie::Widget::Legend
  • Selkie::Widget::LineChart
  • Selkie::Widget::ListView
  • Selkie::Widget::Modal
  • Selkie::Widget::MultiLineInput
  • Selkie::Widget::PasswordStrength
  • Selkie::Widget::Plot
  • Selkie::Widget::ProgressBar
  • Selkie::Widget::RadioGroup
  • Selkie::Widget::RichText
  • Selkie::Widget::RichText::Span
  • Selkie::Widget::ScatterPlot
  • Selkie::Widget::ScrollView
  • Selkie::Widget::Select
  • Selkie::Widget::Sparkline
  • Selkie::Widget::Spinner
  • Selkie::Widget::TabBar
  • Selkie::Widget::Table
  • Selkie::Widget::Text
  • Selkie::Widget::TextInput
  • Selkie::Widget::TextInput::HighlightSpan
  • Selkie::Widget::TextStream
  • Selkie::Widget::Toast
  • Selkie::Widget::ViewportedCardList

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.