Selkie--Widget--Histogram

NAME

Selkie::Widget::Histogram - Bin a numeric series and render it as a BarChart

SYNOPSIS

use Selkie::Widget::Histogram;
use Selkie::Sizing;

# Bin 1000 random samples into 10 bins
my @samples = (1..1000).map: { rand * 100 };
my $h = Selkie::Widget::Histogram.new(
    values => @samples,
    bins   => 10,
    sizing => Sizing.flex,
);

# Custom bin edges instead of equal-width bins
my $edges = Selkie::Widget::Histogram.new(
    values    => @latencies-ms,
    bin-edges => [0, 10, 50, 100, 500, 1000, 5000],
    sizing    => Sizing.flex,
);

DESCRIPTION

A histogram is a categorical view of a numeric distribution. This widget bins a list of numeric values into intervals and delegates rendering to Selkie::Widget::BarChart. Each bin becomes a bar labelled by its lower edge.

Bin convention

Intervals are left-closed, right-open, with the final bin closed-closed so the maximum sample is always counted. For bin edges [0, 10, 20, 30]:

  • Bin 1: [0, 10) — values 0 ≤ v < 10

  • Bin 2: [10, 20)

  • Bin 3: [20, 30] — values 20 ≤ v ≤ 30 (inclusive)

This matches numpy / R / matplotlib defaults.

Modes

Two ways to specify the bins:

  • Equal-width — pass :bins(N). The widget computes N equal-width bins spanning [min, max] of the data.

  • Explicit edges — pass :bin-edges([...]). The widget uses your edges directly. edges.elems = bin count + 1.

The two are mutually exclusive. :bins is convenient; :bin-edges is for non-uniform binning (log-scale latency, age brackets, etc.).

EXAMPLES

Distribution of request latencies

my @latencies = $request-log.map: *.<duration-ms>;
my $h = Selkie::Widget::Histogram.new(
    values => @latencies,
    bins   => 20,
    sizing => Sizing.flex,
);

Non-uniform bins for skewed data

Latencies cluster near zero with a long tail. Equal bins waste most of the chart on near-zero values. Custom edges let you focus on the distribution where it matters:

my $h = Selkie::Widget::Histogram.new(
    values    => @latencies,
    bin-edges => [0, 5, 10, 25, 50, 100, 250, 500, 1000, 5000],
    sizing    => Sizing.flex,
);

Reactive — auto-rebin when the source data changes

# Histogram doesn't bind to a store directly; instead, subscribe in
# app code and call set-values when the source updates.
$store.subscribe-with-callback(
    'latencies-hist',
    -> $s { $s.get-in('metrics', 'latency-samples') // [] },
    -> @samples { $hist.set-values(@samples) },
    $hist,
);

SEE ALSO

has Positional[Real] @.values

Numeric values to bin.

has UInt $.bins

Equal-width bin count. Mutually exclusive with bin-edges.

has Positional[Real] @.bin-edges

Explicit bin edges, ascending. bin-edges.elems = bin count + 1. Mutually exclusive with bins.

method set-values

method set-values(
    @new
) returns Mu

Replace the value list and re-bin. The chart re-renders automatically.

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.