Meter (ringen) API
Concentrische ringen, van buiten naar binnen, die elk (value - min) / (max - min) van een volledige cirkel over een achtergrondspoor bestrijken - zie de Meter-demo.
Import
ts
import "@michi-vz/wc/gauge-chart";
// <michi-vz-gauge-chart> is now definedts
import { mountGaugeChart } from "@michi-vz/core";
const chart = mountGaugeChart(el, props);ts
import { GaugeChart } from "@michi-vz/react/gauge-chart";ts
import { GaugeChart } from "@michi-vz/vue/gauge-chart";ts
import { gaugeChart } from "@michi-vz/svelte/gauge-chart";ts
import { bindChart, applyGaugeChartProps } from "@michi-vz/angular/gauge-chart";
// needs CUSTOM_ELEMENTS_SCHEMA on the component that hosts <michi-vz-gauge-chart>Props
| Prop | Type | Default | Description |
|---|---|---|---|
dataSet* | GaugeRingDatum[] | - | Rings, OUTER to INNER; each sweeps value/max of the circle over a track |
title | string | - | Optional chart title rendered above the plot |
max | number | 100 | Value corresponding to a full sweep - the entire `sweepAngle` (360° by default; e.g. with `sweepAngle: 180`, `value === max` fills the whole half) (default 100). |
min | number | 0 | Value at the START of the sweep (default 0). A ring maps `(value - min) / (max - min)` onto the sweep and values are clamped into [min, max]. When `max <= min` the chart warns and falls back to 0..max, so bounds computed from data that collapses never yield an empty or reversed gauge. |
ringThickness | number | 18 | Ring stroke thickness in px (default 18). |
ringGap | number | 2 | Gap between adjacent rings in px (default 2). |
outerRadius | number | null | Outermost ring's outer edge radius in px; default fills the plot box. |
startAngle | number | 0 | Arc start angle in degrees, 0 = 12 o'clock, positive clockwise (default 0). |
sweepAngle | number | 360 | Angular extent of the gauge in degrees, clockwise from `startAngle` (default 360 = a full ring). 180 with `startAngle: -90` gives the classic half gauge. Both the track and the value arc span this range, and a ring's value is measured against it: at `sweepAngle: 180`, `value === max` fills the whole half. Clamped to (0, 360]: an unset, zero, or negative value falls back to a full 360° ring, NOT an empty gauge - a consumer computing `sweepAngle` from a ratio that can hit 0 gets a full circle. |
sweepFit | boolean | false | Fit the layout to the SWEPT arc instead of the full circle: the outer radius grows until the arc's bounding box fills the plot, the box is centred, and the centre readout anchors to the box's middle (inside a half gauge, above its baseline). While `ticks` or `endLabels` are present a 36px band is reserved on every side for them. An explicit `outerRadius` still wins; only the placement is fitted. On a full 360° ring only the reserve for ticks applies (end labels are skipped there). Default false. |
ticks | GaugeTick[] | - | Reference ticks on the OUTER ring: a short radial line just outside the arc plus a two-line label (caption over value) further out. Values are clamped into [min, max] with a warning; order is irrelevant. Ticks describe the scale, so a multi-ring gauge draws them once. |
endLabels | boolean | { min?: GaugeEndLabel; max?: GaugeEndLabel } | - | Labels under the two ends of a PARTIAL sweep: min at the start end, max at the end. `true` draws only the formatted values; the object form adds captions. Ignored with a warning on a full 360° ring, where both ends coincide. |
valueMarker | boolean | GaugeValueMarker | - | Marker at each ring's value: a circle on the arc centreline with a radial tick through it, filled with the ring's colour. Rings whose value is null get no marker. `true` uses the defaults in `GaugeValueMarker`. |
gradient | string[] | - | Multi-stop colour ramp for every ring's arc, as a LINEAR gradient across the plot box (evenly spaced stops). A ring's own `gradient` wins. The ramp is anchored to the FULL sweep, not the drawn portion, so a half-full gauge shows the first half of the ramp rather than the whole ramp compressed. Overrides the resolved solid colour. |
roundedCaps | boolean | false | Round the arc ends (default false = square caps). |
ringOpacity | number | number[] | 1 | Arc opacity per ring, outer→inner; a single number applies to every ring (default 1). |
trackColor | string | string[] | "#00000014" | Track colour(s) behind the arcs, outer→inner; per-ring `trackColor` wins (default "#00000014"). |
trackOpacity | number | number[] | 1 | Track opacity per ring, outer→inner (default 1). |
defaultActive | number | "inner" | "outer" | null | - | The ring active when nothing is hovered: a dataSet index, "inner"/"outer", or null for none (default "inner"). |
activeStyle | GaugeActiveStyle | {} | Emphasis applied to the active ring (default { opacity: 1 }). |
showCenterLabel | boolean | true | Draw the built-in centre label: active ring's name + formatted value (default true). Turn off to render your own centre overlay (drive it via onHighlightItem). |
centerContent | (ring: GaugeRingContext | null) => string | - | Custom centre HTML for the active ring (sanitized before insertion); wins over the default label+value markup. Receives null when no ring is active. |
valueFormatter | (v: number) => string | - | Formats a ring value for the centre label and tooltips (default `${v}%`). |
noValueLabel | string | - | Centre value text for an active ring with no data (default "n/a"). |
fontFamily | string | - | Font family for the title/centre label; sets the --michi-vz-font-family CSS var |
isLoading | boolean | - | Show the loading overlay and skip the no-data check |
isNodata | boolean | ((dataSet: GaugeRingDatum[] | null | undefined) => boolean) | - | No-data override: boolean, or a predicate on dataSet; default = empty dataSet (rings whose value is null still RENDER, as empty tracks). |
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 | (ring: GaugeRingContext) => string | - | Opt-in hover tooltip HTML for a ring (sanitized). Default: no tooltip - the centre label is the built-in readout. |
annotationTooltipFormatter | (annotation: GaugeAnnotationContext) => string | null | - | Opt-in hover tooltip HTML for ONE annotation - a value marker, a reference tick or an end label (sanitized). Default: none; the annotations are inert. The drawn annotations take no pointer events, so this is resolved from geometry at the host level and behaves identically in the svg, canvas and webgpu renderers. Hovering an annotation does NOT change which ring is active, so the centre readout stays put while the reader inspects a reference value. Return null or "" to show nothing for that annotation - a marker with no value never exists in the first place, while the scale's ticks and end labels stay hoverable. |
onHighlightItem | (labels: string[]) => void | - | Called with the hovered ring's label (empty array on leave) |
Common props - shared by every chart (14)
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | 300 | Chart width in pixels |
height | number | 300 | Chart height in pixels |
margin | Margin | { top: p.title ? 36 : 8, right: 8, bottom: 8, left: 8 } | 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, ...) |
Events
Het web component verstuurt deze bubbelende CustomEvents (de engine biedt dezelfde via de on*-callbacks in de tabel hierboven):
| Event | Detail | Fires when |
|---|---|---|
michi-vz:highlight | string[] | hover highlight changes |
michi-vz:colormapping | Record<string, string> | a color mapping is generated |
michi-vz:dataprocessed | ChartContext | data is (re)processed |
michi-vz:datawarning | DataWarning[] | input warnings are detected |
getContext()
mountGaugeChart(el, props).getContext() geeft een renderer-onafhankelijke GaugeChartContext: de max-schaal, de rings (label / value / fraction / index, van buiten naar binnen), statistieken (aantal ringen, grootste ring), een deterministische samenvatting in natuurlijke taal en een a11y-tabel. Zie LLM-context.
Source
Props zijn getypeerd als GaugeChartProps in @michi-vz/core.
