Skip to main content

<BarChart>

component@pond-ts/chartssource

A bar / histogram draw layer. In its simplest form, one rectangle per event spanning the key's [begin, end] from the axis baseline to a numeric column's value (see below). It also draws stacked bars (a group-by dimension → segments, columns / a Map series / bins) and horizontal bars (orientation='horizontal', bins on the y axis) — first-class histogram support. Registers into the enclosing Layers and renders nothing to the DOM; the row draws it.

Data sources. A time / value TimeSeries or ValueSeries (column), a wide series or bins array (columns), or a Map<group, TimeSeries> (column) — the last three stack. Every shape composes from pond's own aggregation (aggregate / byColumn / partitionBy); the histogram guide has the recipes.

Baseline (single, vertical). Bars rest on the zero line when the axis domain spans zero, or on the axis floor when an explicit <YAxis min> sits above zero (see resolveBarBaseline).

Baseline (stacked). A stack is cumulative from value 0 — the segments sum upward from the zero line, so its value axis must include 0. The auto-fit guarantees this: stackValueExtent always returns [0, maxTotal]. An explicit <YAxis min> above 0 is therefore unsupported for a stack — it would hide the bottom of the cumulative column; only the portion above the floor draws (clipped cleanly at the plot floor, as any bar below an explicit floor is). Segment values are assumed non-negative (a negative or zero segment is skipped — diverging stacks are out of scope).

Interaction (opt-in via id). Hover lights the bar / segment under the cursor (hit-tested by pixel rect, so it works in both orientations); click selects it (outlined). A stacked segment's identity is (id, key = bin begin, label = group). Both channels are controllable from outside via the container (selected/onSelect, hovered/onHover). The in-chart flag/crosshair value cursor is single-series-vertical only.

<Layers>
  <BarChart series={hourlyVolume} column="count" />
  <BarChart series={byHost} column="n" colors={{ web1: '#…' }} />
  <BarChart bins={powerDist} column="seconds" orientation="horizontal" ordinal />
</Layers>

Props

asstring

The single series' semantic identifier — what the data is. The theme maps it to a BarStyle (theme.bar[as] ?? theme.bar.default). Single series onlyignored (not an error) on a stacked chart, which colours its segments per group instead (see colors).

axisstring

Which <YAxis> (by its id) this layer scales against — the scale (as picks the style). Omitted ⇒ the row's default axis. For a horizontal histogram this is the bin (band) axis; for a vertical one the value axis.

binColorsreadonly (string | undefined)[]

Per-bin colours for a single-series band chart — binColors[i] fills bar i (aligned to the bins / bands in order), overriding the as/theme fill. This is the way to colour heart-rate / power zones or value bands each their own colour (the colors map above is per-group, for stacks). An undefined/short entry falls back to the theme fill. Meant for a single-series chart (column + bins, or a horizontal single series); on a multi-group stack it would tint every segment of a bin alike, so it's not the tool there.

binsreadonly BinRecordBinRecordtype@pond-ts/chartsunknown

A single bin record from byColumn — its [start, end) range plus the mapped aggregate columns (read by name via stacksFromBins). Deliberately just the start/end shape (no index signature) so pond's byColumn(...): Array<{ start, end } & ReduceResult> assigns to it structurally — the aggregate fields ride along and are read out by the reader.

[]

byColumn bin recordsArray<{ start, end, …aggregates }> from a value-band aggregation (series.byColumn('power', { width: 20 }, { seconds: … })). The value-axis alternative to series: column / columns name the aggregate field(s) to draw. Pair with ordinal for a category (band) axis.

categoriesreadonly CategoryDatumCategoryDatuminterface@pond-ts/charts{ label: string; value: number }

One category's { label, value } for a categorical bar chart — the row-read / transpose view's (columnName, cell) pair (categorical-axis RFC, Phase 1). An ordered list of these is the explicit categorical data source; Phase 2's transpose reader produces the same list from a wide series' row.

[]

Categorical data — an ordered { label, value }[], one bar per category on a first-class ordinal category x-axis (the container infers xKind:'category' and builds a band scale over the labels). The transpose view's "columns on x": each label is a category (ticker / account / zone), value its bar height. Provide exactly one of series / bins / categories; categories takes no column/columns and is vertical only (categories on x). Colour per category via binColors. (Categorical-axis RFC, Phase 1.)

colorsReadonly<Record<string, string>>

