DualWindowMeter
DualWindowMeter overlays a fast and a slow rolling mean of one series against a target line.
- encodes
- two co-plotted rolling means vs a target line
- precision
- high
- nodes
- ≤ 6
DualWindowMeter computes two rolling means from one raw series: a thin fast window that reacts instantly, and a thick
slow window that carries the sustained read. Both run against a target line, so a momentary spike stays separable from
sustained drift. The slow trace is the thicker of the two because drift away from target matters more than a spike, and
the window sizes are part of the reading, so windows is an explicit prop. It is the general form of any noisy metric
with a compliance target.
Install
import { DualWindowMeter } from "@microcharts/react/dual-window-meter";// samples — real values under “Sample data” below<DualWindowMeter data={samples} target={-23} format={{ maximumFractionDigits: 1 }} title="Loudness"/>Sample data
const samples = Array.from( { length: 60 }, (_, i) => -22 + Math.sin(i / 3) * 4 + Math.sin(i / 11) * 2 - (i > 40 ? 2 : 0),);Try it
When to use it
Use it for loudness and LUFS metering, latency SLO compliance, and CPU-headroom compliance. For a single series use Sparkline, and reach for something else when there is no target to compare against.
Sizing
Variants
With a locale, the right-edge readings and the accessible summary follow that locale's decimal mark: the fast reading
above renders "-23,9" rather than "-23.9", and the accessible name reads "Slow window -25 vs target -23; fast -23,9."
Edge cases
Both traces share one domain, and each begins only where its window has filled. With the default windows={[3, 30]} and
the 10 samples above, the fast trace starts at sample 3 and the slow trace never appears at all; its readout shows "—"
instead of a partial-window value.
Four homes
Accessibility
The accessible name leads with the sustained read: "Slow window -25 vs target -23; fast -23,9." The interactive entry roves the samples with ←/→, announcing the fast value, the slow value, and the target at each point.
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
| Prop | Type | Notes |
|---|---|---|
| data* | number[] | Raw samples; two rolling means are computed. |
| target* | number | The compliance line — required. |
| windows | [number, number] | Fast/slow integration windows (samples). |
| band | [number, number] | A compliance corridor instead of one line. |
| domain | [number, number] | Fix the vertical scale instead of auto-fitting both traces. |
| animate | boolean | interactiveOpt-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.