Skip to content
microcharts
ReferenceFrontierDualWindowMeter

DualWindowMeter

React dual-window meter chart — two time windows compared in one compact meter. Tiny accessible SVG microchart; RSC-safe static or /interactive.

DualWindowMeter answers "is the level compliant against its target both right now and on average — momentary spikes vs sustained drift?". From one raw series it computes two rolling means: a thin fast window that reacts instantly and a thick slow window that carries the sustained read, both against a target line. It is the general form of any noisy metric with a compliance target.

DualWindowMeter
interactive · 4.95 kB · static · 2.63 kB

Install

Import & usereact/dual-window-meter
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),);
Needs package + stylesheetSet up with AI

Try it

When to use it

  • Good for — loudness / LUFS metering, latency SLO or CPU-headroom compliance.
  • Avoid for — a single series (Sparkline) or anything without a target to compare against.

Sizing

Variants

corridor
custom windows
locale

With a locale, the right-edge readings and the accessible summary follow that locale's decimal mark — the fast reading above renders "-23,9", not "-23.9", and the accessible name reads "Slow window -25 vs target -23; fast -23,9."

Edge cases

short series — slow window still filling

Four homes

Why this default

Thin-fast, thick-slow because the sustained read should carry more ink — a momentary spike on the fast trace matters less than a slow-window drift away from target. The window sizes are part of the reading, not a hidden implementation detail — windows is an explicit prop, and the examples that change it state both sizes. Both traces always share one domain; a trace begins only where its window has filled, never faking a partial-window value.

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

PropTypeNotes
data*number[]Raw samples; two rolling means are computed.
target*numberThe 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.
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