Interactive Answers
Dot Histogram
A distribution as stacked dots — every sample visible, median and p95 marked, samples past a limit such as a timeout flagged.
2 variantsMIT
Preview
Response time
Last 320 runs · timeout 15 s
320 runs
Median 4.4sp95 15.3stimed out 22 · 6.9%1 dot = 2 runs
Installation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/dot-histogram.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { DotHistogram } from "@/components/ui/dot-histogram";
// Show how response times spread when the agent reports on recent runs.
export function LatencyAnswer({ runs }: { runs: Run[] }) {
return (
<DotHistogram
title="Response time"
subtitle={`Last ${runs.length} runs · timeout 15 s`}
values={runs.map((r) => r.seconds)}
threshold={15}
thresholdLabel="timed out"
unit="runs"
format={(v) => `${+v.toFixed(1)}s`}
onSelect={(bin) => openRuns(bin.from, bin.to)}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| values* | number[] | — | Raw samples. The component bins them and works out the median and p95. |
| title* | string | — | Header title. |
| subtitle | string | — | Secondary line under the title. |
| threshold | number | — | Samples at or above it are drawn red and counted in the footer. |
| thresholdLabel | string | "over limit" | What a flagged sample means, e.g. “timed out”. |
| bins | number | 48 | Number of columns. |
| unit | string | "samples" | Plural name for one sample, used in the header, tooltip and footer. |
| format | (value: number) => string | — | Formats axis labels, the median, p95 and tooltip ranges. |
| onSelect | (bin: DotHistogramBin) => void | — | Called when a column is hovered or reached with the arrow keys. |
| className | string | — | Extra classes for the root element. |
type DotHistogramBin = { from: number; to: number; count: number; flagged: boolean };
// Tall columns switch to one dot per group ("1 dot = 3 runs") so the chart keeps its height.
// Keyboard: focus the chart, then ← → Home End move between filled columns, Esc clears.