Distribution · Intermediate

Histogram

Distribution of raw samples with its tail and the share past a limit.

Open in playground
Use when
30 or more raw samples, such as request latency, where the tail and the share past a limit matter
Avoid when
Comparing categories (use bars), or fewer than 10 samples (a beeswarm fits better)

Try it

35

Histogram

API request latency (ms)
  • Over the SLO
  • Within
HistogramHistogram. 320 samples, median 174.5ms, p95 457ms, the tallest bin is 150ms to 200ms (86), 20 above the SLO of 400ms (6.3%).
Histogram data
50ms to 100ms31 (9.7%), cumulative 9.7%
100ms to 150ms81 (25.3%), cumulative 35%
150ms to 200ms86 (26.9%), cumulative 61.9%
200ms to 250ms45 (14.1%), cumulative 75.9%
250ms to 300ms31 (9.7%), cumulative 85.6%
300ms to 350ms16 (5%), cumulative 90.6%
350ms to 400ms10 (3.1%), cumulative 93.8%
400ms to 450ms3 (0.9%), cumulative 94.7%
450ms to 500ms3 (0.9%), cumulative 95.6%
500ms to 550ms1 (0.3%), cumulative 95.9%
550ms to 600ms0 (0%), cumulative 95.9%
600ms to 650ms0 (0%), cumulative 95.9%
650ms to 700ms2 (0.6%), cumulative 96.6%
700ms to 750ms0 (0%), cumulative 96.6%
750ms to 800ms0 (0%), cumulative 96.6%
800ms to 850ms1 (0.3%), cumulative 96.9%
850ms to 900ms1 (0.3%), cumulative 97.2%
900ms to 950ms0 (0%), cumulative 97.2%
950ms to 1,000ms0 (0%), cumulative 97.2%
1,000ms to 1,050ms1 (0.3%), cumulative 97.5%
1,050ms to 1,100ms1 (0.3%), cumulative 97.8%
1,100ms to 1,150ms0 (0%), cumulative 97.8%
1,150ms to 1,200ms0 (0%), cumulative 97.8%
1,200ms to 1,250ms2 (0.6%), cumulative 98.4%
1,250ms to 1,300ms2 (0.6%), cumulative 99.1%
1,300ms to 1,350ms0 (0%), cumulative 99.1%
1,350ms to 1,400ms0 (0%), cumulative 99.1%
1,400ms to 1,450ms3 (0.9%), cumulative 100%
1 in 16 requests misses the SLOIntermediate

Hover over the chart, or Tab in and use the arrow keys to move between items. The numbers are sample data.

Variants

Named looks for this chart. Each one is the example above with a few options or fields changed. The CLI (ztd-charts example histogram --variant <id>) and the MCP server know the same names.

Dots

API request latency (ms)
  • Over the SLO
  • Within
Sample data

Outline

API request latency (ms)
  • Over the SLO
  • Within
Sample data

Log bins

API request latency (ms)
  • Over the SLO
  • Within
Sample data

Density curve

API request latency (ms)
  • Over the SLO
  • Within
Sample data

Without percentile lines

API request latency (ms)
  • Over the SLO
  • Within
Sample data

Code

HistogramChart.tsx
import { ChartCard, HistogramChart } from "ztd-charts";

const data = [
  {"ms":844},
  {"ms":132},
  {"ms":147},
  {"ms":127},
  {"ms":256},
  {"ms":108},
  // … 314 more rows
];

export function Example() {
  return (
    <ChartCard number="35" title="Histogram" subtitle="API request latency (ms)" takeaway="1 in 16 requests misses the SLO" level="intermediate" legend={[{"label":"Over the SLO","color":"accent"},{"label":"Within","color":"neutral"}]} replay>
      <HistogramChart
        data={data}
        value="ms"
        unit="ms"
        marks={["p50","p95"]}
        threshold={{"value":400,"label":"SLO","side":"above"}}
      />
    </ChartCard>
  );
}

Props

<HistogramChart> takes these props. Rows marked Common work the same on every chart.

35 props

Prop
dataRequiredAn array of objects. Pass CSV, REST or database rows as they areobject[]
valueSample value field (raw rows)string | (d, i) => number
groupGroup field. Up to 2 groups overlapstring | (d, i) => string
x0Bin start (pre-binned rows)string | (d, i) => number
x1Bin end (pre-binned rows)string | (d, i) => number
countSamples in the bin (pre-binned rows)string | (d, i) => number
variantShape. dots stacks one dot per N samples, step draws an outline that overlays well"bars" | "dots" | "step"Default "bars"
marksPercentile lines with labels, such as ["p50", "p95", "p99"]. p50 is solid, the rest dashed. From pre-binned rows they are estimated inside the binsstring[]Default ["p50","p95"]
thresholdLimit line { value, label, side }. side "above" (default) or "below" is the bad side: its bins take the accent color and the description counts the samples past itobject
edgesBin edges, smallest first. Samples outside them are counted and reported, not drawn. Bins come from edges, then binWidth, then bins, then the Freedman-Diaconis rule (Sturges under 30 samples)number[]
binWidthBin width. Edges fall on multiples of it. Not used with lognumber
binsAbout this many bins. Widths snap to a readable stepnumber
logLog bins and axis. Every value must be above 0booleanDefault false
kdeDensity curve over the bins (raw rows only)booleanDefault false
heightCommonHeight in px. Without it, each chart picks a default that fits its widthnumber
widthCommonFixed width in px. Without it, the chart fits its parentnumber
highlightCommonItem to highlight. An index, a name, an array, or "max" | "min" | "first" | "last" | "none"number | string | (number|string)[] | "max" …
formatCommonValue format. "number" | "integer" | "percent" (values are already percents: 42 → "42%") | "ratio" (0.42 → "42%") | "compact" | "currency" (KRW for Korean locales, otherwise USD; for another currency pass Intl options with currency) | "decimal" or Intl.NumberFormat options"number" | "percent" | "compact" | …
unitCommonUnit appended to values. For example "%" or "ms"string
localeCommonLocale for numbers, dates and the text a chart writes itself (tooltips, screen reader sentences). "ko" or "ko-*" switches to Korean. Falls back to the ThemeProvider localestringDefault "en-US"
animateCommonEntry and update animationbooleanDefault true
durationCommonAnimation length (ms)number
easingCommonMotion curve"spring" | "easeOut" | "easeInOut" | "linear"Default "spring"
staggerCommonDelay between items as they enter (ms)number
reducedMotionCommon"auto" follows the OS setting. true always turns motion offanyDefault "auto"
animateOnViewCommonPlay when the chart scrolls into viewbooleanDefault true
showLabelsCommonLabels drawn on the chart (values and names)booleanDefault true
tooltipCommonShow tooltips. { template: "{label} · {value} · owner {owner}" } writes them: {label}, {value}, {series} or any other column of the row. \n starts a new line, and a line with an empty value is left outtooltipDefault true
syncIdCommonCharts with the same syncId show the hovered x together (line, area, bar, candlestick). <ChartGrid sync> sets one for every chart inside itstring
ariaLabelCommonName for screen readersstring
descriptionCommonDescription for screen readers. Built from the data when omittedstring
onHoverCommonRuns when hover or keyboard focus moves to another item(e: ChartEvent | null) => void
onClickCommonRuns on click, Enter or Space(e: ChartEvent) => void
replayKeyCommonReplays the entry animation when it changesstring | number
themeCommonChanges theme tokens for this chart onlyPartial<ChartTheme>