Fontein (Jet d'Eau) API
Eén getal per kolom (de grote stip), het echte bereik eromheen (de fontein, van low tot high) en de metingen zelf (de kleine stippen), allemaal op één y-as. Categorische x = momentopname; temporele of numerieke x = trend. Zie de Fontein-demo en de leeswijzer.
Import
import "@michi-vz/wc/fountain-chart";
// <michi-vz-fountain-chart> is nu gedefinieerdimport { mountFountainChart } from "@michi-vz/core";
const chart = mountFountainChart(el, props);import { FountainChart } from "@michi-vz/react/fountain-chart";import { FountainChart } from "@michi-vz/vue/fountain-chart";import { fountainChart } from "@michi-vz/svelte/fountain-chart";import { bindChart, applyFountainChartProps } from "@michi-vz/angular/fountain-chart";
// heeft CUSTOM_ELEMENTS_SCHEMA nodig op de component die <michi-vz-fountain-chart> bevatProps
| Prop | Type | Default | Description |
|---|---|---|---|
timeline | boolean | TimelinePeriodConfig | - | Opt-in "play through years" (cumulative): the marks draw UP TO the active period and extend as the timeline steps; `interpolate` sweeps smoothly between years, `false` jump-cuts. Headless controller via `chart.timeline()` plus the built-in play button + scrubber. Off by default; wins over `progressiveDraw` when both are set. The reveal always shows the whole active jet, fountain and small dots included, and a jet's value labels appear with it; undrawn jets cannot be hovered. Trend mode only. Not drawn by the "webgpu" renderer (an ignored-option warning). |
progressiveDraw | boolean | ProgressiveDrawConfig | - | Opt-in reveal animation: wipes the marks in left to right on mount (a clip reveal; axes and titles stay put). `true` uses defaults (1200 ms, easeInOutCubic); a config tunes durationMs, easing, autoplay, and replayOnUpdate (`tipLabel` is LineChart-only and ignored here). Off by default; respects prefers-reduced-motion (renders fully drawn instantly) and `replay()` re-runs it. Jets the wipe has not reached cannot be hovered. Not drawn by the "webgpu" renderer (an ignored-option warning). |
dataSet* | FountainDataItem[] | - | Array of jets; each item renders one fountain |
title | string | - | Optional chart title rendered above the plot |
xAxisDataType | FountainXAxisType | - | How the x-axis is parsed: a temporal/numeric type renders TREND mode (jets at their dates, the x range inset by half a column on each side, one tick per period); "band" (or omitted) renders SNAPSHOT mode (one column per label) |
yAxisDomain | [number, number] | - | Explicit [min, max] for the value (y) axis, used as given (not rounded). The auto domain includes 0, every value, low, high and reference line, plus 10% headroom, rounded to nice ticks. Data outside a user domain is clamped to the plot edge and small dots outside it are not drawn (an `out-of-domain` warning). |
xAxisFormat | (d: number | string) => string | - | Formats an x tick value into its display label |
yAxisFormat | (d: number | string) => string | - | Formats a y value: the tick labels and the numbers in the value labels and the tooltip (default: the locale's number format) |
ticks | number | 5 | Approximate number of axis ticks to generate (default 5) |
tickValues | Array<number | Date> | - | Explicit x tick values, overriding the per-period ticks (trend mode) |
showRange | boolean | true | Draw the fountain: the range [low, high] as a bell (default true). `false` draws the stem and the big dot only; the small dots need the fountain to sit in, so they hide too. |
showSamples | boolean | true | Draw the small dots, one per sample, when items carry `samples` (default true) |
showValueLabels | boolean | true | Print value labels under each x label (default true): bold "usual 30", then "<low word> 22" and "<high word> 55" (see `endLabels`), "only N <sampleWord>" under 10 samples, and per reference line with a `goodSide` a bold "17 of 20" plus its `countLabel`. The chart reserves bottom margin for them. On narrow columns the text shrinks, then the end lines go, before a label would overlap a neighbour; when even the usual line cannot fit, when the x labels have to tilt, or where two jets share a column, the value labels are left out (a `layout-overflow` warning). |
drift | boolean | false | The Geneva look: the top of every fountain leans downwind, the same way for every jet, so it means nothing (default false: readers found it confusing) |
yAxisTitle | string | - | Title drawn rotated beside the y-axis, e.g. "minutes (higher = slower)" |
endLabels | [string, string] | - | Words for the low and high ends in the value labels and tooltip (default ["lowest", "highest"]; e.g. ["best", "worst"], ["cheapest", "dearest"]) |
referenceLines | FountainReferenceLine[] | - | Horizontal reference lines (a promise, a limit, a budget). With `goodSide`, each jet with samples counts its small dots on the good side. |
labels | FountainLabels | - | UI words for localisation (English defaults "usual", "of", "only", "forecast") |
readingGuide | boolean | string | - | A reading guide under the plot (default false), on one line when it fits, else wrapped between its rules (at each " · "), never inside one. `true` prints the default ("Small dot = one measurement · Big dot = the usual one · Dots close together = steady · Tall fountain = changes a lot · Few dots = just a guess") with only the rules for marks the chart draws: no small-dot rules without small dots (no samples, showSamples or showRange off, forecasts only), no "Tall fountain" rule without a fountain. A string replaces it and is printed as given. |
sampleWord | string | - | PLURAL noun for the samples in the value labels and tooltip, e.g. "days", "orders" (default "measurements"). Plural on purpose: there is no pluralising logic, and one string is easy to localise. |
showTrendLine | boolean | - | Draw a dashed grey line through the big dots, left to right (default true in trend mode with one series; false with several series, where one line would zig-zag between them, and in snapshot mode; set it true to join an ordered sequence of categories, e.g. hours) |
tooltipFormatter | (d: FountainDataItem & { value: number }, jet?: FountainTooltipJet) => string | - | Returns custom tooltip HTML for a hovered or pinned jet (sanitized before it is inserted). Default: the label (with its period in trend mode), "usual 30", "<low word> 22 · <high word> 55", "20 <sampleWord>" and a count per reference line with a goodSide, numbers formatted like the y-axis. Click or tap pins the tooltip; clicking the pinned jet or empty space, or Escape, unpins. The first argument is the item with its resolved `value` (the median of its samples when it gives none), so `d.value` is always a number; a formatter typed `(d: FountainDataItem) => string` still fits. The second is the jet as drawn (its range, samples, reference counts, period and the default lines), so a custom tooltip needs no re-derivation. |
isLoading | boolean | - | Show the loading overlay; with nothing drawn yet the axes and marks wait for data, while a refetch keeps the stale jets on screen. |
isNodata | boolean | ((dataSet: FountainDataItem[] | null | undefined) => boolean) | - | No-data override: boolean, or a predicate on the data; default = an empty dataSet. With no data the chart draws the no-data overlay instead of axes and marks. |
noDataLabel | string | - | Text for the vanilla default no-data overlay (ignored when suppressed). |
suppressDefaultOverlay | boolean | - | A framework wrapper sets this to render its OWN loading/no-data node instead. |
onHighlightItem | (labels: string[]) => void | - | Called when the hovered, pinned or cleared label changes (only on a change: moving within one jet does not re-fire; leaving every jet fires []) |
style | "jet" | "plume" | - | Deprecated ignored since core 1.29; emits an ignored-option warning. There is one look now: stem, fountain, small dots, big dot. |
frothLayers | number | - | Deprecated ignored since core 1.29; emits an ignored-option warning |
bloomExponent | number | - | Deprecated ignored since core 1.29; emits an ignored-option warning |
stemFraction | number | - | Deprecated ignored since core 1.29; emits an ignored-option warning |
showDroplets | boolean | - | Deprecated ignored since core 1.29; emits an ignored-option warning |
showMist | boolean | - | Deprecated ignored since core 1.29; emits an ignored-option warning |
Common props - shared by every chart (14)
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | 900 | Chart width in pixels |
height | number | 480 | Chart height in pixels |
margin | Margin | { top: 50, right: 40, bottom: 50, left: 60 } | Inner margins (top/right/bottom/left, in px); default 8 (36 top with a title) |
colors | string[] | - | Categorical palette for rings without an explicit colour or colorsMapping entry |
colorsMapping | Record<string, string> | - | Explicit label -> colour map; takes precedence over the palette and per-item colours |
highlightItems | string[] | - | Labels to emphasise (active styling); others keep their base opacity |
disabledItems | string[] | - | Labels to hide entirely (ring + track removed; remaining rings keep their radii order) |
renderer | "svg" | "canvas" | "webgpu" | "svg" | Render as inline SVG (default) or to a canvas / WebGPU layer; getContext() is identical either way |
locale | string | - | BCP-47 locale used for number formatting |
skipColorMappingDispatch | boolean | false | External-CSS mode: unmapped labels resolve to transparent and onColorMappingGenerated is not emitted, so arc colours come from your CSS via the data-label-safe contract |
enableTransitions | boolean | true | Animate opacity/arc changes with CSS transitions (SVG renderer; default true) |
onColorMappingGenerated | (mapping: Record<string, string>) => void | - | Called with the resolved label -> colour map after the chart assigns colours |
onChartDataProcessed | (context: ChartContext) => void | - | Called with the renderer-agnostic ChartContext whenever the data is (re)processed |
onDataWarning | (warnings: DataWarning[]) => void | - | Called with any non-fatal data warnings (out-of-range values, duplicate labels, ...) |
Twee modi, één datavorm
Stel xAxisDataType: "band" in (of laat het weg) voor momentopname-modus: één kolom per label. Geef een temporele of numerieke xAxisDataType plus een date bij elk item voor trendmodus: de jets staan langs de x-as, en bij één reeks verbindt een stippellijn de grote stippen. Een item met forecast: true krijgt een gestippelde steel en rand, een lichtere vulling en een holle grote stip, zonder kleine stippen.
Nieuw in core 1.29
| Prop | Type | Standaard | Wat hij doet |
|---|---|---|---|
showRange | boolean | true | Tekent de fontein, het bereik [low, high]. false tekent alleen de steel en de grote stip; de kleine stippen verdwijnen ook. |
showSamples | boolean | true | Tekent een kleine stip per meting, als items samples hebben. |
showValueLabels | boolean | true | Zet onder elk x-label: vet "usual 30", "<laag woord> 22", "<hoog woord> 55", "only N <sampleWord>" onder 10 metingen, en per referentielijn met goodSide een vet "17 of 20" plus de countLabel. |
drift | boolean | false | De Genève-look: de top van elke fontein buigt dezelfde kant op. Hij draagt geen data. |
yAxisTitle | string | geen | Titel die gedraaid naast de y-as staat, bijvoorbeeld "minuten (hoger = langzamer)". |
endLabels | [string, string] | ["lowest", "highest"] | De woorden voor het lage en het hoge uiteinde in de labels en de tooltip. |
referenceLines | FountainReferenceLine[] | geen | Stippellijnen in de waarschuwingskleur van het thema, met het label aan het rechtereinde. Zie hieronder. |
labels | FountainLabels | Engels | De andere woorden van de grafiek, om te vertalen. Zie hieronder. |
readingGuide | boolean | string | false | Een leeswijzer onder de grafiek, afgebroken tussen twee onderdelen (bij een « · ») als hij niet op één regel past. true toont de standaardtekst, die alleen noemt wat de grafiek tekent (niets over kleine stippen zonder kleine stippen, geen Tall fountain zonder fontein); een string vervangt hem. |
sampleWord | string | "measurements" | Het zelfstandig naamwoord in het meervoud voor de metingen ("dagen", "bestellingen"). Bewust meervoud: er is geen automatisch meervoud. |
showTrendLine heeft nu een standaard per modus: true in trendmodus met één reeks; false met meerdere reeksen, waar één lijn heen en weer tussen de reeksen zou springen, en in momentopname-modus (zet hem op true om een geordende rij categorieën te verbinden).
Data-item: FountainDataItem
| Veld | Type | Wat het is |
|---|---|---|
label | string | De kolom (momentopname) of de naam van de reeks (trend). Bepaalt de kleur en de data-label-hook. |
code | string | Optionele vaste id die in de context komt; wordt niet getoond. |
value | number | De grote stip. Optioneel als er samples zijn: dan hun mediaan. Zonder eindige waarde en zonder metingen wordt de jet overgeslagen. |
low | number | De onderkant van de fontein. |
high | number | De top van de fontein. |
spread | number | Kortere vorm voor een gelijk bereik: low = value - spread, high = value + spread. |
samples | number[] | De echte metingen, elk een kleine stip op de precieze hoogte binnen de fontein. |
forecast | boolean | Een voorspelde periode: gestippelde steel en rand, lichtere vulling, holle grote stip, geen kleine stippen en geen telling. |
color | string | Kleur per item. Volgorde per jet: colorsMapping[label], dan color, dan de paletkleur van het label. |
date | number | string | De x-positie in trendmodus; een item zonder bruikbare datum wordt daar overgeslagen. |
predicted | boolean | Verouderd: gebruik forecast. Werkt nog. |
certainty | boolean | Verouderd: certainty: false is forecast: true. Werkt nog. |
density | number | Verouderd en genegeerd (een waarschuwing ignored-option). |
lean | number | Verouderd en genegeerd (een waarschuwing ignored-option). |
Het bereik komt van de eerste die er is: low/high, dan spread, dan de laagste en hoogste meting; zonder een van die drie heeft de jet geen fontein. Een ontbrekend uiteinde volgt dezelfde volgorde. Metingen buiten een opgegeven bereik, en een waarde buiten het bereik, maken het bereik groter en sturen een waarschuwing. Negatieve waarden mogen: het y-domein bevat 0 en elke low, en de steel loopt vanaf de basislijn naar beneden.
Referentielijn: FountainReferenceLine
| Veld | Type | Wat het is |
|---|---|---|
value | number | Waar de lijn ligt, in y-eenheden. Altijd binnen het automatische y-domein. |
label | string | Staat aan het rechtereinde van de lijn (afgebroken als het moet; de grafiek houdt rechts ruimte vrij). |
goodSide | "below" | "above" | Welke kant goed is. Als hij is ingesteld, telt elke jet met metingen ze: "below" telt de metingen op of onder de lijn, "above" die op of boven de lijn. |
countLabel | string | Woorden na de telling, bijvoorbeeld "op tijd", "geslaagd". Standaard "below the line" of "above the line". |
Woorden: FountainLabels
| Veld | Standaard | Waar het staat |
|---|---|---|
usual | "usual" | Voor de waarde van de grote stip: "usual 30". |
of | "of" | Tussen een telling en het totaal: "17 of 20". |
only | "only" | Voor een klein aantal metingen: "only 5 days". |
forecast | "forecast" | Achter het x-label van een voorspelde jet en in de tooltip: "Fri (forecast)". |
Themavariabelen
De grafiek leest deze CSS-variabelen van zijn host-element (of een voorouder), in elke renderer:
| Variabele | Standaard | Wat het kleurt |
|---|---|---|
--michi-vz-surface | #fff | De achtergrond waarop de grafiek staat: de dunne rand om elke kleine stip en de rand om een grote stip, die ze loshouden van wat eronder ligt. Zet hem bij een donker thema op de achtergrondkleur van je pagina. |
--michi-vz-attention | #c0392b | De referentielijnen, hun labels en de tellingen onder de kolommen. |
--michi-vz-lake | #9cc3dd | De band bij 0 (het meer). |
--michi-vz-ink | currentColor | De trendlijn, de vette regel « usual 30 » en de titel. |
--michi-vz-muted | #666 | De andere waardelabels, de titel van de y-as, de leeswijzer en de aslabels. |
--michi-vz-grid | lightgray | Het dunne lijntje boven de leeswijzer. |
--michi-vz-font-family, --michi-vz-font-size | geërfd, 12px | Elk woord dat de grafiek toont. |
De holle grote stip van een voorspelling is een ring waarbinnen niets wordt getekend (wat eronder ligt, wordt weggeknipt), dus hij blijft hol op elke achtergrond, zonder variabele.
/* De grafieken op een donkere pagina */
.dark .charts {
--michi-vz-surface: #1b1b1f;
--michi-vz-ink: #e3e3e3;
--michi-vz-muted: #a0a0a0;
}Gebeurtenissen
De webcomponent verzendt deze bubbelende CustomEvents (de engine biedt hetzelfde via de on*-callbacks in de tabel hierboven):
| Gebeurtenis | Detail | Treedt op wanneer |
|---|---|---|
michi-vz:highlight | string[] | de jet onder de muis verandert (het label) |
michi-vz:colormapping | Record<string, string> | er een kleurtoewijzing wordt gegenereerd |
michi-vz:dataprocessed | ChartContext | gegevens worden (opnieuw) verwerkt |
michi-vz:datawarning | DataWarning[] | er waarschuwingen over de invoer zijn (zie Waarschuwingen) |
getContext()
mountFountainChart(el, props).getContext() geeft een renderer-onafhankelijke FountainChartContext:
mode:"snapshot"voor een categorische (band-)x,"trend"voor een temporele of numerieke x.xAxis:{ type, domain }, de kolomlabels in momentopname-modus of[min, max]in trendmodus.yAxis:{ domain }.jets: één item per getekende jet (in x-volgorde in trendmodus):
| Veld | Wat het is |
|---|---|
label, code, color | Het label van de jet, de optionele id en de uiteindelijke kleur. |
value | De grote stip. |
low, high | De onderkant en de top van de fontein; null zonder bereik. |
range | high - low; null zonder bereik. |
rangeRatio | range / |value|: hoe groot het bereik is naast het getal. null als de waarde 0 is of er geen bereik is. |
sampleCount | Aantal kleine stippen. |
referenceCounts | Eén { value, goodSide, count, total, countLabel } per referentielijn met goodSide; [] voor een voorspelling of een jet zonder metingen. |
predicted | true voor een voorspelde jet. |
xPosition | De ruwe date in trendmodus, null in momentopname-modus. |
spread | Verouderd: (high - low) / 2, 0 zonder bereik. Gebruik range. |
spreadRatio | Verouderd: spread / |value|, 0 als het niet te berekenen is. Gebruik rangeRatio. |
upperBound | Verouderd: high (of de waarde zonder bereik). Gebruik high. |
lean | Verouderd: altijd null. |
stats:jetCount: aantal getekende jets.tallest:{ label, value }van de grootste waarde, ofnull.widestRange:{ label, range }van het breedste bereik, ofnullals geen jet een bereik heeft.frothiest: verouderd.{ label, spreadRatio }van de jet met de grootsterangeRatio. GebruikwidestRangeofjets[].rangeRatio.trendSlope: helling (kleinste kwadraten) van de waarden per periode (trendmodus, één reeks); andersnull.valueRange:[min, max]van de waarden, ofnull.predictedCount: aantal voorspelde jets.
legendData: elk label van de heledataSetmet zijn kleur, in volgorde van voorkomen; uitgeschakelde labels blijven staan metdisabled: true. In trendmodus alleen bij meer dan één reeks.summary: één zin in gewone woorden (in het Engels), bijvoorbeeldFountain chart "How long is my commute, really?" with 4 jets. Highest usual value: Bus at 40. Widest range: Car, from 22 to 55.a11yTable: kolommenLabel,Usual, de tweeendLabels,Samples, en één kolom per referentielijn metgoodSide(met decountLabelals kop, cellen zoals"17 of 20"); trendmodus zetPeriodvooraan. Het label van een voorspelde jet krijgt "(forecast)" erachter: zijn rij in trendmodus luidt["Year 4", "Battery (forecast)", …].
Zie LLM-context voor hoe je de context gebruikt in prompts en rapporten.
Waarschuwingen
onDataWarning (en de gebeurtenis michi-vz:datawarning) krijgt DataWarning[], elk { type, message, label? }. De grafiek tekent data nooit stilletjes anders: elke reparatie wordt gemeld.
type | Wanneer | Wat de grafiek doet |
|---|---|---|
non-finite-value | Een item heeft geen eindige value en geen metingen, of sommige metingen zijn niet eindig. | Slaat de jet over (ook in de stats), of laat die metingen weg. Een ontbrekende waarde met metingen wordt hun mediaan. |
range-excludes-value | low/high (of spread) laten de waarde erbuiten. | Maakt het bereik groter zodat de waarde erin valt. |
sample-outside-range | Een meting ligt buiten een opgegeven bereik. | Maakt het bereik groter zodat de meting erin valt. |
inverted-range | low ligt boven high, of spread is negatief. | Draait de uiteinden om (gebruikt de grootte van de spreiding). |
missing-date | Trendmodus, maar het item heeft geen bruikbare date. | Slaat het item over (de grafiek blijft in trendmodus). |
duplicate-date | Twee jets hebben dezelfde datum in trendmodus. | Tekent ze over elkaar. |
duplicate-label | Een label komt vaker voor in momentopname-modus. | De jets delen één kolom. |
out-of-domain | Een waarde, een uiteinde of een meting ligt buiten een opgegeven yAxisDomain, of een referentielijn. | Houdt de tekening binnen de grafiek; kleine stippen en lijnen erbuiten worden niet getekend. |
ignored-option | Een verwijderde prop is ingesteld, of een item heeft density of lean. | Negeert hem. |
empty-dataset | De dataSet is leeg. | Toont de geen-data-overlay ("No data available", je noDataLabel, of je eigen met suppressDefaultOverlay) in plaats van assen en marks. isNodata: false tekent de lege assen. |
layout-overflow | Elke jet krijgt minder dan 24 px, of de waardelabels passen niet (smalle kolommen, gedraaide x-labels, jets in één kolom, of een grafiek die te laag is). | Tekent de jets toch en laat de waardelabels weg die niet passen, eerst de woorden voor de uiteinden. Maak de grafiek breder, toon minder jets of voeg samen. |
Verouderd
Dit werkt allemaal nog in core 1.29 en verdwijnt in een latere release. Zie Overstappen vanaf core 1.28.
- Props, genegeerd met een waarschuwing
ignored-option:style,frothLayers,bloomExponent,stemFraction,showDroplets,showMist. Op de web component:fountainStyle(fountain-style). - Velden van items:
predictedencertaintywerken nog; gebruikforecast.densityenleanworden genegeerd met een waarschuwing. - Velden van de context:
jets[].spread,jets[].spreadRatio,jets[].upperBoundenjets[].lean(altijdnull);stats.frothiest. Gebruikrange,rangeRatio,highenstats.widestRange.
Bron
Props zijn getypeerd als FountainChartProps in @michi-vz/core.
