Layout only returns geometry — interactivity is entirely yours. This example attaches pointer handlers to each SVG word so users can explore terms. The pattern works for tooltips, filtering, drill-down links, and selection state in analytics dashboards.
text but not the
original weight. Build a Map(text → weight) before layout so
tooltips and click handlers can show the value behind each word.
Interaction flow:
layout() and render each word as its own SVG element (or Canvas
region with manual hit-testing).pointerenter, dim non-hovered words and show a tooltip with
text + weight.click, pin the selection or fire an app event (e.g. filter a table
by the clicked term).export function bindWordInteractions(el, { text, weight }, handlers) { el.style.cursor = "pointer"; el.addEventListener("pointerenter", () => handlers.onHover(text, weight)); el.addEventListener("pointerleave", () => handlers.onLeave()); el.addEventListener("click", () => handlers.onSelect(text, weight)); }
If you render on Canvas, store placements and on mousemove test whether the
pointer falls inside each word's axis-aligned bbox (approximate: half the string width from
measureText, half the fontSize in height). SVG avoids this
bookkeeping — the browser does hit-testing for free.
Hover a word to highlight it and see a tooltip; click to pin the selection. Switch between 50- and 500-word random datasets, or go fullscreen to explore a larger layout area.
Presets tune minFontSize / maxFontSize so words stay readable
at each scale (50 → 16–88px, 500 → 10–52px). Fullscreen lays out against the viewport
so you can see the engine's maximum placement count.