Charts
Histogram Chart
A numeric distribution grouped into adjacent equal-width ranges.
When to use it: Use it to show shape, concentration, spread, and outliers in continuous observations.
Example
import {
ChartDescription,
ChartTable,
ChartTitle,
ChartTooltip,
HistogramChart,
HistogramChartBin,
HistogramChartPlot,
} from "@comp0/react";
const responseTimes = [180, 210, 230, 250, 270, 290, 310, 340, 380, 420, 480, 620] as const;
const formatMilliseconds = (value: number) => `${Math.round(value)} ms`;
export function Example() {
return (
<HistogramChart
values={responseTimes}
valueLabel="Response time"
frequencyLabel="Requests"
formatValue={formatMilliseconds}
className="w-full max-w-2xl rounded-lg has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-4 has-[:focus-visible]:outline-teal-600 dark:has-[:focus-visible]:outline-teal-400"
>
<ChartTitle className="text-base font-semibold text-zinc-950 dark:text-zinc-50">
API response-time distribution
</ChartTitle>
<HistogramChartPlot
aria-label="Histogram showing API response-time distribution"
binCount={5}
className="mx-auto mt-5 aspect-square w-full max-w-md overflow-visible"
>
{(bin) => (
<HistogramChartBin key={bin.index} bin={bin} className="group outline-none">
<rect
x={bin.x}
y={bin.y}
width={bin.width}
height={bin.height}
className="fill-teal-600 stroke-white group-data-active:stroke-zinc-950 dark:fill-teal-400 dark:stroke-zinc-950 dark:group-data-active:stroke-white"
strokeWidth="1"
vectorEffect="non-scaling-stroke"
/>
</HistogramChartBin>
)}
</HistogramChartPlot>
<ChartDescription className="mt-5 text-sm text-zinc-600 dark:text-zinc-400">
Most sampled requests completed below 350 milliseconds, with one slower outlier.
</ChartDescription>
<ChartTable className="mt-4 w-full border-collapse text-left text-sm [&_td]:border-t [&_td]:border-zinc-200 [&_td]:py-2 [&_th]:border-zinc-200 [&_th]:py-2 dark:[&_td]:border-zinc-800 dark:[&_th]:border-zinc-800 [&_caption]:sr-only" />
<ChartTooltip className="pointer-events-none z-50 rounded-md bg-zinc-950 px-2 py-1 text-sm text-white shadow-lg dark:bg-zinc-50 dark:text-zinc-950" />
</HistogramChart>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
HistogramChart
Native figure sharing observations, labels, and value formatting. Owns a DOM element.
ChartTitle
Native figcaption that visibly names the figure. Owns a DOM element.
HistogramChartPlot / HistogramChartBin
Adjacent SVG bins positioned against value and frequency axes. Owns a DOM element.
ChartDescription
Visible prose summarizing shape and outliers. Owns a DOM element.
ChartTable
Native table that renders a complete default from the chart data: a caption from the ChartTitle text or axis labels, column headers, and one row per value. Pass children for a custom body. Owns a DOM element.
ChartTooltipOptional
Optional floating range and count shown on hover or focus. Owns a DOM element.
Step by step
- 1
Add the main part
Start HistogramChart with finite observations and visible value and frequency labels.
- 2
Add the supporting parts
Choose a meaningful binCount and wrap each rendered range in HistogramChartBin.
- 3
Make the behavior clear
Describe the distribution and keep the underlying observations or bin counts in a native ChartTable.
Exampletsx <HistogramChart values={responseTimes} valueLabel="Response time" frequencyLabel="Requests"> <ChartTitle>Response-time distribution</ChartTitle> <HistogramChartPlot aria-label="Histogram of response times"> {(bin) => ( <HistogramChartBin bin={bin}> <rect x={bin.x} y={bin.y} width={bin.width} height={bin.height} /> </HistogramChartBin> )} </HistogramChartPlot> <ChartTable /> <ChartTooltip /> </HistogramChart>;
Keyboard
- ⇥
- Enters the chart at its current bin and leaves with one more Tab.
- ←→
- Moves between adjacent bins.
- HomeEnd
- Moves to the first or last bin.
- Esc
- Dismisses an open ChartTooltip.
Forms and accessibility
Charts are descriptive content and do not create form values.
Accessibility checklist
- Name both the measured value axis and the frequency axis.
- Choose bins that communicate the distribution honestly; changing bin count can materially change its appearance.
- Wrap each custom bar in HistogramChartBin so its range and count are keyboard reachable.
- Keep the underlying observations or exact bin counts available in a native table.
- Adjacent bins should remain visibly separable in every color scheme.
API reference
import { ChartDescription, ChartTable, ChartTitle, ChartTooltip, HistogramChart, HistogramChartBin, HistogramChartPlot } from "@comp0/react";HistogramChart
DOM elementNative figure sharing observations, labels, and value formatting.
| Prop | Type | Description |
|---|---|---|
values | readonly number[] | Finite observations grouped into ranges by HistogramChartPlot. |
valueLabel | string | Visible headings for values and counts. |
frequencyLabel | string | Visible headings for values and counts. |
formatValue | (value: number) => string | Formats range boundaries and horizontal ticks. |
ChartTitle
DOM elementNative figcaption that visibly names the figure.
HistogramChartPlot / HistogramChartBin
DOM elementAdjacent SVG bins positioned against value and frequency axes.
| Prop | Type | Description |
|---|---|---|
aria-label | string | Concise text alternative naming the distribution. |
binCount | number | Positive number of equal-width bins; defaults from the observation count. |
xMin | number | Optional value bounds and visible tick counts. |
xMax | number | Optional value bounds and visible tick counts. |
xTickCount | number | Optional value bounds and visible tick counts. |
yTickCount | number | Optional value bounds and visible tick counts. |
children | (bin: HistogramChartBinState) => ReactNode | Custom bin renderer receiving its range, count, and geometry. |
bin | HistogramChartBinState | Bin state passed from the plot to HistogramChartBin. |
ChartDescription
DOM elementVisible prose summarizing shape and outliers.
ChartTable
DOM elementNative table that renders a complete default from the chart data: a caption from the ChartTitle text or axis labels, column headers, and one row per value. Pass children for a custom body.
ChartTooltip
OptionalDOM elementOptional floating range and count shown on hover or focus.
| Prop | Type | Description |
|---|---|---|
placement | PopoverPlacement | Side of the active mark; defaults to "top". |
offset | number | Distance from the active mark; defaults to eight pixels. |
children | ReactNode | (details: ChartValueDetails) => ReactNode | Custom content receiving the active bin's formatted details. |
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
HistogramChartPlot / HistogramChartBin
| Style hook | Meaning |
|---|---|
[data-min] | The inclusive lower bound of this bin. |
[data-max] | The upper bound of this bin. |
[data-count] | The number of observations in this bin. |
[data-active] | The bin currently reached by pointer or keyboard. |
ChartTooltip
| Style hook | Meaning |
|---|---|
[data-open] | A value tooltip is visible. |