Histogram
Shows a numeric distribution using explicit bins and an accessible frequency table.
← All chart guides · Framework setup · Native counterparts
See it and copy it
Framework example
Explore the live chart, then open its code for Astro, React, or Elements.
Most requests finish in under 500 ms
1,180 requests · Response time (ms) · Last 24 hours
1 series, 10 points. Values range from 11 to 302.
Requests
View chart data
| Category | Start | End | Requests |
|---|---|---|---|
| 0–100 | 0 | 100 | 18 |
| 100–200 | 100 | 200 | 96 |
| 200–300 | 200 | 300 | 218 |
| 300–400 | 300 | 400 | 302 |
| 400–500 | 400 | 500 | 244 |
| 500–600 | 500 | 600 | 146 |
| 600–700 | 600 | 700 | 82 |
| 700–800 | 700 | 800 | 42 |
| 800–900 | 800 | 900 | 21 |
| 900–1000 | 900 | 1000 | 11 |
View Histogram code
Framework usage
Switch targets to compare the adapter code. This live preview runs the Astro example. React and Elements use their own behavior APIs; complete the matching framework setup before copying an example.---
import { Histogram } from '@santi020k/lumen-astro'
const bins = [18, 96, 218, 302, 244, 146, 82, 42, 21, 11].map((count, index) => ({
start: index * 100,
end: (index + 1) * 100,
count
}))
---
<Histogram
aria-label="Request count by response time in milliseconds"
heading="Most requests finish in under 500 ms"
description="1,180 requests · Response time (ms) · Last 24 hours"
caption="Equal 100 ms bins reveal a long tail beyond the 300–400 ms peak. Illustrative data; bin counts are calculated by the application."
valueLabel="Requests"
{bins}
/>import { Histogram } from '@santi020k/lumen-react'
const bins = [18, 96, 218, 302, 244, 146, 82, 42, 21, 11].map((count, index) => ({
start: index * 100,
end: (index + 1) * 100,
count
}))
export const Example = () => (
<>
<Histogram
aria-label="Request count by response time in milliseconds"
heading="Most requests finish in under 500 ms"
description="1,180 requests · Response time (ms) · Last 24 hours"
caption="Equal 100 ms bins reveal a long tail beyond the 300–400 ms peak. Illustrative data; bin counts are calculated by the application."
valueLabel="Requests"
bins={bins}
/>
</>
)<script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements(['Histogram'])
</script>
<lumen-histogram id="example-histogram"
aria-label="Request count by response time in milliseconds"
heading="Most requests finish in under 500 ms"
description="1,180 requests · Response time (ms) · Last 24 hours"
caption="Equal 100 ms bins reveal a long tail beyond the 300–400 ms peak. Illustrative data; bin counts are calculated by the application."
value-label="Requests"></lumen-histogram>
<script type="module">
"use strict";
const bins = [18, 96, 218, 302, 244, 146, 82, 42, 21, 11].map((count, index) => ({
start: index * 100,
end: (index + 1) * 100,
count
}));
const chart = document.getElementById('example-histogram')
chart?.setAttribute('bins', JSON.stringify(bins))
</script>When to use Histogram
Use for a continuous measure such as response time, order value, or duration after your application groups observations into bins.
- In count mode, height represents observations in a bin. In density mode, area represents count, so a wider bin does not exaggerate its concentration.
- Use formatBoundary for the measured axis and formatValue for frequency. The table retains raw counts alongside the plotted frequency.
Prepare the data
import type { LumenHistogramBin } from '@santi020k/lumen-core'
const bins = [
{ start: 0, end: 100, count: 8 },
{ start: 100, end: 200, count: 24 },
{ start: 200, end: 300, count: 42 }
] satisfies readonly LumenHistogramBin[]- The application owns binning. Provide finite start/end boundaries with start below end and a finite, nonnegative count.
- Bins are sorted by start. They must not overlap; gaps are allowed and keep their numeric spacing.
- The default frequency="count" requires equal-width bins. Use frequency="density" for unequal widths; density is count divided by bin width.
Avoid misleading comparisons
- Bin width changes the apparent shape. Use the same boundaries when comparing populations and explain your binning convention.
- Density here is count per unit of width, not a probability density normalized to a total area of one.
Choose your target
Add this component
Choose the package for your runtime. All adapters share the Lumen stylesheet. Use the matching registry command when you want a local wrapper for that framework.
pnpm add @santi020k/lumen-astropnpm add @santi020k/lumen-astrolumen add Histogramlumen add Histogrampnpm add @santi020k/lumen-reactpnpm add @santi020k/lumen-reactlumen add Histogram --target reactlumen add Histogram --target reactpnpm add @santi020k/lumen-elementspnpm add @santi020k/lumen-elementslumen add Histogram --target elementslumen add Histogram --target elementsAPI reference
Lumen-specific props and runtime attributes for the Astro primitive. Use the framework differences above and the copyable examples for React composition and Elements attributes; the public adapter types define their supported contracts.
| Attribute | Values | Default | Description |
|---|---|---|---|
| bins | LumenHistogramBin[] | required | Supplies non-overlapping numeric start/end boundaries and nonnegative counts. The application owns binning. |
| frequency | "count" | "density" | "count" | Density divides count by bin width. Unequal-width bins require density. |
| formatBoundary, formatValue | formatter functions | String | Formats numeric boundaries and the plotted frequency. |
| valueLabel, labels | string, Partial<LumenChartLabels> | localized defaults | Labels the measure and the accessible data table. |
| showTable | boolean | true | Retains raw bin counts alongside the plotted frequency. |
| class, className | string | "" | Merges custom classes with the generated ui-* root classes. |
| ...native attributes | HTML attributes | - | Forwards standard attributes to the root element unless the component consumes them. |