Skip to content
microcharts
ReferenceFrontierTraceFold

TraceFold

TraceFold lays out trace spans by start, duration, and depth, and accents the critical path.

encodes
width = duration, x = start, row = depth; critical path accented
precision
high
nodes
1 rect per span, cap 40

A request took 214 ms and you need to know which spans set that number. TraceFold draws one rect per span, placed by its start time, sized by its duration, and stacked by its nesting depth. Widths sit on one shared linear time scale, never normalized per row, so a wide span is a slow span. The critical path, the chain of spans that bound the total, is accented and every other span muted.

TraceFold
interactive · 5.28 kB · static · 2.52 kB

Install

Import & usereact/trace-fold
import { TraceFold } from "@microcharts/react/trace-fold";// spans — real values under “Sample data” below<TraceFold data={spans} title="Request trace" />
Sample data
const spans = [  { label: "request", start: 0, duration: 214, depth: 0 },  { label: "db.query", start: 10, duration: 86, depth: 1, parent: 0 },  { label: "auth", start: 0, duration: 8, depth: 1, parent: 0 },  { label: "render", start: 96, duration: 60, depth: 1, parent: 0 },  { label: "serialize", start: 156, duration: 40, depth: 1, parent: 0 },  { label: "index-scan", start: 12, duration: 70, depth: 2, parent: 1 },  { label: "decode", start: 82, duration: 12, depth: 2, parent: 1 },  { label: "log", start: 200, duration: 14, depth: 1, parent: 0 },  { label: "gc", start: 90, duration: 5, depth: 2, parent: 1 },];
Needs package + stylesheetSet up with AI

Try it

When to use it

Use it for request traces, flame charts, and p95-exemplar latency breakdowns. For a single duration use Bullet; for a time series use Sparkline.

Sizing

Variants

structure audit

emphasis="none" drops the accent when the nesting, not the latency, is what you are reading. The critical-path walk itself is deterministic: ties resolve to the earliest start.

locale

format also takes Intl.NumberFormatOptions — with a locale, the accessible summary's numbers follow that locale's own grouping and decimal marks ("14.868 ms" in German, not "14,868 ms"). In-rect text stays the plain span label either way; only the announced numbers are localized.

Edge cases

single span
labels drop out

A zero-duration span keeps a one-unit floor so it stays visible. That is the only width distortion in the chart.

Four homes

Accessibility

The accessible name gives the biggest span and its path status: "4 spans over 214 ms; longest db.query (86 ms) on the critical path." The interactive entry roves spans within a depth with ←/→ and between depths with ↑/↓, announcing each span's duration, share of the total, depth, and whether it is on the critical path.

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*Span[]Flat span list; parent = index.
emphasis"critical" | "none"Mute non-critical spans, or uniform.
labelsbooleanWidth-gated in-rect labels.
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