Skip to content

Graphique en aires ​

Composition

Le total augmente, mais quelle part le fait grimper ? Empilez vos catégories et observez la part de chacune dans le tout s'étendre ou se réduire dans le temps, pour qu'une marée montante et une composition changeante racontent leurs histoires en même temps.

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

Le graphique ci-dessus est le même moteur dans chaque framework - seul le code d'intégration ci-dessous diffère.

Quand le choisir ​

  • La composition dans le temps quand le total compte aussi. Les bandes empilées montrent la part de chaque catégorie tandis que le bord supérieur trace la somme - une marée montante et une composition changeante en une seule image.
  • Les histoires « la répartition change ». Une part qui s'amincit pendant que le total grossit est un message qu'aucun tableur ne délivre aussi vite - idéal pour les revues de chiffre d'affaires par produit ou de trafic par canal.
  • Quand les rangs se redistribuent, changez de graphique. Si l'histoire est de savoir qui a dépassé qui, le graphique en ruban rend les échanges explicites ; pour un instant unique, un camembert suffit.
  • Des parts, des taux ou des indices qui ne s'additionnent pas. Gardez les aires, mais superposez-les au lieu de les empiler : stacked: false, présenté ci-dessous.

Aires superposées ​

L'empilement n'a de sens que si les séries s'additionnent pour former un tout. Les parts, les taux et les indices, non : un ménage peut posséder un ordinateur portable et un smartphone, si bien que les taux d'équipement dépassent 100 % une fois additionnés, et un bord supérieur empilé tracerait un total que personne ne sait lire. Avec stacked: false, chaque aire va plutôt de zéro jusqu'à sa propre valeur, en remplissage translucide surmonté d'une ligne le long de son bord supérieur.

Example
canvas · responsive
Aller plus loin : Guide Insights·Guide DevTools
tsx
<AreaChart {...props} stacked={false} />
vue
<AreaChart :options="{ ...props, stacked: false }" />
svelte
<div use:areaChart={{ ...props, stacked: false }}></div>
ts
applyAreaChartProps(this.c.nativeElement, { ...props, stacked: false });
html
<michi-vz-area-chart id="c"></michi-vz-area-chart>
<script>
  // un attribut HTML ne peut qu'activer l'empilement : passez par la propriété pour le désactiver
  document.getElementById("c").stacked = false;
</script>
  • L'axe des y monte jusqu'à la plus grande valeur individuelle (arrondie à une graduation ronde), pas jusqu'à la somme d'une ligne, et n'a pas de plancher à 100 : des parts aussi petites que 0,9 gardent leur hauteur. Un yAxisDomain explicite ou forcePercentageScale reste prioritaire.
  • Les aires les plus grandes sont dessinées en premier, pour que les plus petites restent visibles au-dessus. L'ordre de la légende et les couleurs ne changent pas.
  • Toutes les aires couvrent le bas du graphique : le survol choisit donc la série dont le bord supérieur est le plus proche du pointeur.
  • La ligne supérieure prend la couleur de l'aire, y compris celle que votre CSS définit sur .area[data-label-safe], dans les trois moteurs de rendu.
  • stackOffset: "expand" normalise un empilement et n'a donc rien à faire ici : il est ignoré, avec un avertissement de données ignored-option.

Données volumineuses sur WebGPU Expérimental ​

AreaChart dispose d'un renderer="webgpu" optionnel qui peint les bandes empilées sur le GPU tandis que les axes, étiquettes et infobulles restent sur la couche SVG. C'est conditionné par les capacités du navigateur : sur un navigateur sans WebGPU, il rétrograde automatiquement vers canvas.

⚗️ 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 · ~7 500 points… detecting

Chronologie continue et graduations sans données ​

L'axe des x conserve toujours la première et la dernière période et incline / réduit les étiquettes trop nombreuses à environ 5. Activez fillPeriodTicks pour dessiner une graduation pour chaque mois de la plage ; les mois sans données s'affichent estompés avec une infobulle « pas de données » au survol. Basculez-le :

Toggle it on: the empty months appear as faded ticks. Hover one to see its "no data" tooltip. First and last periods are always kept, either way.

