Skip to content
microcharts
ReferenceDecisionRateVolume

RateVolume

RateVolume plots a rate line over the volume bars behind it, so a rate is never read without its denominator.

encodes
line position (rate) over zero-anchored ghost bars (volume)
precision
high for rate, low-deliberate for volume
nodes
1 per bar + ≤ 5

RateVolume draws a precise rate line over low-precision ghost volume bars, which are the denominator. No prop removes the bars: a 4.1% conversion rate reads very differently on 38 events than on 3,800. The bars are muted and unlabeled because the question they answer is "enough?", not "how many?". Set minVolume and any period below it renders its rate point hollow, a shape cue that survives forced-colors and print.

RateVolume
interactive · 5.47 kB · static · 2.92 kB

Install

Import & usereact/rate-volume
import { RateVolume } from "@microcharts/react/rate-volume";// periods — real values under “Sample data” below<RateVolume data={periods} minVolume={50} title="Conversion rate" />
Sample data
const periods = [  { rate: 0.023, volume: 220 }, { rate: 0.025, volume: 190 }, { rate: 0.028, volume: 160 },  { rate: 0.029, volume: 130 }, { rate: 0.031, volume: 110 }, { rate: 0.034, volume: 90 },  { rate: 0.036, volume: 66 }, { rate: 0.041, volume: 38 },];
Needs package + stylesheetSet up with AI

Try it

When to use it

Use it for a conversion or error rate with its denominator, a KPI card where the rate is the headline, and spotting a big rate move on thin volume. When volume itself needs a precise read, pair a SparkBar; for a plain series use Sparkline.

Sizing

Variants

low-volume flag + step
locale

format and volumeFormat both take Intl.NumberFormatOptions and share the same locale. Under de-DE the rate label reads "4,1 %" and volumes group with a period ("3.800"), following that locale's own conventions rather than a hardcoded English format.

Edge cases

a zero-volume period breaks the line
empty data

A period with zero (or non-finite) volume renders no bar and no rate mark. A rate on zero volume is undefined regardless of the input, so the line gaps across that period instead of interpolating through one nothing was measured on, and the interactive entry announces it as "no events" rather than a rate. With no data at all, the chart renders an empty root and the accessible name says "No data."

Four homes

Accessibility

The accessible name always pairs the rate with its volume: "4.1% on 38 events (low volume); up from 2.3% across 5 periods." The interactive entry steps the periods, and its live region states the volume with every rate, announcing "no events" for a zero-volume period.

The interactive entry follows the shared 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

PropTypeNotes
data*{ rate; volume }[]Periods, oldest first — each a rate and the volume it was measured on.
minVolumenumberBelow it, the rate mark renders hollow — 'insufficient denominator'.
curve"linear" | "step"Step suits per-period aggregate rates.
volumeFormatIntl.NumberFormatOptions | (n) => stringVolume has different units than rate; formatted separately.
unitstringNoun for the volume unit in the summary (default 'events').
volumeDomain[number, number]Volume (bar) domain — defaults to [0, max], zero-anchored.
label"last" | "none"Endpoint rate in a right gutter.
animatebooleaninteractiveOpt-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.

Related charts