Histogram & Density

Pro

Distribution of a sample: five bin-width rules, count / density / cumulative measures, an optional kernel density curve, a rug, and mean / median / quantile markers. The rule that shaped the picture is always stated. Pure SVG.

</>sv-histogram-chart charthistogramdistributiondensitystatistics
import { SvHistogramChartComponent } from '@styloviz-pro/charts';

Demo & usage

Basic usage

Pro

Usage example — open the gallery for the full interactive demo.

Pro

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Pin the bin count

Pro

Density curve and rug

Pro

Cumulative distribution

Pro

Weighted samples

Pro

Mean, median and P90 markers

Pro

When to use

  • Seeing the SHAPE of one numeric variable — where the mass sits, whether it is skewed, whether it has two modes.
  • Answering "what share came in under X" with the cumulative measure.
  • For comparing distributions across several groups, a Box Plot puts them side by side; for individual points, a Scatter Plot.

Async states

  • loading
  • empty
  • error
  • retry

Inputs

NameTypeDefaultDescription
loadingbooleanfalseTrue while the samples are being fetched.
errorSvDataError | string | nullnullLoad failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`.
emptyMessagestring'No samples to plot'Copy for the no-data state.
filteredbooleanfalseTrue when the emptiness is caused by a filter rather than an empty set.
samplesreadonly SvHistogramSample[][]The readings to bin. Each may carry a `weight`.
binRuleSvBinRule'freedman-diaconis'How the bin width is chosen. Freedman–Diaconis is the default because it is the most robust to outliers: it scales with the interquartile range rather than the full spread, so one extreme reading does not widen every bin. The rule is always named under the plot — a histogram's shape is a function of its bin width as much as of its data, so an unstated rule leaves the picture unfalsifiable.
binCountnumber10Bin count, used when `binRule` is `'fixed'`.
binEdgesreadonly number[][]Explicit bin edges, bypassing `binRule`. Widths may differ. Repeated edges are merged; fewer than two distinct numbers fall back to `binRule`, and the note under the plot says so.
measureSvHistogramMeasure'count'What the bars encode. `count` is the plain frequency. `density` is `count ÷ bin width`, which is the only honest height when the bins differ in width. `cumulative` draws the running total, turning the chart into a distribution function.
showDensitybooleanfalseOverlay a Gaussian kernel density estimate. Off by default: the curve is a MODEL rather than the data, and its bandwidth smooths a real bimodal distribution into one mound as easily as it reveals one. When on, the bandwidth is named under the plot.
bandwidthnumber0Kernel bandwidth. Falls back to Silverman's rule of thumb.
showRugbooleanfalseDraw a tick per sample along the baseline.
showMeanbooleanfalseMark the mean with a labelled reference line. Weighted when the samples carry weights, like the bars.
showMedianbooleanfalseMark the median with a labelled reference line. Same type-7 quantile rule as the box plot, weighted when the samples carry weights.
quantilesreadonly number[][]Quantiles to mark, as probabilities in `[0, 1]` — `[0.9, 0.99]` draws P90 and P99. Values outside the range and duplicates are ignored.
widthnumber640Plot width in pixels.
heightnumber320Plot height in pixels.
colorstring''Bar fill. Falls back to the shared chart palette.
valueLabelstring''Label for the value axis, e.g. a unit.
titlestring''Chart title, rendered above the plot.
ariaLabelstring''Accessible name override. Falls back to a generated summary.
customClassstring''Extra CSS classes applied to the root wrapper.

Outputs

EventPayload typeDescription
retryvoidThe host should re-run the failed load.
binHoverSvHistogramBinEventEmitted when a bin is hovered or keyboard-focused.
binSelectSvHistogramBinEventEmitted when a bin is clicked or activated with Enter/Space.

Wire it to your API

This component is headless about transport: it renders what you give it and reports what the user asks for. Nothing below requires @styloviz/data — drive it from whatever you already use.

Template

Pro

Bound to the names this component actually exposes.

Host class

Pro

Drive the three async inputs from your own fetch.

  • This component does not emit a query, so it renders what you give it. Fetch on your own trigger and bind `samples`, `loading` and `error`.
  • Set `filtered` when a search or filter is active. It is the difference between "you have no orders" and "no orders match this filter" — telling a customer with 4,000 orders the first one reads as a bug.
  • Normalize failures with `toSvDataError()` from `@styloviz/core`. It derives `retryable` from the status, so a 404 does not get a "Try again" button that can only fail again.

Full walkthrough: Connecting to a backend.

Customization & theming

  • Five bin-width rules, or explicit edges of your own — an edge is widened rather than lose a sample outside it, because a count that does not add up is the one thing a histogram must never do. Repeated edges are merged; an edge list with fewer than two distinct numbers falls back to the bin rule, and the note under the plot says so rather than showing an empty chart.
  • Count, density or cumulative measures.
  • Optional kernel density overlay with a bandwidth override — weighted the same way as the bars when the samples carry weights — and an optional rug of individual readings.
  • Statistical annotation: `showMean`, `showMedian` and `quantiles` (probabilities, e.g. `[0.9, 0.99]`) draw labelled reference lines, weighted like the bars. Off by default.
  • Bar colour, plot size, and a unit label carried into the axis and the table.

Best practices

  • Do: Treat the bin rule as part of the finding, not a display setting. The same samples at 8 bins and at 60 are a smooth mound and a spiky comb, and neither is wrong — which is why the rule is named under every plot and cannot be hidden. Quote it when you quote the shape.
  • Do: Use the density measure whenever the bins are not all the same width. Bar AREA is what a reader takes off a histogram, so drawing counts on unequal bins makes a wider bin look fuller for the same number of samples. The chart says so when you do it; density is the fix it names.
  • Don't: Do not read the density curve as data. It is a kernel density estimate — a model — and its bandwidth smooths a genuinely bimodal distribution into one mound as easily as it reveals one. It is drawn dashed for that reason, and its bandwidth is stated.
  • Tip: Freedman–Diaconis is the default because it scales with the interquartile range rather than the full spread, so a single extreme reading does not widen every bin. It falls back to the square-root rule when the interquartile range is zero, which a heavily-moded sample produces — and the note under the plot then names the rule that actually ran and why, not the one you asked for.

Accessibility

  • Every bar is a focusable `role="button"` named with its range, count and share. Bar height is the only place a count exists in the drawing and no axis is precise enough to read one off, so those figures are in the name rather than left to be estimated.
  • The plot is ONE tab stop: Tab lands on a bar, the arrow keys walk the others (Home / End jump to the ends, no wrap), Enter or Space selects. A tab stop per bar was up to 200 Tab presses to get past one chart.
  • Mean, median and quantile markers are told apart by dash pattern and label, never by colour alone, and every marked figure is stated in the chart's accessible name.
  • `sv-data-summary-table` publishes every bin's range, count, share and running total — the last of which the plain measure never draws at all.
  • The rug is deliberately not focusable: every reading it marks is already counted in a bar that is, so making each tick a tab stop would add hundreds of stops that say nothing new.
  • What shaped the picture is stated in the rendered output: the bin rule that actually ran (including a fallback, or your own edges), the sample count, unequal widths drawn at count, the density bandwidth, and any reading that could not be binned or whose weight could not be used.

Feedback on Histogram & Density

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.