Incremental chart updates in ApexChart (updateSeries instead of full re-render) #23

Closed
opened 2026-07-28 16:53:53 +00:00 by claude-bot · 1 comment
Collaborator

Problem

ApexChart exposes exactly one path to the client:

protected void sendOptions(Map<String, Object> options) {
    getElement().callJsFunction("renderChart", MAPPER.writeValueAsString(options));
}

renderChart in frontend/components/apex-chart.ts tears the chart down and builds it again. Every data change is a full destroy + rebuild: the chart flashes, animations restart from zero, and any zoom/selection state is lost.

That is fine for a one-shot dashboard. It is not fine as soon as data can change — refresh buttons, polling, a global date filter, or @Push-driven live updates all become visibly janky.

Proposal

  • Add an updateSeries (and optionally appendData) client function to apex-chart.ts that calls ApexCharts' own updateSeries / updateOptions on the existing instance.
  • Expose a server-side updateData(...) on AxisChart / PieChart that sends only series and categories, falling back to a full renderChart when no chart instance exists yet.
  • Keep the theme overlay behaviour (applyThemeOverlay()) correct across incremental updates — it currently runs as part of the render path.

Once this exists, the follow-ups become cheap:

  • per-widget refresh action,
  • UI.setPollInterval or @Push for auto-refreshing widgets,
  • re-filtering all widgets from a global filter bar without the whole dashboard blinking.

Acceptance criteria

  • Changing a chart's data updates the SVG in place; no full rebuild.
  • First render still works unchanged.
  • Light/dark theme overlay stays correct after an incremental update.
  • Playwright e2e asserting the chart element is not recreated on data change.

Depends on

Data service layer — without a way to get new data, there is nothing to push through this path.

Scope

Small to medium, mostly in apex-chart.ts plus a thin Java API.

## Problem `ApexChart` exposes exactly one path to the client: ```java protected void sendOptions(Map<String, Object> options) { getElement().callJsFunction("renderChart", MAPPER.writeValueAsString(options)); } ``` `renderChart` in `frontend/components/apex-chart.ts` tears the chart down and builds it again. Every data change is a full destroy + rebuild: the chart flashes, animations restart from zero, and any zoom/selection state is lost. That is fine for a one-shot dashboard. It is not fine as soon as data can change — refresh buttons, polling, a global date filter, or `@Push`-driven live updates all become visibly janky. ## Proposal - Add an `updateSeries` (and optionally `appendData`) client function to `apex-chart.ts` that calls ApexCharts' own `updateSeries` / `updateOptions` on the existing instance. - Expose a server-side `updateData(...)` on `AxisChart` / `PieChart` that sends only series and categories, falling back to a full `renderChart` when no chart instance exists yet. - Keep the theme overlay behaviour (`applyThemeOverlay()`) correct across incremental updates — it currently runs as part of the render path. Once this exists, the follow-ups become cheap: - per-widget refresh action, - `UI.setPollInterval` or `@Push` for auto-refreshing widgets, - re-filtering all widgets from a global filter bar without the whole dashboard blinking. ## Acceptance criteria - Changing a chart's data updates the SVG in place; no full rebuild. - First render still works unchanged. - Light/dark theme overlay stays correct after an incremental update. - Playwright e2e asserting the chart element is not recreated on data change. ## Depends on Data service layer — without a way to *get* new data, there is nothing to push through this path. ## Scope Small to medium, mostly in `apex-chart.ts` plus a thin Java API.
claude-bot added the enhancement label 2026-07-28 16:53:53 +00:00
pitfriedrich added the ai-ready label 2026-07-28 17:17:51 +00:00
claude-bot added the ai-wip label 2026-07-28 17:18:22 +00:00
Author
Collaborator

PR: #32

updateData patches the live ApexCharts instance (updateSeries, plus updateOptions only when categories/labels change); AxisChart.updateData / PieChart.updateData fall back to setData before the first render. Theme overlay is re-applied to the merged options.

Covered by ApexChartUpdateTest (browserless, asserts the queued client call) and DashboardChartPlaywrightTest (Chromium, asserts the <svg> node is not recreated). ./mvnw test: 16/16 green.

Not part of this PR (follow-ups from the issue): per-widget refresh action, polling/@Push, global filter bar — no data service layer yet, so nothing drives the new path in the UI.

PR: https://gitea.pitfriedrich.net/pitfriedrich/chart-app/pulls/32 `updateData` patches the live ApexCharts instance (`updateSeries`, plus `updateOptions` only when categories/labels change); `AxisChart.updateData` / `PieChart.updateData` fall back to `setData` before the first render. Theme overlay is re-applied to the merged options. Covered by `ApexChartUpdateTest` (browserless, asserts the queued client call) and `DashboardChartPlaywrightTest` (Chromium, asserts the `<svg>` node is not recreated). `./mvnw test`: 16/16 green. Not part of this PR (follow-ups from the issue): per-widget refresh action, polling/`@Push`, global filter bar — no data service layer yet, so nothing drives the new path in the UI.
claude-bot added ai-review and removed ai-wipai-ready labels 2026-07-28 17:29:53 +00:00
Sign in to join this conversation.