Sankey
Stroom
"Waar gaat het allemaal naartoe?" Een Sankey-diagram brengt de stroom door een systeem in kaart: knopen worden ingedeeld in kolommen, en de dikte van elke band is de stroomwaarde. Het is het juiste beeld voor handel tussen exporteurs en markten, budget van bronnen naar bestemmingen, verkeer van verwijzers naar pagina's - overal waar een hoeveelheid onderweg opsplitst en weer samenkomt.
De lay-out wordt berekend met d3-sankey: knopen worden op basis van de grafiektopologie aan kolommen toegewezen, verticaal gepakt, en verbindingen worden getekend als vloeiende horizontale banden. Hover over een knoop of een stroom voor de bijbehorende cijfers.
Wanneer kies je deze
- Stromen met structuur. Handel tussen exporteurs en markten, budget van bronnen naar bestemmingen, gebruikers door een trechter: waar hoeveelheden vandaan komen, waar ze naartoe gaan, wat opsplitst en weer samenkomt.
- Het dominante pad en de lekken vinden. Banddikte is de waarde, dus de dikke routes en de dunne verliezen lees je meteen af - het auditoverzicht van elk systeem.
- Slechts één fase? Als er niets doorheen stroomt, rangschikt een staafdiagram bronnen overzichtelijker dan een Sankey met twee kolommen.
Veel data op WebGPU Experimenteel
De optionele renderer="webgpu" van deze grafiek tekent de marks op de GPU, terwijl assen/labels/tooltips op SVG blijven; capability-gated met automatische terugval naar canvas.
Speel door de jaren heen
Geef elke link een date en zet timeline aan: de momentopname van een jaar bestaat uit de links die die datum delen - knopen worden gedeeld over de jaren heen, alleen de stromen komen en gaan - en de banddikte glijdt tussen jaren. Standaard uit - zonder opt-in verandert er niets. Dit is interactief jaar-voor-jaar stappen, niet de eenmalige intro verderop.
Druk op de afspeelknop onder de grafiek: de data stapt door de jaren, één momentopname per keer. Sleep de scrubber om naar een jaar te springen.
const ref = useRef<SankeyChartHandle>(null);
<SankeyChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / stepForward()<SankeyChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" /><div use:sankeyChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>applySankeyChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });<michi-vz-sankey-chart id="c"></michi-vz-sankey-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.- Waarden glijden standaard tussen periodes (
interpolate); stem de beweging af mettweenMseneasing, of zetinterpolate: falsevoor harde overgangen. Met reduced motion is de overgang altijd hard. - De headless controller is altijd beschikbaar:
chart.timeline()biedtplay() / pause() / toggle() / seek(period) / stepForward() / stepBack(), plusonStepenformatPeriodin de config voor eigen UI. - Links zonder
dateblijven in elke periode zichtbaar. timelinewint het vanprogressiveDrawals beide zijn ingesteld - de onthulanimatie verderop blijft uit zolang de timeline de regie heeft.
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<SankeyChartHandle>(null);
<SankeyChart
ref={ref}
{...props}
progressiveDraw={{ durationMs: 2000 }}
/>;
// ref.current?.replay() speelt de animatie opnieuw af<SankeyChart :options="{ ...props, progressiveDraw: { durationMs: 2000 } }" /><div use:sankeyChart={{ ...props, progressiveDraw: { durationMs: 2000 } }}></div>applySankeyChartProps(this.c.nativeElement, {
...props,
progressiveDraw: { durationMs: 2000 },
});<michi-vz-sankey-chart id="c"></michi-vz-sankey-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. - Onthulanimatie is een eenmalige animatie bij mounten; speel door de jaren hierboven stapt in plaats daarvan jaar voor jaar door de data.
Gebruik
import { SankeyChart } from "@michi-vz/react";
export default () => <SankeyChart {...props} />; // props = the chart options<script setup>
import { SankeyChart } from "@michi-vz/vue";
</script>
<template>
<SankeyChart :options="props" />
</template><script>
import { sankeyChart } from "@michi-vz/svelte";
</script>
<div use:sankeyChart={props}></div>// main.ts - register the elements once
import "@michi-vz/angular";
import { applySankeyChartProps } from "@michi-vz/angular";
// component (uses CUSTOM_ELEMENTS_SCHEMA)
// template: <michi-vz-sankey-chart #c></michi-vz-sankey-chart>
applySankeyChartProps(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-sankey-chart id="c"></michi-vz-sankey-chart>
<script>
Object.assign(document.getElementById("c"), props); // nodes, links, …
</script>import { mountSankeyChart } from "@michi-vz/core";
const chart = mountSankeyChart(el, props);
chart.update(next);
chart.getContext(); // renderer-agnostic, LLM-ready
chart.destroy();Datavorm
In tegenstelling tot de andere grafieken neemt een Sankey twee arrays aan: nodes (elk met een unieke id, een optionele label en color) en links (source → target op basis van id, met een value).
const props = {
linkColorMode: "source", // colour links by their source (or "target")
nodes: [
{ id: "France" }, { id: "Germany" },
{ id: "EU" }, { id: "Asia" },
],
links: [
{ source: "France", target: "EU", value: 40 },
{ source: "France", target: "Asia", value: 22 },
{ source: "Germany", target: "EU", value: 55 },
{ source: "Germany", target: "Asia", value: 35 },
],
};Een link naar een onbekende knoop-id (of een knoop in disabledItems) wordt met een datawarning weggelaten; het uitschakelen van een knoop laat ook de bijbehorende links vervallen.
Lay-outinstellingen
nodeWidth bepaalt de breedte van het knooprechthoek, nodePadding de verticale tussenruimte tussen knopen in een kolom, en linkOpacity hoe doorschijnend de banden zijn. linkColorMode kleurt elke band naar zijn source-knoop (standaard) of target-knoop. De a11y-spiegel en getContext() presenteren de links als een leesbare "Bron → Doel: waarde"-tabel.
Afgeronde knopen. nodeRadius (px, standaard 2) rondt de hoeken van het knooprechthoek af - verhoog de waarde voor het pilvormige uiterlijk, of zet hem op 0 voor rechte hoeken. Deze wordt begrensd tot de helft van de kortste zijde van de knoop, zodat een dunne knoop nooit vervormt.
Afgeronde stromen. De stromen worden getekend als gevulde linten; linkRadius (px, standaard 2) rondt hun hoeken af waar ze de knopen raken, voor een zachtere verbinding (begrensd tot de helft van de banddikte; 0 = scherp). linkColorMode kleurt elke stroom naar zijn source- of target-knoop, op linkOpacity:
const props = { nodeRadius: 4, linkRadius: 4, /* …nodes, links */ };API
Props zijn getypeerd als SankeyChartProps 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. Volledige referentie: Sankey API.
