Why resize handling matters
ECharts measures its container once at init. Without a resize hook it stays at that initial size forever — a chart inside a sidebar that opens later, a dashboard tile that re-flows when the parent grid changes columns, or any chart embedded in an HTMX-swapped fragment will all render at the wrong dimensions.
What phaChart does
On init(), the Alpine factory attaches a
ResizeObserver to the chart container and calls
chart.resize() whenever the container's box changes — whether that's the viewport
resizing or the container alone reflowing (a drawer opening, a grid cell growing, an HTMX swap resizing the
parent). The callback is debounced to one resize per animation frame, so the observer firing during ECharts' own
re-layout can't loop. On destroy() it disconnects the observer and disposes the ECharts
instance, so there's no leak.
Where ResizeObserver isn't available the factory falls back to a
window resize listener. To opt out of resizing entirely pass
phaChart({ option, autoResize: false }); you keep
getChart().resize() as a public method to call manually.
Container-driven resize
Because the observer watches the container and not the window, a chart re-lays-out even when the viewport never changes. Drag the resize grip in the bottom-right corner of the box below — the chart tracks it, and the legend wraps as the width narrows. No extra wiring on the page; this is the default behaviour.
HTMX swaps clean up cleanly
When HTMX replaces a wrapper via outerHTML, Alpine's
destroy() runs on the old node — disconnecting its observer and disposing the old ECharts
instance — and the new node's init() creates a fresh one with its own observer. There's
nothing to wire up.