Xzero UI
Pro library

Small multiplesPro

A trellis of small line charts that reads as one chart, with a synced crosshair, a shared or independent y scale that springs the axes, sorting with a FLIP reorder, a ghost of the overall total behind every panel and dimming for flat trends.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/small-multiples
Live · keyboard ready

Render <SmallMultiples /> for the regional revenue demo, or pass series (id, name, values) and periods (short, long) with formatValue and formatTick for your own unit. Use defaultSort, defaultScale, defaultDimFlat, flatThreshold and growthLag to set the opening view, and onIndexChange to follow the crosshair.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/small-multiples

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { SmallMultiples } from "@/components/xzero/blocks/small-multiples/small-multiples";

export function SignupsByPlan() {
  return (
    <SmallMultiples
      title="Signups by plan"
      description="Weekly signups, last 26 weeks"
      series={plans.map(plan => ({ id: plan.id, name: plan.name, values: plan.weekly }))}
      periods={weeks.map(week => ({ short: week.short, long: week.long }))}
      growthLag={4}
      formatValue={value => value.toLocaleString("en-US")}
      formatTick={value => value.toLocaleString("en-US")}
      defaultScale="shared"
    />
  );
}

API reference

SmallMultiples

A trellis of small line charts, one per region or product, that reads as one chart. A synced crosshair shows every panel's value at the same period, a shared or independent y scale springs the axes and lines between comparing size and comparing shape, panels sort by latest value, growth or name with a FLIP reorder, a dashed ghost of the overall total sits behind every panel for context, and flat trends can be dimmed.

PropTypeDefaultDescription
seriesSmallMultiplesSeries[]smallMultiplesSeriesOne panel per series: a stable id, a name for the panel heading and one value per period.
periodsSmallMultiplesPeriod[]smallMultiplesPeriodsPeriods on the shared x axis, oldest first, each with a short label ("Sep 2025") and a long label ("September 2025") for the readout and screen readers.
titlestring"Revenue by region"Heading of the block.
descriptionstringsmallMultiplesDescriptionLine under the title. Pass an empty string to hide it.
defaultSort"latest" | "growth" | "name""latest"Opening panel order.
defaultScale"independent" | "shared""independent"Opening y scale. Independent fits each series to its own range so panels compare shape; shared starts every panel at zero on one range so panels compare size.
defaultDimFlatbooleantrueWhether panels with a flat trend start dimmed.
flatThresholdnumber0.05Growth below this absolute share counts as flat (0.05 is 5 percent).
growthLagnumber12Periods between the latest value and the value growth is measured against. 12 compares monthly data with the same month last year.
formatValue(value: number) => string–Formats values for panel headings, the readout and screen readers. The default reads values as thousands of US dollars ($412k, $1.71M).
formatTick(value: number) => string–Formats compact axis ticks in the right gutter of each panel.
onSortChange(sort: SmallMultiplesSort) => void–Called after the panel order changes.
onScaleChange(scale: SmallMultiplesScale) => void–Called after the y scale switches between independent and shared.
onIndexChange(index: number | null) => void–Called when the synced crosshair moves to a period, or with null when it leaves the panels.
classNamestring–Class on the root element.

Keyboard interactions

KeysAction
TabMoves to the sort control, the scale control, the dim switch and then the panels.
Left / Right arrowOn the panels, moves the synced crosshair one period in every panel at once. Focusing the panels with the keyboard places it on the latest period.
Page up / Page downOn the panels, moves the crosshair twelve periods.
Home / EndOn the panels, jumps to the first or latest period.
EscapeOn the panels, clears the crosshair and shows the latest values again.
Arrow keysIn the sort and scale controls, choose the next or previous option.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components