Xzero UI
Pro library

Waffle chart

A ten by ten unit chart where every cell is one percent, and cells fly to their new group when the data changes.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/waffle-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/waffle-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 { WaffleChart } from "@/components/xzero/waffle-chart/waffle-chart";

const mix = [
  { key: "wind-solar", label: "Wind and solar", value: 218 },
  { key: "hydro", label: "Hydro", value: 20 },
  { key: "gas", label: "Gas", value: 76 },
  { key: "coal", label: "Coal", value: 132 },
  { key: "other", label: "Other", value: 61 },
];

export function PowerMix() {
  return <WaffleChart data={mix} label="Electricity generation, 2023" unit="TWh" />;
}

API reference

WaffleChart

A unit chart where every cell is one share of the whole. When the data changes, cells keep following their category and fly to their new block with a staggered spring, and the shares in the legend roll to their new values.

PropTypeDefaultDescription
data (required)WaffleCategory[]–Categories in fill order: { key, label, value, color? }. The first fills from the bottom-left corner, column by column. Shares come from the total.
label (required)string–What the whole is, such as "Electricity generation, 2023". Names the chart, the summary, and the table.
unitstring""Unit after raw values in the tooltip and table, such as "TWh".
formatValue(value: number, category: WaffleCategory) => string–Formats raw values. Shares are always percentages.
rowsnumber10Grid rows. rows × columns cells make the whole.
columnsnumber10Grid columns. 10 × 10 means one cell per percent.
accentKeystring | nullfirst keyThe category painted in the first series hue, derived from the accent. The next three take the supporting series and later ones fall back to neutral steps.
activeKeystring | null–Controlled focused category. Other cells dim while one is focused.
defaultActiveKeystring | nullnullInitial focused category when uncontrolled.
onActiveChange(key: string | null) => void–Called when a legend item is pinned or released.
legendbooleantrueCategory list with rolling shares. It sits beside the grid from 420px and below it on narrower containers.
decimalsnumber0Decimal places for shares.
emptyLabelstring"No data"Message when the data is empty or sums to zero.
refRef<HTMLElement>–Forwarded to the figure.
classNamestring–Extra class on the figure.

Keyboard interactions

KeysAction
TabFocuses the grid, then each legend item.
Arrow keysMove the reading cell by cell across the grid.
PageUp / PageDownJump to the first cell of the previous or next category.
Home / EndGo to the first or last filled cell.
EscapeClears the reading.
Enter / Space on a legend itemPins or releases that category.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in charts

Guidance for AI tools

Waffle chart: A ten by ten unit chart where every cell is one percent, and cells fly to their new group when the data changes. 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