Xzero UI
Pro library

Race bar chartPro

A ranking over time: bars overtake each other on springs, values count up, and a timeline you can play or scrub.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/race-bar-chart
Live · keyboard ready

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/race-bar-chart

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 { RaceBarChart } from "@/components/xzero/race-bar-chart/race-bar-chart";

const items = [
  { id: "chair", label: "Oak lounge chair", group: "furniture" },
  { id: "lamp", label: "Mushroom lamp", group: "lighting" },
];
const frames = [
  { period: "January", values: { chair: 14000, lamp: 66000 } },
  { period: "February", values: { chair: 30000, lamp: 128000 } },
];

export function ProductRace() {
  return <RaceBarChart items={items} frames={frames} groups={[{ id: "furniture", label: "Furniture" }, { id: "lighting", label: "Lighting" }]} label="Revenue by product" highlight="chair" />;
}

API reference

RaceBarChart

A bar chart race: bars overtake each other on springs as values grow, numbers count continuously, the period rolls in large type, and a timeline plays, pauses, and scrubs through time.

PropTypeDefaultDescription
items (required){ id: string; label: string; group?: string }[]–The things being ranked. A stable id keeps each bar's identity across frames.
frames (required){ period: string; values: Record<string, number> }[]–One frame per period, in order. Missing ids count as zero.
label (required)string–What is ranked. Names the chart for assistive technology.
groups{ id: string; label: string }[]–Names and order of the groups. The first four take the series hues and a legend appears; without groups every bar takes the first hue.
formatValue(value: number) => string–Formats values on bars, in the tooltip, and in the table. Defaults to a compact number.
formatTick(value: number) => string–Formats the value axis.
barsnumber8Bars shown at once. Items below the cut slide out of view.
framenumber–Controlled frame index. A new value glides the race there.
defaultFramenumber0Initial frame when uncontrolled.
onFrameChange(index: number) => void–Called when the shown period changes.
playingboolean–Controlled playback.
defaultPlayingbooleanfalseInitial playback when uncontrolled.
onPlayingChange(playing: boolean) => void–Called when playback starts or stops.
autoPlaybooleantrueStarts playing the first time the chart scrolls into view. Ignored with reduced motion.
frameDurationnumber1400Milliseconds per period while playing.
loopbooleanfalseRewinds to the first period after the last and keeps playing.
highlightstring–Item id whose name and value are emphasized, such as your own product.
classNamestring–Extra class on the root figure.

Keyboard interactions

KeysAction
Space / EnterPlays or pauses. At the end, replays from the start.
ArrowLeft / ArrowRightSteps one period back or forward; the race glides there.
ArrowUp / ArrowDownMoves the reading through the bars by rank and shows the tooltip.
Home / EndJumps to the first or last period.
EscapeClears the reading.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in advanced charts

Guidance for AI tools

Race bar chart: A ranking over time: bars overtake each other on springs, values count up, and a timeline you can play or scrub. 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