Skip to content
microcharts
ReferenceCoreEventTimeline

EventTimeline

EventTimeline places instants as diamonds and durations as rects on one compact row.

encodes
span extent on a linear time axis; points as position marks
precision
high
nodes
≤ 14 (1 per item + track + now tick, ≤ 12 items documented)

An API had a freeze window overnight, nine healthy hours, an incident at 11:00, and a release at 20:00. EventTimeline puts all of it on one row: diamonds mark instants, rects mark durations. The type distinction is a shape, so it survives 12 px where color coding wouldn't. Duration is length on a linear time axis, never log or compressed time.

EventTimeline
interactive · 5.79 kB · static · 3.09 kB

Install

Import & usereact/event-timeline
import { EventTimeline } from "@microcharts/react/event-timeline";// windows, today — real values under “Sample data” below<EventTimeline data={windows} domain={today} title="API uptime" />
Sample data
const windows = [  { start: Date.UTC(2026, 5, 3, 1), end: Date.UTC(2026, 5, 3, 5), label: "Freeze", kind: "accent" },  { start: Date.UTC(2026, 5, 3, 6), end: Date.UTC(2026, 5, 3, 15), label: "Healthy", kind: "positive" },  { start: Date.UTC(2026, 5, 3, 11), label: "Incident", kind: "negative" },  { start: Date.UTC(2026, 5, 3, 16), end: Date.UTC(2026, 5, 3, 18), kind: "negative" },  { start: Date.UTC(2026, 5, 3, 20), label: "Release" },];const today: [number, number] = [Date.UTC(2026, 5, 3), Date.UTC(2026, 5, 4)];
Needs package + stylesheetSet up with AI

Try it

When to use it

Use it for per-service uptime rows, and for on-call shifts and release windows in cards. Avoid it past roughly 12 items; for aggregated durations use a MiniBar of the totals.

Sizing

Variants

now tick
span labels

Edge cases

instants only
clipped by the window

A span that crosses the domain boundary is cut flat at the edge rather than rescaled to fit, so you see the part inside the window and nothing more. An item that falls entirely outside the domain is excluded, with a dev-only console warning. Spans that overlap render translucent in data order; that translucency is a legibility device rather than an encoding, and the exact intervals are in the announcements.

Four homes

Accessibility

The accessible name is the coverage read: "2 spans covering 46% of the window; 0 events." Coverage merges intervals first, so overlaps never double-count. The interactive entry cycles items chronologically: spans announce "Freeze: Jun 3, 01:00 to Jun 3, 05:00 — 4h.", instants "Incident: Jun 3, 11:00."

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*{ start; end?; label?; kind? }[]Spans (with end) and point events (without), ms epoch or Date.
domain[start, end]The window — fix it across rows for small multiples.
nownumber | DateCurrent-moment tick; authored, never implicit.
label"none" | "spans"Centered in-span labels with deterministic drop-out.
dateFormatIntl.DateTimeFormatOptions | (d: Date) => stringinteractiveAnnounced timestamp format for focused events (defaults to a locale date-time).
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