refactor(frontend): replace recharts with uPlot for charts

Swap the Sparkline chart component (the only chart in the panel) from recharts to uPlot, keeping its public prop API identical so the three consumers (SystemHistoryModal, XrayMetricsModal, NodeHistoryPanel) are untouched. This drops recharts and 32 transitive deps (es-toolkit, victory-vendor, d3, redux, immer), shrinking the chart vendor chunk to ~51KB (22KB gzip).

The uPlot port reimplements every recharts feature on canvas: gradient area fill, spline curves, up to three series, dashed horizontal grid, formatted axes, hover tooltip and marker, reference lines, and min/max extrema dots. Because canvas cannot read CSS variables, axis and ring colors are resolved via getComputedStyle and repainted on theme changes through a MutationObserver on the body class and documentElement data-theme.

Also removes the es-toolkit/compat resolver shim from vite.config.js, which existed only for recharts, and swaps the manualChunks entry to vendor-uplot.

Note: repaint with redraw(false); a bare uPlot redraw() re-runs _setScale and nulls the index-based x-scale, which collapsed the series to a flat, partial line.
This commit is contained in:
MHSanaei
2026-07-08 02:20:30 +02:00
parent bc309ed9f8
commit 8ee79cf447
6 changed files with 487 additions and 581 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ Two key ideas that explain most of the complexity:
**Frontend (`frontend/`):**
- **React 19** + **Ant Design 6** + **Vite 8** + **TypeScript**.
- Data layer: **TanStack Query** (`@tanstack/react-query`) over the native **Fetch API**; **Zod 4** schemas.
- Router: **react-router-dom 7**. Charts: **recharts**. Editor: **CodeMirror 6**.
- Router: **react-router-dom 7**. Charts: **uPlot** (`frontend/src/components/viz/Sparkline.tsx`). Editor: **CodeMirror 6**.
- **Build output goes to `internal/web/dist/`** (see `vite.config.js``outDir`) and is
embedded into the Go binary with `go:embed`. Three HTML entries: `index.html` (panel SPA),
`login.html`, `subpage.html`. The Go server serves the SPA; there is no separate frontend