Skip to content

Graphique d'étendue

Tendances

« Quelle est l'ampleur de la dispersion ? » Quand une ligne unique ment sur vos données, tracez la bande à la place. Du meilleur au pire cas, le cône de prévision, du 5e au 95e percentile - cela colore toute l'étendue par série pour que l'incertitude soit quelque chose que le lecteur peut voir, pas deviner.

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

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

Quand le choisir

  • Chaque fois qu'une ligne unique exagérerait votre certitude. Cônes de prévision, bandes du 5e au 95e percentile, scénarios du meilleur au pire cas : la largeur de la bande est la réponse honnête.
  • Comparer la volatilité entre séries. Une bande large à côté d'une bande étroite est un message sur le risque qu'aucune moyenne ne transmet - écarts de portefeuille, gigue de SLA, plages de température.
  • Des niveaux de confiance imbriqués autour d'une seule prévision ? C'est exactement ce que le graphique en éventail compose pour vous, bandes et médiane en un seul appel.

Données volumineuses sur WebGPU Expérimental

RangeChart possède un renderer="webgpu" optionnel qui dessine les bandes min/max comme une géométrie rendue par le GPU tandis que les axes, les libellés 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 · ~200 bands… detecting

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<RangeChartHandle>(null);

<RangeChart
  ref={ref}
  {...props}
  progressiveDraw={{ durationMs: 2000 }}
/>;
// ref.current?.replay() rejoue l'animation à la demande
vue
<RangeChart :options="{ ...props, progressiveDraw: { durationMs: 2000 } }" />
svelte
<div use:rangeChart={{ ...props, progressiveDraw: { durationMs: 2000 } }}></div>
ts
applyRangeChartProps(this.c.nativeElement, {
  ...props,
  progressiveDraw: { durationMs: 2000 },
});
html
<michi-vz-range-chart id="c"></michi-vz-range-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 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<RangeChartHandle>(null);

<RangeChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / stepForward()
vue
<RangeChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" />
svelte
<div use:rangeChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>
ts
applyRangeChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });
html
<michi-vz-range-chart id="c"></michi-vz-range-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.
  • 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.
  • 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.

Utilisation

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

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

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

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

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

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

API

Les props sont typées comme RangeChartProps 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.