API Graphique à bulles
Cercles dimensionnés par valeur, attirés en grappe par gravité, chacun pouvant être divisé en un noyau réalisé et un anneau inexploité - voir la démo du Graphique à bulles.
Import
ts
import "@michi-vz/wc/bubble-chart";
// <michi-vz-bubble-chart> is now definedts
import { mountBubbleChart } from "@michi-vz/core";
const chart = mountBubbleChart(el, props);Props
| Prop | Type | Default | Description |
|---|---|---|---|
timeline | boolean | TimelinePeriodConfig | - | Opt-in "play through years": snapshots one period at a time over the distinct per-row `date` values, with a headless controller (`chart.timeline()`) plus an optional built-in play button + scrubber. Off by default; requires rows with `date`. Values tween between periods unless `interpolate: false`. |
dataSet* | BubbleDataItem[] | - | Array of bubbles; each value sets the circle area (bubbles are gravity-packed into a cluster) |
title | string | - | Optional chart title rendered above the plot |
gravity | number | 0.09 | Strength of the pull toward the centre in [0,1] (default 0.09) - higher = tighter cluster ("suck together"). |
chargeStrength | number | 0 | Many-body charge: negative repels, positive attracts (default 0). |
padding | number | 2 | Gap between packed circles in px (default 2). |
fillRatio | number | 0.62 | Fraction of the plot area the bubbles should fill, in (0,1] (default 0.62). |
layoutMode | "sync" | "async" | "sync" | How the force layout settles: "sync" (default; identical layout every render, blocks until settled) or "async" (the SAME deterministic settle, run in ~12ms slices so thousands of bubbles never freeze the page; the loading overlay shows while it runs). |
settleTicks | number | 400 | Force-simulation ticks to settle (default 400); fewer = faster but looser. |
splitLabels | [string, string] | ["Realized", "Untapped"] | Names of the two split parts (default ["Realized","Untapped"]). |
splitOpacity | number | 0.35 | Apparent colour strength of the untapped veil in [0,1] (default 0.35); rendered as solid colour under a white veil so it reads as a lighter tint of the same hue on any background. |
showSplit | boolean | - | Render the realized/untapped split. Defaults to auto-on when any item has `partial`. |
showLegend | boolean | false | Render a 2-swatch split legend (uses splitLabels). |
showLabels | boolean | true | Draw the label inside each bubble when it is large enough (default true). |
filter | { limit: number; sortingDir: "asc" | "desc" } | - | Keep only the top-N bubbles by value. |
valueFormatter | (n: number) => string | - | Formats a numeric value for labels and tooltips |
tooltipFormatter | (bubble: BubbleContext) => string | - | Returns custom tooltip HTML for a hovered datum/mark (sanitized before it is inserted) |
onHighlightItem | (labels: string[]) => void | - | Called when the hovered/highlighted label(s) change |
Common props - shared by every chart (14)
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | 700 | Chart width in pixels |
height | number | 500 | Chart height in pixels |
margin | Margin | { top: 36, right: 8, bottom: 8, left: 8 } | 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, ...) |
Événements
Le composant web émet ces CustomEvents en bubbling (le moteur expose les mêmes via les callbacks on* dans le tableau ci-dessus) :
| Événement | Détail | Se déclenche quand |
|---|---|---|
michi-vz:highlight | string[] | le surlignage au survol change |
michi-vz:colormapping | Record<string, string> | une correspondance de couleurs est générée |
michi-vz:dataprocessed | ChartContext | les données sont (re)traitées |
michi-vz:datawarning | DataWarning[] | des avertissements sur les données d'entrée sont détectés |
getContext()
mountBubbleChart(el, props).getContext() renvoie un BubbleChartContext agnostique du renderer : le tableau plat bubbles (value / partial / remainder / percent), splitLabels, des statistiques de synthèse (nombre de bulles, total, totaux par partie, plus grande bulle, plus grand reliquat), un résumé déterministe en langage naturel, et un tableau d'accessibilité. Voir Contexte LLM.
Source
Les props sont typées comme BubbleChartProps dans @michi-vz/core.
