Lintdiagram
Samenstelling
Wie wint terrein en wie verliest het? Wanneer marktaandeel, budgetverdelingen of stemmentotalen van de ene periode naar de andere herschikken, laten de linten die elke kolom verbinden je een enkele categorie volgen terwijl ze aanzwelt, krimpt, en van plaats wisselt met haar rivalen.
De grafiek hierboven is dezelfde engine in elk framework - alleen de integratiecode hieronder verschilt.
Wanneer kies je deze
- Marktaandeel, budgetverdelingen, ranglijsten. Wanneer categorieën van periode tot periode van plaats wisselen, laten de linten "wie haalde wie in, en wanneer" als eerste zien.
- Herschikkingen presenteren aan een zakelijk publiek. Elke categorie houdt haar kleur terwijl ze aanzwelt, krimpt en van rang wisselt, zodat het oog één concurrent door het hele verhaal kan volgen.
- Wisselt er nooit iets van rang, dan lopen de linten parallel en vertelt een vlakdiagram hetzelfde aandeelverhaal met minder inkt.
Veel data op WebGPU Experimenteel
RibbonChart heeft een optionele renderer="webgpu" die de linten op de GPU tekent, terwijl assen, labels en tooltips op de SVG-laag blijven. Dit is capability-gated: in een browser zonder WebGPU wordt automatisch teruggevallen op canvas, en getContext().renderer rapporteert wat daadwerkelijk is getekend.
Onthulanimatie
De grafiek tekent zichzelf van links naar rechts bij het mounten, waarbij de elementen na elkaar verschijnen voordat ze op hun plek vallen. Standaard uit - een grafiek kiest ervoor met de progressiveDraw-prop.
Elke lijn groeit van het eerste naar het laatste jaar; het label volgt de punt en komt tot stilstand bij het lijneinde. Met reduced motion ingeschakeld verschijnt de grafiek meteen volledig getekend.
progressiveDraw: true gebruikt de standaardinstellingen (1200 ms, easeInOutCubic). Een configuratieobject verfijnt het gedrag:
const ref = useRef<RibbonChartHandle>(null);
<RibbonChart
ref={ref}
{...props}
progressiveDraw={{ durationMs: 2000 }}
/>;
// ref.current?.replay() speelt de animatie opnieuw af<RibbonChart :options="{ ...props, progressiveDraw: { durationMs: 2000 } }" /><div use:ribbonChart={{ ...props, progressiveDraw: { durationMs: 2000 } }}></div>applyRibbonChartProps(this.c.nativeElement, {
...props,
progressiveDraw: { durationMs: 2000 },
});<michi-vz-ribbon-chart id="c"></michi-vz-ribbon-chart>
<script>
const el = document.getElementById("c");
el.progressiveDraw = { durationMs: 2000 };
// el.replay() speelt de animatie opnieuw af
</script>durationMseneasing("linear", "easeOutQuad", "easeInOutCubic", of een eigen(t) => t-functie) bepalen het tempo.autoplay: falserendert de grafiek volledig getekend; roepreplay()aan (React-ref-handle, webcomponent-methode of de core-instantie) om de animatie op aanvraag te starten.replayOnUpdate: trueherhaalt de animatie bij elke datawijziging.- Respecteert
prefers-reduced-motion: de grafiek verschijnt dan meteen volledig getekend.
Speel door de jaren heen
De data beslaat al meerdere jaren, dus er is niets te taggen. Zet timeline aan: de eigen afspeelknop en scrubber van de grafiek stappen door die jaren - bij elke stap tekenen de linten zich alleen tot het actieve jaar, en tijdens het afspelen lopen ze vloeiend verder door. Scrub je terug, dan trekken de linten zich weer terug. Hoveren toont alleen wat al echt getekend is. Standaard uit - zonder opt-in verandert er niets.
Druk op de afspeelknop onder de grafiek: de grafiek tekent zich verder door tot elk jaar terwijl hij speelt. Sleep de scrubber om naar een jaar te springen.
const ref = useRef<RibbonChartHandle>(null);
<RibbonChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / stepForward()<RibbonChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" /><div use:ribbonChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>applyRibbonChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });<michi-vz-ribbon-chart id="c"></michi-vz-ribbon-chart>
<script>
const el = document.getElementById("c");
el.timeline = { speedMs: 1000, loop: true };
// el.getTimeline() -> play() / pause() / seek(year)
</script>speedMsbepaalt het tempo,loopbegint opnieuw,autoplay: truestart bij mounten,showControl: falseverbergt de ingebouwde balk.- De headless controller is altijd beschikbaar:
chart.timeline()biedtplay() / pause() / toggle() / seek(period) / stepForward() / stepBack(), plusonStepenformatPeriodin de config voor eigen UI. - Waarden glijden standaard tussen jaren (
interpolate); zetinterpolate: falsevoor harde overgangen. Met reduced motion is de overgang altijd hard. timelinewint het vanprogressiveDrawwanneer beide op dezelfde grafiek staan.
Gebruik
import { RibbonChart } from "@michi-vz/react";
export default () => <RibbonChart {...props} />; // props = the chart options<script setup>
import { RibbonChart } from "@michi-vz/vue";
</script>
<template>
<RibbonChart :options="props" />
</template><script>
import { ribbonChart } from "@michi-vz/svelte";
</script>
<div use:ribbonChart={props}></div>// main.ts - register the elements once
import "@michi-vz/angular";
import { applyRibbonChartProps } from "@michi-vz/angular";
// component (uses CUSTOM_ELEMENTS_SCHEMA)
// template: <michi-vz-ribbon-chart #c></michi-vz-ribbon-chart>
applyRibbonChartProps(this.c.nativeElement, props);<script type="module" src="https://cdn.jsdelivr.net/npm/@michi-vz/wc/dist/michi-vz-wc.bundle.js"></script>
<michi-vz-ribbon-chart id="c"></michi-vz-ribbon-chart>
<script>
Object.assign(document.getElementById("c"), props); // dataSet/series, title, …
</script>import { mountRibbonChart } from "@michi-vz/core";
const chart = mountRibbonChart(el, props);
chart.update(next);
chart.getContext(); // renderer-agnostic, LLM-ready
chart.destroy();API
Props zijn getypeerd als RibbonChartProps in @michi-vz/core. Gedeeld door alle grafieken: width, height, margin, colors / colorsMapping, renderer ("svg", "canvas", of experimenteel "webgpu"), highlightItems, disabledItems, en de on*-callbacks. onChartDataProcessed / getContext() retourneren de renderer-agnostische ChartContext.
