Skip to content
microcharts

Composition

How to place a chart in a sentence, a table cell, a KPI card, or a tab, and how SparkGroup puts a row of charts on one shared scale.

A microchart is built to sit inside an interface rather than in a chart pane of its own. This page has the placement recipe for each context the gallery demos use: the size, the props, and the surface each one wants, plus how to compare several charts at once.

In a sentence

A chart in running prose scales with the surrounding font and sits on the text baseline. Wrap it in mc-inline (shipped in styles.css) and pass dots="none" to drop its endpoint dots so it reads as one glyph. No chart in the catalog draws an axis, so there is nothing else to turn off. Pass summary={false} as well, so a screen reader hears the sentence and not a second description of it.

Inline in prose

p95 latency this week — trending down.

See Sizing for the em-based variant that scales with the surrounding type size.

In a table cell

In a dense table the row already carries a name and a number, so the chart shows the shape between them. Keep it small, turn dots off, pass summary={false}, and leave the numeric column on tabular-nums so the figures line up.

Trend column
checkout-api31 ms
auth-api16 ms
search-api78 ms

In a KPI card

The number leads and the chart gives it context. Give the chart a little more height, turn fill on so it reads as an area, and pass summary={false}: the figure and its label already name the value.

Figure + trend
Active connections
1,600concurrent, now

In a tab or button

A spark beside a tab label previews what's behind it. The label is the primary read, so the chart goes tiny: a small box with no dots.

Metric tabs
CPUMemoryNetwork

Charts sit on your surface

Every chart is transparent and never paints its own background. It takes its ink color from --mc-stroke, which tracks light and dark for you, and shows through to whatever surface it lands on. The contrast of that surface is your decision.

  • Put the chart on a surface with enough contrast for a 1.5 px line. The data, valence, and accent inks all clear 4.5:1 on the built-in light and dark themes. (--mc-neutral, the muted context ink for baselines and ghost marks, sits at 3.5:1, past the 3:1 bar for non-text and quieter than the data.)
  • A low-contrast tint stays low-contrast: the chart does not compensate for it.
  • Need the ink to differ from the page (charts on a colored panel, frosted glass)? Set --mc-stroke, and the valence tokens if needed, on the container. See Theming. Don't override .mc-root paint rules.

The gallery renders each demo inside a panel with a card background and a hairline border. That panel is not part of the library; it's a surface, like your app's cards, table rows, and headers.

Small multiples: one shared scale

When you place several sparklines in a row to compare them, they must share one vertical scale. Auto-scaling each chart to its own range makes a flat line and a spiking one look identical, which is a correctness bug and easy to miss.

SparkGroup handles it for you. It reads every child's data, computes one domain across all of them, and applies one physical size, so the row is comparable. It's hook-free and RSC-safe, and a child's own explicit domain/width still wins.

Shared-scale row

Pass zero when the group is bars or areas (so the shared domain anchors at zero), or an explicit domain={[min, max]} when you want a fixed frame instead of the data's own range (domain defaults to "shared").

Two more details. Only children that carry a data prop get the scale and size injected; plain wrappers, labels, and captions pass through untouched, so you can interleave them without them picking up stray DOM attributes. The group renders one <div className="mc-group">, an inline-flex row that wraps: its gap is --mc-gap scaled by --mc-density, and className/style on SparkGroup land on that div if you want a different layout.

The summary decision

Nearly every demo above passes summary={false}. Here is when that's the right call:

  • Standalone chart (the one thing in its region): keep the auto-summary on. It's the accessible name a screen reader announces, generated from the data.
  • Repeated or captioned chart (table rows, tabs, a chart next to a number that already states it): pass summary={false} to mark it decorative. The surrounding text is the accessible name, and a per-chart summary would make a screen reader read the same thing on every row.

summary is the only accessibility lever you set by hand. The role="img", the <title>, and the interaction contract on interactive entries (roving arrow keys, select-to-pin with Enter or Space, touch scrub, live announcements) are automatic. See Accessibility.