Per-group colour override for a stacked chart — { group: cssColor }. A segment resolves colors[group] ?? theme.bar[group]?.fill ?? theme.bar.default.fill, so named roles (e.g. a crit band styled in the theme) come from the theme while ad-hoc groups (five hosts) take a colour here without minting a theme role. The single styling channel still holds: this is the stack's one colour input.

columnstring

Name of the numeric value column for the bar height (single series). Provide column or columns, not both.

columnsreadonly string[]

Stacked-segment columns, bottom → top — one segment per name. Use with a wide series (e.g. pivotByGroup output) or with bins. Mutually exclusive with column, and invalid with a Map series (there the segments are the map's groups; use column).

gapnumber

Pixel gap between adjacent bars / bins — the bar's key span is inset by this total (half each side). Omitted ⇒ the theme's bar gap. A span the gap would invert collapses to the style's minWidth.

idstring

The stable series identity for selection + hover — and it gates interactivity (a bar layer is selectable/hoverable only when given an id). For a stack, a clicked / hovered segment is identified by (id, key = bin begin, label = group), so two segments in one bin don't both light up.

ordinalboolean

For bins: lay the bands out as uniform unit slots ([i, i+1]) instead of their numeric [start, end] edges — an ordinal band axis where every band reads the same width (heart-rate zones). Ignored for series.

orientationOrientationOrientationtype@pond-ts/charts'vertical' | 'horizontal'

Bar growth direction — the histogram orientation. 'vertical' bars grow up from a value baseline, bins on the x axis (the column / time-bucket look); 'horizontal' bars grow right, bins on the y axis (the band look, e.g. heart-rate zones). The stacked geometry below transposes on this alone — the StackedBarSeries data is identical for both.

Bar growth direction (the histogram orientation). Default 'vertical'.

  • 'vertical' — bars grow up from a value baseline, bins on the x axis (time buckets, value bands). The column / time-histogram look.
  • 'horizontal' — bars grow right, bins on the y axis (a band axis like heart-rate zones). Label the bands with <YAxis ticks={[{ at, label }]}>.

A 'horizontal' chart puts the value on the shared x axis, so its container's x-kind is 'value' — it cannot share a <ChartContainer> with time-series rows (each horizontal histogram stands alone). Vertical charts have no such constraint. The in-chart flag / crosshair value cursor is drawn for the single-series vertical case only; stacked and horizontal charts read out via hover / click (onHover / onSelect).

seriesTimeSeriesTimeSeriesclasspond-ts

An immutable, schema-typed, ordered collection of events — the batch layer's core primitive. A series is constructed whole from complete data and never mutated: every transform (filter, align, rollup, …) returns a new TimeSeries, so the full analytical surface can sort, scan, or index freely. Example: new TimeSeries({ name, schema, rows }).

<S> | ValueSeriesValueSeriesclasspond-ts

A value-keyed series — the closed value-axis counterpart of TimeSeries. Its key is a monotonic non-time axis (distance, cumulative work, …). Two doors in: project a TimeSeries onto one of its monotonic columns (TimeSeries.byValue(axis) — a track re-keyed by cumulative distance), or construct directly from columnar arrays (`ValueSeries.fromC…

<VS> | ReadonlyMap<string, TimeSeriesTimeSeriesclasspond-ts

An immutable, schema-typed, ordered collection of events — the batch layer's core primitive. A series is constructed whole from complete data and never mutated: every transform (filter, align, rollup, …) returns a new TimeSeries, so the full analytical surface can sort, scan, or index freely. Example: new TimeSeries({ name, schema, rows }).

<S>>

The source series. Provide exactly one of series or bins.

  • A TimeSeries (interval / timeRange-keyed is the primary form — each event's key [begin, end] is a bar's x-span; a point-keyed series derives its width from neighbour spacing) → single-series bars via column, or stacked bars from a wide series via columns.
  • A ValueSeries (series.byValue('dist')) bars against its value axis.
  • A ReadonlyMap<group, TimeSeries> — one series per stack group, all on the same bin grid, the shape series.partitionBy('host', { groups }).aggregate(seq, m).toMap() returns. Stacked bars, column names the shared value column, groups = map order.

Live charts: series.byValue(…) / .toMap() mint fresh objects each call, so an inline series={…} re-registers this layer every render — on a frequently re-rendering chart, memoize the projection (useMemo).