Skip to content
microcharts
ReferenceFrontierTimeInRange

TimeInRange

TimeInRange shows how much of a period stayed inside its corridor, and which side the rest missed on.

encodes
stacked share length in fixed semantic order
precision
high
nodes
≤ 5 rects + ≤ 3 labels
collection
Frontier
Source

72% in range, 9% below, 19% above. TimeInRange prints the share of a period that stayed inside its corridor and which side the rest missed on, with the in-range percent leading. Zones sit in a fixed order (below, in, above), so the strip reads by position first and color second. They are never sorted by magnitude, because which side a miss landed on is half the reading.

TimeInRange
interactive · 5.07 kB · static · 2.56 kB

Install

Import & usereact/time-in-range
import { TimeInRange } from "@microcharts/react/time-in-range";<TimeInRange data={{ below: 9, in: 72, above: 19 }} title="Time in range" />
Needs package + stylesheetSet up with AI

Try it

Live playground
onActive
idle
  1. hover · rove · click…

Hover or arrow across the zones — each announces its share of the period.

labels
orientation
in-range · 72
readout
animate
import { TimeInRange } from "@microcharts/react/time-in-range/interactive";<TimeInRange  data={{ below: 9, in: 72, above: 19 }}/>

When to use it

Use it for SLO and uptime corridors, glucose-style time-in-range, and thermal or budget bands. To rank parts use SegmentedBar; for a single ratio use Progress.

Sizing

table cell
clinical column

Variants

clinical column
five zones

Severity tiers are drawn in the same hue at greater ink weight, so a severe zone never depends on color alone.

Edge cases

no data
labels drop out

Percent labels use largest-remainder rounding, so they always sum to 100 and the summary reads the same integers as the labels.

Four homes

In a sentence

Glucose time-in-range — 72% in range, 9% below.

In a table cell
Patient A72%
Patient B68%
Patient C81%
In a KPI card
In range
72%glucose TIR
In a tab header
Patient APatient BPatient C

Preview uses the public chart API only. When an interactive twin exists, it swaps in with the same props and no entrance motion - code samples stay on the static import. Placement recipes: Composition, Sizing.

Accessibility

The accessible name leads with the headline, then the misses: "72% in range, 7% below, 15% above, 2% severe low, 4% severe high." The interactive entry roves the zones, and each announces its share ("in range: 72%.").

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, press Escape, or press outside the chart. On touch, a tap pins and a drag scrubs.

Props

PropTypeNotes
data*TimeInRangeDatumCounts or fractions; normalized to 1.
orientation"horizontal" | "vertical"Vertical suits clinical columns and KPI cards.
label"in" | "all" | "none"The in-range headline, a full audit, or clean.
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