Pie
A pie or donut chart of parts against a whole, colored from a theme-derived palette, with an interactive readout.
Live demo
Pie plots a set of labelled values as wedges of a circle, each a share of the whole. Each slice takes its color from a scheme resolved off the live theme (skittles by default, so the parts read as distinct), or pass explicit colors and reverse.
Set variant="donut" for a ring with the total in its center. It's interactive: hovering or focusing a slice dims the rest and floats its value and share, and the chart is mirrored into a visually-hidden table so assistive tech reads the numbers. A legend names each slice; optional showValues prints the percentage on each wedge. Size it with size; zero and negative values drop out, and a chart with nothing left to plot shows a muted No data message in place of the wedges.
When to use
How this component composes with the rest of the set.
Props
8 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Variants
pie
A full pie of solid wedges.
donut
A ring with the total in its center.
States
slice-hover
Pointer over or keyboard focus on a slice: the rest dim and a value/share readout floats above it.
slice-focus
Keyboard focus on a slice draws a token ring; each slice is a tab stop announcing its label, value, and share.
Anatomy
The named parts that make up the component, with their selectors.
chart
The <figure> root holding the SVG, legend, tooltip, and the accessible data table.
slice
One wedge, filled with its palette color and separated by a hairline; the focus/hover target.
center
The donut's center total.
legend
The slice key; each item pairs a color dot with the slice label.
tooltip
The floating value/share readout shown on hover or focus of a slice.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--bg-0
--bg-1
--border-thick
--border-thin
--duration-fast
--ease-standard
--elevation-3
--fg-0
--fg-1
--fg-2
--font-sans
--leading-normal
--radius-md
--radius-sm
--ring
--space-1
--space-2
--space-3
--surface-overlay
--surface-overlay-border
--text-lg
--text-sm
--text-xs
--weight-bold
--weight-semibold
Accessibility
Code
Pie
Four sources as shares of the whole, colored from the skittles scheme.
<xtyle-pie label="Traffic by source"></xtyle-pie>
<script>
document.querySelector("xtyle-pie").data = [
{ label: "Direct", value: 42 },
{ label: "Search", value: 30 },
{ label: "Social", value: 18 },
{ label: "Referral", value: 10 },
];
</script>
<script lang="ts">
import { Pie } from "@xtyle/svelte";
const data = [
{ label: "Direct", value: 42 },
{ label: "Search", value: 30 },
{ label: "Social", value: 18 },
{ label: "Referral", value: 10 },
];
</script>
<Pie {data} label="Traffic by source" />
---
import { Pie } from "@xtyle/astro";
const data = [
{ label: "Direct", value: 42 },
{ label: "Search", value: 30 },
{ label: "Social", value: 18 },
{ label: "Referral", value: 10 },
];
---
<Pie data={data} label="Traffic by source" />
Donut
variant="donut" opens the center for the total; here on the accents scheme.
<xtyle-pie variant="donut" scheme="accents" label="Budget"></xtyle-pie>
<script>
document.querySelector("xtyle-pie").data = [
{ label: "Rent", value: 1200 },
{ label: "Food", value: 600 },
{ label: "Transit", value: 300 },
{ label: "Fun", value: 400 },
];
</script>
<script lang="ts">
import { Pie } from "@xtyle/svelte";
const data = [
{ label: "Rent", value: 1200 },
{ label: "Food", value: 600 },
{ label: "Transit", value: 300 },
{ label: "Fun", value: 400 },
];
</script>
<Pie {data} variant="donut" scheme="accents" label="Budget" />
---
import { Pie } from "@xtyle/astro";
const data = [
{ label: "Rent", value: 1200 },
{ label: "Food", value: 600 },
{ label: "Transit", value: 300 },
{ label: "Fun", value: 400 },
];
---
<Pie data={data} variant="donut" scheme="accents" label="Budget" />
Discrete outcomes
scheme="statuses" colors each slice by a semantic tone (success, failed, warn, info, skipped, live) so a run-outcome chart reads by meaning, and stays right even when a category is absent.
<xtyle-pie variant="donut" scheme="statuses" label="Runs"></xtyle-pie>
<script>
// Give each slice a semantic `tone` so it colors by meaning: a run where nothing
// failed drops the failed slice without shifting the others' colors.
document.querySelector("xtyle-pie").data = [
{ label: "Passed", value: 128, tone: "success" },
{ label: "Failed", value: 14, tone: "failed" },
{ label: "Flaky", value: 9, tone: "warn" },
{ label: "Skipped", value: 21, tone: "skipped" },
{ label: "Running", value: 6, tone: "live" },
{ label: "Queued", value: 11, tone: "info" },
];
</script>
<script lang="ts">
import { Pie } from "@xtyle/svelte";
// A semantic `tone` per slice colors by meaning, stable even if a category is absent.
const data = [
{ label: "Passed", value: 128, tone: "success" },
{ label: "Failed", value: 14, tone: "failed" },
{ label: "Flaky", value: 9, tone: "warn" },
{ label: "Skipped", value: 21, tone: "skipped" },
{ label: "Running", value: 6, tone: "live" },
{ label: "Queued", value: 11, tone: "info" },
];
</script>
<Pie {data} variant="donut" scheme="statuses" label="Runs" />
---
import { Pie } from "@xtyle/astro";
// A semantic `tone` per slice colors by meaning, stable even if a category is absent.
const data = [
{ label: "Passed", value: 128, tone: "success" },
{ label: "Failed", value: 14, tone: "failed" },
{ label: "Flaky", value: 9, tone: "warn" },
{ label: "Skipped", value: 21, tone: "skipped" },
{ label: "Running", value: 6, tone: "live" },
{ label: "Queued", value: 11, tone: "info" },
];
---
<Pie data={data} variant="donut" scheme="statuses" label="Runs" />