Lijndiagram API
Alles wat je nodig hebt om een lijndiagram in code op te zetten; voor het verhaal en de demo's, zie de Lijndiagram-demo.
Import
import "@michi-vz/wc/line-chart";
// <michi-vz-line-chart> is now definedimport { mountLineChart } from "@michi-vz/core";
const chart = mountLineChart(el, props);Eigenschappen
| 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. |
dataSet* | LineDataItem[] | - | Array of line series, each with its own points |
title | string | - | Optional chart title rendered above the plot |
yAxisDomain | [number, number] | - | Fix the y-axis range as [min, max] instead of deriving it from the data |
yAxisScale | "linear" | "log" | "linear" | Y-axis scale: "linear" (default) or a base-10 "log" scale. In "log" mode, a non-positive value (<= 0) can't be plotted, so those points are dropped as missing (reported via `onDataWarning`); a dataSet with no positive values at all renders the no-data state instead. |
xAxisDataType | "date_annual" | "date_monthly" | "number" | "number" | How x values are parsed and formatted: yearly dates, monthly dates, or plain numbers |
xAxisFormat | (d: number | string) => string | - | Formats an x tick value into its display label |
yAxisFormat | (d: number | string) => string | - | Formats a y tick value into its display label |
ticks | number | 5 | Approximate number of x-axis ticks to generate |
yTicks | number | - | Number of y-axis ticks (default 10, matching the legacy denser value axis). |
showGridLines | boolean | - | Draw horizontal dashed grid lines at each y tick (default true). |
showVerticalGridLines | boolean | - | Draw vertical dashed grid lines at each x tick (default false - the legacy chart drew none). |
highlightZeroLine | boolean | - | Emphasise the y=0 grid line with a darker solid stroke (default true). |
tickValues | Array<number | Date> | - | Explicit tick values, overriding the generated ones |
fillPeriodTicks | boolean | - | Draw a tick for EVERY period across the axis range (every month/year), not just the periods present in the data. Periods with no value render faded and show `noDataTickTooltip` on hover. Opt-in; default false. |
noDataTickTooltip | (date: number) => string | - | Tooltip content (plain text or sanitized HTML) for a faded no-data tick; receives the tick's epoch-ms value. Used only with `fillPeriodTicks`. Default: a localized "Data not available". |
noDataTickColor | string | - | Colour for faded no-data tick labels; sets the `--michi-vz-tick-nodata` CSS var on the host. Used only with `fillPeriodTicks`. |
curve | "curveBumpX" | "curveLinear" | "curveMonotoneX" | - | Default interpolation for every series (per-series `curve` wins). |
detectGaps | boolean | false | Auto-derive `certainty` from missing periods (dashes the gap segment). |
expectedStep | number | - | Expected cadence in axis units; REQUIRED for xAxisDataType "number". |
showDataPoints | boolean | false | Whether to draw a marker at each data point (default false) |
enableMouseLine | boolean | MouseLineConfig | true | Solid vertical crosshair line snapped to the nearest data point x on hover; pass a config object to style it (default true) |
singlePointLine | boolean | SinglePointLineConfig | - | true / config draws a horizontal guide line for single-point series. |
fontFamily | string | - | Font family for axis/title/tooltip text (SVG + canvas). Sets the --michi-vz-font-family CSS var so both renderers resolve it. |
filter | Filter | - | Top-N / sort filter applied to the data before rendering |
progressiveDraw | boolean | ProgressiveDrawConfig | - | Animate each line drawing itself left to right on mount (progressive reveal). `true` uses defaults; pass a config to tune duration, easing, tip labels, and autoplay. Off by default, so existing charts are unchanged. Respects prefers-reduced-motion: the chart then renders fully drawn instantly. Ignored by the webgpu renderer. |
isLoading | boolean | - | Show the loading overlay and skip the no-data check (legacy michi-vz parity). |
isNodata | | boolean | ((dataSet: LineDataItem[] | null | undefined) => boolean) | - | No-data override: boolean, or a predicate on dataSet; default = empty/all-empty-series. |
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. |
tooltipFormatter | ( d: DataPoint, series: DataPoint[], dataSet: LineDataItem[], ) => string | - | Returns custom tooltip HTML for a hovered datum (sanitized before it is inserted) |
sharedTooltip | boolean | false | When true, hovering anywhere in the plot shows ONE tooltip listing every series' value at the nearest x (year) - the "shared"/crosshair tooltip - instead of the single nearest series. Pairs with the crosshair (enableMouseLine, on by default). |
sharedTooltipFormatter | (input: { x: number | string; xLabel: string; entries: Array<{ label: string; value: number; color: string; d: DataPoint }>; }) => string | - | Custom HTML for the shared tooltip. `entries` is one row per series that has a point at the hovered x, in dataSet order, each with its resolved colour. |
onHighlightItem | (labels: string[]) => void | - | Called when the hovered/highlighted label(s) change |
svgChildren | string | - | Pre-serialised SVG markup injected as direct <svg> children (axis-title text, reference lines). The React wrapper fills this from `children`; mirrors the legacy <LineChart>'s `{children}` slot. |
Common props - shared by every chart (14)
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | 1000 | Chart width in pixels |
height | number | 500 | Chart height in pixels |
margin | Margin | { top: 50, right: 50, bottom: 50, left: 60 } | Inner margins (top/right/bottom/left, in px) reserved for axes, titles, and labels |
colors | string[] | - | Categorical palette for series/labels 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; all other marks dim |
disabledItems | string[] | - | Labels to hide and exclude from scales/stacks |
renderer | "svg" | "canvas" | "webgpu" | "svg" | Render as inline SVG (default) or to a canvas (faster for large datasets); getContext() is identical either way |
locale | string | - | BCP-47 locale used for number and date formatting |
skipColorMappingDispatch | boolean | false | External-CSS mode: unmapped labels resolve to transparent and onColorMappingGenerated is not emitted, so mark colours come from your CSS via the data-label-safe contract |
enableTransitions | boolean | true | Animate updates with CSS transitions (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 (duplicate labels, non-finite values, non-monotonic dates, ...) |
Raster- en asweergave
Vier eigenschappen bepalen de dichtheid van de y-astickmarks en het tekenen van rasterlijnen:
| Eigenschap | Standaardwaarde | Opmerkingen |
|---|---|---|
yTicks | 10 | Geschat aantal tickmarks op de y-as. De oorspronkelijke standaardwaarde was 10; kies een lagere waarde (bijv. 5) voor een as met minder tickmarks. |
showGridLines | true | Horizontale onderbroken rasterlijnen bij elke y-tick. |
showVerticalGridLines | false | Verticale onderbroken rasterlijnen bij elke x-tick. Het legacy-diagram tekende deze niet; schakel dit alleen in wanneer de extra hulplijnen de leesbaarheid ten goede komen. |
highlightZeroLine | true | Tekent de y=0-lijn als een doorgetrokken lijn (gekleurd via --michi-vz-zero-line, met terugval op de rasterkleur) in plaats van een gewone onderbroken tick. Handig wanneer een dataset zowel positieve als negatieve waarden bevat. |
Laad- en 'geen data'-status
De engine beheert een data-mv-state-attribuut op het host-element met drie mogelijke waarden - "loading", "nodata" en "ready" - en toont voor de eerste twee ingebouwde overlays, tenzij je dit uitschakelt.
| Eigenschap | Type | Standaardwaarde | Opmerkingen |
|---|---|---|---|
isLoading | boolean | false | Toont de .mv-loading-overlay en slaat de controle op geen data volledig over. |
isNodata | boolean | (dataSet) => boolean | - | Overschrijft het standaardpredicaat (lege dataSet of elke serie heeft nul punten). Geef false door om het diagram te forceren te renderen, ook wanneer de data leeg lijkt. |
noDataLabel | string | - | Tekst die wordt getoond in de standaard .mv-nodata-overlay. Wordt genegeerd wanneer suppressDefaultOverlay true is. |
suppressDefaultOverlay | boolean | false | Voorkomt dat de engine zijn eigen laad-/geen-data-node injecteert. Gebruik dit wanneer een framework-wrapper (bijv. de LineChart van @michi-vz/react) in plaats daarvan isLoadingComponent / isNodataComponent als React-overlay rendert. De host wordt nooit unmount - de overlay wordt er alleen bovenop gelegd. |
Gedrag van de React-wrapper
De LineChart van @michi-vz/react stelt automatisch suppressDefaultOverlay in en rendert isLoadingComponent / isNodataComponent als een gepositioneerde React-node boven de host van het diagram. De DOM van het diagram is altijd gemount, dus isNodataComponent wordt ook bij lege data nog altijd geactiveerd, zelfs zonder aangepast predicaat.
Lettertypefamilie
fontFamily stelt de CSS custom property --michi-vz-font-family in op het host-element; deze wordt gelezen door zowel de SVG-tekstrenderer als de getComputedStyle-probe van canvas. Het lettertype moet al door de pagina geladen zijn - er wordt geen lettertype ingebed.
ChartContext / legendData
onChartDataProcessed ontvangt een LineChartContext die BaseChartContext uitbreidt. De basis bevat nu een legendData-veld:
interface LegendItem {
label: string; // series label as it appears in dataSet
color: string; // resolved colour at the time of processing
order: number; // appearance order (legend slot index)
disabled?: boolean; // true when the label is currently hidden
dataLabelSafe?: string; // sanitizeForClassName(label) - the CSS hook the canvas colour probe matches
}
interface BaseChartContext {
// ... existing fields ...
legendData?: LegendItem[]; // populated by LineChart; treat absence as []
}legendData is de canonieke payload voor kleurautoriteiten aan de kant van de consument. Een framework-wrapper die zijn eigen kleur-CSS aanstuurt (bijv. useChartUtils van thd MonitorV2) leest bij elke aanroep van onChartDataProcessed legendData[].{label, dataLabelSafe, color, disabled} en genereert per label stroke/fill-regels die het data-label-safe-attribuut targeten. Dit maakt het niet langer nodig om colorsMapping te kruisverwijzen met de volgorde van de series.
Gebeurtenissen
Het webcomponent verzendt deze bubbelende CustomEvents (de engine biedt dezelfde functionaliteit via de on*-callbacks in de tabel hierboven):
| Gebeurtenis | Detail | Wordt geactiveerd wanneer |
|---|---|---|
michi-vz:highlight | string[] | de hover-markering verandert |
michi-vz:colormapping | Record<string, string> | een kleurmapping wordt gegenereerd |
michi-vz:dataprocessed | ChartContext | data (opnieuw) wordt verwerkt |
michi-vz:datawarning | DataWarning[] | invoerwaarschuwingen worden gedetecteerd |
getContext()
mountLineChart(el, props).getContext() retourneert een renderer-onafhankelijke LineChartContext (gestructureerde statistieken + een deterministische samenvatting in gewone taal + een a11y-tabel). Zie LLM-context.
Bron
Eigenschappen zijn getypeerd als LineChartProps in @michi-vz/core.
