Skip to content

Camembert / Anneau

Composition

« Quelle part chaque élément occupe-t-il dans le tout ? » La plus ancienne question de la visualisation de données, et un camembert y répond encore le mieux lorsqu'il n'y a qu'une poignée de parts. Chaque part est dimensionnée selon sa valeur et étiquetée avec son pourcentage ; les parts sont triées par valeur pour que la plus grosse se lise en premier. Vous préférez un anneau ? C'est le même graphique - réglez innerRadiusRatio au-dessus de 0 pour creuser le trou (le contexte indique alors mode: "donut").

Example
canvas · responsive
Aller plus loin : Guide Insights·Guide DevTools

La variante en anneau n'est qu'une prop plus loin - voici les mêmes parts avec innerRadiusRatio: 0.6, un léger padAngle, et des coins arrondis :

Example
canvas · responsive
Aller plus loin : Guide Insights·Guide DevTools

Gardez un nombre de parts faible (≈ 6 ou moins). Pour de nombreuses catégories, une barre ou un treemap se lit plus précisément qu'un camembert.

Quand le choisir

  • Parts pour présentation au conseil. Une poignée de parts, chacune étiquetée avec son pourcentage : toujours le moyen le plus rapide de montrer « qui prend quelle part du tout » sur une diapositive.
  • Anneaux de tableau de bord. Réglez innerRadiusRatio et le centre creusé devient un emplacement de choix pour le chiffre phare que le camembert vient appuyer.

Données volumineuses sur WebGPU Expérimental

PieChart possède un renderer="webgpu" optionnel qui dessine les parts comme des arcs rendus par le GPU tandis que les libellés, la légende et les infobulles restent sur la couche SVG. Il est conditionné aux capacités du navigateur : sur un navigateur sans WebGPU, il bascule automatiquement sur canvas, et getContext().renderer indique lequel a effectivement dessiné.

⚗️ Experimental - not yet stable. WebGPU rendering is an opt-in preview. It needs a WebGPU-capable browser (Chrome / Edge, or Safari 26+); everywhere else it falls back to canvas automatically. Axes, labels and tooltips stay on the SVG layer - only the data marks are painted on the GPU.
Heavy-data demo · 40 slices… detecting

Faire defiler les annees

Donnez un date à chaque part et activez timeline : le camembert devient un récit année par année, avec son propre bouton lecture et son curseur, un instantané des parts à la fois. Désactivé par défaut - sans opt-in, rien ne change.

Appuyez sur le bouton lecture sous le graphique : les données défilent année par année, un instantané à la fois. Faites glisser le curseur pour sauter à une année.

tsx
const ref = useRef<PieChartHandle>(null);

<PieChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / stepForward()
vue
<PieChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" />
svelte
<div use:pieChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>
ts
applyPieChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });
html
<michi-vz-pie-chart id="c"></michi-vz-pie-chart>
<script>
  const el = document.getElementById("c");
  el.timeline = { speedMs: 1000, loop: true };
  // el.getTimeline() -> play() / pause() / seek(year)
</script>
  • speedMs règle le rythme, loop reboucle, autoplay: true démarre au montage, showControl: false masque la barre intégrée.
  • Les valeurs glissent d'une période à l'autre par défaut (interpolate) ; ajustez le mouvement avec tweenMs et easing, ou passez interpolate: false pour des coupes nettes. Avec reduced motion, la coupe est toujours nette.
  • Le contrôleur headless reste disponible : chart.timeline() expose play() / pause() / toggle() / seek(period) / stepForward() / stepBack(), plus onStep et formatPeriod dans la config pour une UI maison.
  • Un filter (top-N, tri) s'applique toujours à l'intérieur de chaque période : seules les 5 meilleures parts de l'année passent le filtre.
  • Les parts sans date restent visibles à chaque période.

Utilisation

tsx
import { PieChart } from "@michi-vz/react";

export default () => <PieChart {...props} />; // props = the chart options
vue
<script setup>
import { PieChart } from "@michi-vz/vue";
</script>

<template>
  <PieChart :options="props" />
</template>
svelte
<script>
  import { pieChart } from "@michi-vz/svelte";
</script>

<div use:pieChart={props}></div>
ts
// main.ts - register the elements once
import "@michi-vz/angular";
import { applyPieChartProps } from "@michi-vz/angular";

// component (uses CUSTOM_ELEMENTS_SCHEMA)
// template: <michi-vz-pie-chart #c></michi-vz-pie-chart>
applyPieChartProps(this.c.nativeElement, props);
html
<script type="module" src="https://cdn.jsdelivr.net/npm/@michi-vz/wc/dist/michi-vz-wc.bundle.js"></script>

<michi-vz-pie-chart id="c"></michi-vz-pie-chart>
<script>
  Object.assign(document.getElementById("c"), props); // dataSet, innerRadiusRatio, …
</script>
ts
import { mountPieChart } from "@michi-vz/core";

const chart = mountPieChart(el, props);
chart.update(next);
chart.getContext(); // renderer-agnostic, LLM-ready
chart.destroy();

Forme des données

Chaque élément de dataSet est une part : un label, une value, et une color optionnelle.

ts
const props = {
  innerRadiusRatio: 0, // 0 = pie; e.g. 0.6 = donut
  showLabels: true,    // % labels inside large-enough slices
  showLegend: true,
  dataSet: [
    { label: "Industry", value: 281, color: "#005aba" },
    { label: "Agri-food", value: 381, color: "#f0a500" },
    { label: "Materials", value: 132, color: "#2aa39a" },
  ],
};

Camembert ou anneau

Un seul moteur dessine les deux. innerRadiusRatio est le trou exprimé comme fraction du rayon extérieur : 0 donne un camembert plein, 0.6 un anneau. padAngle (en radians) ajoute un espace entre les parts et cornerRadius arrondit les coins des arcs. Les parts, l'infobulle, getContext() et la parité SVG/canvas sont identiques dans les deux cas.

API

Les props sont typées comme PieChartProps dans @michi-vz/core. Communes à tous les graphiques : width, height, margin, colors / colorsMapping, renderer ("svg", "canvas", ou "webgpu" expérimental), highlightItems, disabledItems, et les callbacks on*. onChartDataProcessed / getContext() renvoient le ChartContext indépendant du moteur de rendu. Référence complète : API Camembert / Anneau.