Personnalisez via noDataTickTooltip(epochMs) (texte de l'infobulle) et noDataTickColor (ou la variable CSS --michi-vz-tick-nodata).

tsx
<AreaChart
  {...props}
  xAxisDataType="date_monthly"
  fillPeriodTicks
  noDataTickTooltip={() => "No data reported for this month"}
  noDataTickColor="#c0392b"
/>
vue
<AreaChart :options="{ ...props, fillPeriodTicks: true, noDataTickTooltip: () => 'No data' }" />
svelte
<div use:areaChart={{ ...props, fillPeriodTicks: true, noDataTickTooltip: () => 'No data' }}></div>
ts
applyAreaChartProps(this.c.nativeElement, {
  ...props,
  fillPeriodTicks: true,
  noDataTickTooltip: () => "No data",
});
html
<michi-vz-area-chart id="c" fill-period-ticks no-data-tick-color="#c0392b"></michi-vz-area-chart>
<script>
  document.getElementById("c").noDataTickTooltip = () => "No data reported";
</script>

Animation de révélation ​

Le graphique se dessine de gauche à droite au montage, révélant ses éléments dans l'ordre avant de se stabiliser. Désactivé par défaut - un graphique l'active avec la prop progressiveDraw.

Chaque ligne grandit de la première à la dernière année ; l'étiquette suit la pointe puis se pose à l'extrémité de la ligne. Avec reduced motion activé, le graphique s'affiche entièrement tracé, instantanément.

progressiveDraw: true applique les réglages par défaut (1200 ms, easeInOutCubic). Un objet de configuration affine le comportement :

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

<AreaChart
  ref={ref}
  {...props}
  progressiveDraw={{ durationMs: 2000 }}
/>;
// ref.current?.replay() rejoue l'animation à la demande
vue
<AreaChart :options="{ ...props, progressiveDraw: { durationMs: 2000 } }" />
svelte
<div use:areaChart={{ ...props, progressiveDraw: { durationMs: 2000 } }}></div>
ts
applyAreaChartProps(this.c.nativeElement, {
  ...props,
  progressiveDraw: { durationMs: 2000 },
});
html
<michi-vz-area-chart id="c"></michi-vz-area-chart>
<script>
  const el = document.getElementById("c");
  el.progressiveDraw = { durationMs: 2000 };
  // el.replay() rejoue l'animation
</script>
  • durationMs et easing ("linear", "easeOutQuad", "easeInOutCubic", ou une fonction (t) => t personnalisée) façonnent le rythme du tracé.
  • autoplay: false rend le graphique entièrement tracé ; appelez replay() (handle de ref React, méthode du web component ou instance core) pour lancer l'animation à la demande. replayOnUpdate: true la rejoue à chaque changement de données.
  • Respecte prefers-reduced-motion : le graphique s'affiche alors entièrement tracé, instantanément.

Faire defiler les annees ​

Les données couvrent déjà plusieurs années, il n'y a donc rien à taguer. Activez timeline : le bouton lecture et le curseur propres au graphique parcourent ces années - à chaque étape, les bandes empilées ne se dessinent que jusqu'à l'année active, et la lecture les prolonge en douceur au fil de l'avancée. Reculez le curseur et les bandes se rétractent en conséquence. Le survol n'inspecte jamais que ce qui est réellement tracé. Désactivé par défaut - sans opt-in, rien ne change.

Appuyez sur le bouton lecture sous le graphique : le graphique se dessine plus loin jusqu'à chaque année au fil de la lecture. Faites glisser le curseur pour sauter à une année.

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

<AreaChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / seekIndex(i) / stepForward()
vue
<AreaChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" />
svelte
<div use:areaChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>
ts
applyAreaChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });
html
<michi-vz-area-chart id="c"></michi-vz-area-chart>
<script>
  const el = document.getElementById("c");
  el.timeline = { speedMs: 1000, loop: true };
  // el.getTimeline() -> play() / pause() / seek(year) / seekIndex(i)
</script>
  • speedMs règle le rythme, loop reboucle, autoplay: true démarre au montage, showControl: false masque la barre intégrée.
  • Le contrôleur headless reste disponible : chart.timeline() expose play() / pause() / toggle() / seek(period) / seekIndex(i) / stepForward() / stepBack(), plus onStep et formatPeriod dans la config pour une UI maison.
  • seek(period) cherche d'abord la période, en comparant le texte : seek(2021) et seek("2021") vont tous les deux sur 2021, que vos dates soient des nombres ou des chaînes. Un nombre ne compte comme une position (0 = la première) que si aucune période ne correspond, et une chaîne qui ne correspond à rien ne fait rien. seekIndex(i) va toujours par position, comme le curseur intégré.
  • Les valeurs glissent entre les années par défaut (interpolate) ; passez interpolate: false pour des coupes nettes. Avec reduced motion, la coupe est toujours nette.
  • timeline l'emporte sur progressiveDraw quand les deux sont définis sur le même graphique.

Usage ​

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

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

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

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

// component (uses CUSTOM_ELEMENTS_SCHEMA)
// template: <michi-vz-area-chart #c></michi-vz-area-chart>
applyAreaChartProps(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-area-chart id="c"></michi-vz-area-chart>
<script>
  Object.assign(document.getElementById("c"), props); // dataSet/series, title, …
</script>
ts
import { mountAreaChart } from "@michi-vz/core";

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

API ​

Les props sont typées comme AreaChartProps dans @michi-vz/core. Communes à tous les graphiques : width, height, margin, colors / colorsMapping, renderer ("svg", "canvas", ou expérimentalement "webgpu"), highlightItems, disabledItems, et les callbacks on*. onChartDataProcessed / getContext() renvoient le ChartContext agnostique du moteur de rendu.