Histogram
Distribution of a single measure (request latency, order values, file sizes). Pass raw values to have them binned automatically.
Component behavior
Histogram displays the distribution of numeric samples. The x-axis divides values into bins. Bar heights show sample counts.
- Distributions of latency, order values, file sizes, or session lengths.
- Inspection of skew, multiple modes, and percentile placement.
- Thresholds or percentile markers within a distribution.
BarChart: the x-axis consists of named categories.
LineChart: the task requires changes over time.
Heatmap: the distribution must be grouped by a second dimension, such as latency by hour.
ScatterPlot: two measures per sample must be compared.
Props
Pass either values (a raw sample, binned for you) or bins (already aggregated). A HistogramBin is { from, to, count }, with from inclusive and to exclusive except on the last bin. Automatic binning uses the Freedman–Diaconis rule (width from the interquartile range and sample size, capped at 60 bins), falling back to Sturges when the IQR is zero, and to √n for samples under twelve. The y-axis is always counts; ticks controls only that axis.
| Prop | Type | Default | Description |
|---|---|---|---|
values | number[] | — | Raw values for equal-width bins from minimum to maximum. The maximum value is included in the last bin. |
bins | HistogramBin[] | — | Pre-aggregated from, to, and count values. Takes precedence over values. |
binCount | number | — | Override the automatic bin count. Only applies when binning values; ignored when bins is supplied. |
height | number | 140 | Plot area height in pixels. The x-axis row adds to it. |
color | string | "var(--m-color-primary)" | Bar color. Bins render with a 1px gap. |
markers | HistogramMarker[] | — | Labeled vertical markers. Defaults to the warn color. Out-of-range markers are omitted. Labels must be unique. |
formatValue | (value: number) => string | — | Formats the three x-axis labels. Defaults to rounding at 100 and above, one decimal below. |
ticks | number | 4 | Y-axis tick count, including both ends. The x-axis is always exactly three labels: minimum, midpoint, maximum. |
renderTooltip | (bin: HistogramBin, index: number) => ReactNode | — | Tooltip for the hovered bin; receives the bin's edges and count. Flips to the left of the cursor past the midpoint. |
cumulative | boolean | — | Dashed overlay of the running share of the sample at or below each bin, drawn through bin centers from 0 at the floor to 100% at the top of the plot. |
Examples
Percentile markers
percentile(values, p) sorts a copy and interpolates between order statistics. Markers use the x-axis value domain. Markers outside that domain are omitted without an error.
Cumulative overlay
cumulative adds a curve showing the share of samples at or below each bin. Read the x value at the required cumulative fraction to estimate a percentile.
Pre-aggregated bins
For large datasets, aggregate bins before sending data to the browser. Passing bins skips sampling and re-binning and ignores binCount. Use equal-width bins: bars occupy equal-width slots, while markers and axis labels use the numeric domain.
Bin count changes the story
binCount overrides automatic binning. Fewer bins reduce detail; more bins expose sampling variation. Set an explicit count when bins must align with quantized data or thresholds.
import { Histogram, percentile, binValues } from "@solarius/onset";
import type { HistogramBin, HistogramMarker } from "@solarius/onset";
<Histogram
values={latencies}
markers={[
{ value: percentile(latencies, 0.5), label: "P50", color: "var(--m-color-warn)" },
{ value: percentile(latencies, 0.95), label: "P95", color: "var(--m-color-err)" },
]}
cumulative
/>
// Or bin once and reuse the result:
<Histogram bins={binValues(latencies, 20)} />