# HistogramStrip (/docs/charts/histogram-strip)

HistogramStrip answers "what does the distribution look like?". Raw observations in, ≤ 12 uniform bins out — counts
zero-anchored, never density-smoothed. Pre-aggregated counts are not supported; that's SparkBar's contract.

```tsx
<HistogramStrip
  data={Array.from({ length: 120 }, (_, i) => (i % 3 === 0 ? 40 + (i % 10) : 20 + ((i * 7) % 60)))}
  title="Response times"
  style={{ width: 220, height: 56 }}
/>
```

## Install

```tsx
import { HistogramStrip } from "@microcharts/react/histogram-strip";

<HistogramStrip data={times} title="Response times" />
```

Setup (package + stylesheet): [Quickstart](/docs/quickstart#set-up-with-an-ai-agent) or paste [`/agent-setup.md`](/agent-setup.md) into your agent.


## When to use it

- **Good for** — latency clusters in a sentence, distributions per table row.
- **Avoid for** — raw marks (RugStrip) or series over time (Sparkline).


## Variants

```tsx
const responseTimes = Array.from({ length: 120 }, (_, i) =>
  i % 3 === 0 ? 40 + (i % 10) : 20 + ((i * 7) % 60),
);

<HistogramStrip data={responseTimes} markValue={45} title="You are here" />
```

```tsx
<HistogramStrip
  data={[12000, 18000, 24000, 30000, 36000, 42000, 18000, 24000, 30000]}
  locale="de-DE"
/>
```

The accessible summary states the modal bin's edges through `format`/`locale` — under `de-DE` a value like 24000 reads
"24.000" (period as the thousands separator) instead of the English "24,000".

## Edge cases

```tsx
<HistogramStrip data={[]} title="No observations yet" />
```

```tsx
<HistogramStrip data={[4, 4, 4, 4, 4]} title="Constant" />
```

An empty series renders zero bars and an accessible name of "No data." rather than a misleading flat line. A constant
series collapses to ONE full-height bin instead of the usual up-to-12 slivers a naive equal-width binner would draw for
a zero-span domain.


## Why this default

Auto bin count is √n capped at 12 — enough shape to see skew, few enough bars to survive 60 px. All values identical
collapse to ONE bin (never twelve slivers); explicit bin counts collapse to the observation count. `markValue` marks the
bin of a value and never re-bins around it.

## Accessibility

The accessible name names the modal bin — **"120 values, most between 42.09 and 47.36."** The interactive entry roves
bins with range announcements (**"42.09 to 47.36: 26 values."**).

The interactive entry follows the shared [interaction contract](/docs/accessibility#one-interaction-contract):
arrow keys rove between units on both axes, `Home` and `End` jump to the ends, and a click, tap, `Enter` or
`Space` selects a unit — pinning its readout so it survives blur, until you select it again or press `Escape`.
On touch, a tap pins and a drag scrubs.

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `data` (required) | `number[]` | Raw observations. |
| `bins` | `number` | Bin count; auto = min(12, √n). |
| `markValue` | `number` | A VALUE whose bin gets accent. |
| `domain` | `[number, number]` | Fixed bin edges across multiples. |
| `format` | `Intl.NumberFormatOptions \| fn` | Formats the bin edges named in the summary. |
| `locale` | `string \| string[]` | BCP 47 locale(s) for the formatted bin edges. |
| `animate` | `boolean` | (interactive) Opt-in entrance motion when the chart mounts client-side — add `import "@microcharts/react/motion"` once. Inert on the server, on hydrated server HTML, and under `prefers-reduced-motion`. |

Plus the shared grammar — `data`, `domain`, `color`, `title`, `summary`, `format` — and the layout props (`width`, `height`, `className`, `style`) that every chart accepts. Interactive entries also share `animate` and `live`, and — wherever a chart has more than one navigable unit — `onActive`, `onSelect`, `selectedIndex` and `defaultSelectedIndex`; and — wherever the chart shows a hover value — `readout`. See [the shared grammar](/docs/quickstart#the-shared-grammar).
