Skip to content
microcharts
ReferenceExpressiveMusicStaff

MusicStaff

MusicStaff reads a short series as a melody, with each value's pitch on a five-line staff carrying the number.

encodes
pitch (vertical position on a 5-line staff)
precision
medium
nodes
n + 2 (n ≤ 16)
collection
Expressive
Source

MusicStaff reads a short series as a melody, so its shape lands in one look: each value is a note on a five-line staff, pitch (vertical position) is the value, and left-to-right is time. Pitch is the only channel, so there are no clefs, stems, beams, or bar lines. The read is in steps (nine to thirteen positions), so exact values steer to Sparkline with a label. Two adjacent equal values are spaced along the time axis and never dodged vertically, because moving a note vertically would change its pitch.

MusicStaff
interactive · 5.42 kB · static · 2.95 kB

Install

Import & usereact/music-staff
import { MusicStaff } from "@microcharts/react/music-staff";// weeks — real values under “Sample data” below<MusicStaff data={weeks} title="Sprint melody" />
Sample data
const weeks = [3, 5, 4, 8, 6, 9, 7, 11];
Needs package + stylesheetSet up with AI

Try it

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

Hover or arrow ←/→ across the notes — each announces its position and value, like stepping through a melody.

mode
last value
readout
animate
import { MusicStaff } from "@microcharts/react/music-staff/interactive";// weeks — real values under “Sample data” below<MusicStaff  data={weeks}/>
Sample data
const weeks = [3, 5, 4, 8, 6, 9, 7, 11];

When to use it

Use it for a weekly-rhythm read in a sentence, the shape of a sprint or short series in a cell, or a per-channel melody in a tab. For exact values use Sparkline with a label; skip it for long series (over sixteen points) and for trends where the exact slope matters.

Sizing

staff mode clamps the pitch on-staff
a rest (null) leaves a gap

Variants

staff mode + a rest

Ledger mode is the default: a note above or below the staff sits on a hairline ledger tick and keeps its true pitch, rather than being clipped. mode="staff" is for dense cells where ledger lines would collide with a neighbour; there, out-of-range pitches clamp to the nearest staff line or space, trading visual precision for a collision-free cell. The accessible summary is the same either way, since it describes the raw values, not the clamped pixel positions.

Edge cases

a single note
all rests
locale

A single value draws one note and no contour line, since a melody needs at least two notes to have a shape. An all-null series draws the bare staff with no notes at all, and the accessible name falls back to describeSeries's own no-data phrasing. With a locale, the trailing label="last" value follows that locale's own grouping and decimal marks.

Four homes

In a sentence

Sprint velocity this cycle — peaked in week 4, closing at 11 story points.

In a table cell
Platformpeak 11
Corepeak 9
Webpeak 8
In a KPI card
Sprint melody
11peak story points, week 4
In a tab header
PlatformCoreWeb

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

MusicStaff reuses Sparkline's natural-language summary verbatim. For [3, 5, 4, 8, 6, 9] that is "Trending up 200%. Range 3 to 9. Last value 9." The interactive entry steps the notes with ←/→ and announces each as "Point 3 of 6: 4."

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*(number | null)[]The series; null = a rest.
mode"staff" | "ledger"ledger (±2, default) or staff (clamp on-staff).
label"none" | "last"Print the final value after the last note.
fontSizenumberType size of the last-note label, in viewBox units. Defaults from `height`.
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