Chart components

Pie Chart

Pie and donut charts with exact values, keyboard inspection, and composed labels.

Installation

pnpm dlx @mielui/svelte add pie-chart

Usage

Pass Root data with a stable key and a value for each category, and a config entry with a label and an optional color and format for each key. Values must be finite and not negative; do not draw a negative balance as a slice. The total is the sum of the data, and stable keys keep slices and labels tied to the same category across updates.

Put Arc and an optional Label inside Plot, and Legend and Tooltip directly inside Root. Arc draws a donut by default; set innerRadius={0} for a solid pie. Label shows the total in the center; its children snippet receives total and the active slice for custom content. The tooltip follows the pointer outside the ring so the slice you inspect stays visible.

<script lang="ts">
    import * as PieChart from '@mielui/svelte/components/pie-chart';

    const data = [
        { key: 'direct', value: 1240 },
        { key: 'search', value: 860 }
    ];
    const config = {
        direct: { label: 'Direct', color: 'var(--chart-1)' },
        search: { label: 'Search', color: 'var(--chart-2)' }
    };
</script>

<PieChart.Root {data} {config} aria-label="Sessions by acquisition channel">
    <PieChart.Plot>
        <PieChart.Arc />
        <PieChart.Label />
    </PieChart.Plot>
    <PieChart.Tooltip />
    <PieChart.Legend />
</PieChart.Root>

Chart types

Loading and empty data

Set loading on Root while a request is pending; the chart keeps its height and shows a neutral skeleton. An empty dataset shows an empty state rather than made-up values.

Animation

animation defaults to reveal, which runs once on entry; data changes then transition from what is on screen. live highlights segments one after another with quiet pauses and never moves their boundaries. It pauses while a segment is active, while the chart is offscreen, and while the tab is hidden. none turns chart motion off. Reduced motion and the theme's motion setting are respected.

Accessibility

Root requires a descriptive aria-label and includes a data table for screen readers. Focus a legend item to inspect its value, or point at a slice; Escape dismisses the tooltip.

Labels

Pass labels to Root to translate the loading and empty messages and the column headings of the screen-reader table. Every key of PieChartLabels is optional; omitted keys keep the English text.

<script lang="ts">
    import * as PieChart from '@mielui/svelte/components/pie-chart';
    import type { PieChartDatum, PieChartLabels } from '@mielui/svelte/components/pie-chart';

    let { data }: { data: PieChartDatum[] } = $props();

    const config = {
        direct: { label: 'Direct' },
        search: { label: 'Recherche' }
    };
    const labels: PieChartLabels = {
        loading: 'Chargementโ€ฆ',
        empty: 'Aucune donnรฉe',
        category: 'Catรฉgorie',
        value: 'Valeur'
    };
</script>

<PieChart.Root {data} {config} {labels} aria-label="Sessions par canal">
    <PieChart.Plot>
        <PieChart.Arc />
    </PieChart.Plot>
</PieChart.Root>

API reference

PieChart.Root

  • aria-label Required
    string

    Defines a string value that labels the current element.

  • labels
    PieChartLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • data Required
    readonly PieChartDatum[]

    Segments to plot, each with a key and a value.

  • config Required
    { [x: string]: { label: string; color?: string | undefined; format?: ((value: number) => string) | undefined; }; }

    Label, color, and value format for each series, keyed by series.

  • loading
    boolean

    Shows the loading state in place of the content.

    Default false

  • animation
    "reveal" | "live" | "none"

    reveal animates in once, live keeps a subtle motion running, and none is static.

    Default 'reveal'

  • children
    Snippet<[]>

    Content rendered inside.

PieChart.Arc

  • innerRadius
    number

    Hole size as a share of the radius. Zero draws a full pie.

    Default 0.68

  • cornerRadius
    number

    Corner radius of each segment in pixels.

    Default 4

  • padAngle
    number

    Gap between segments in radians.

    Default 0.035

  • class
    string

    Classes added to the element.

PieChart.Label

  • children
    Snippet<[{ total: number; active: PieChartDatum | undefined; }]>

    Content rendered inside.

PieChart.Legend

  • children
    Snippet<[{ item: PieChartDatum; label: string; value: string; percentage: number; }]>

    Content rendered inside.

PieChart.Tooltip

  • children
    Snippet<[{ item: PieChartDatum; label: string; value: string; percentage: number; }]>

    Content rendered inside.

Other parts

These parts have no props of their own. They pass HTML attributes and events to their element.

  • PieChart.Plot