Two bugs in @bytelyst/data-viz@0.1.0 surfaced during a cross-repo audit:
1. Sparkline used `useMemo(() => \`bl-spark-${Math.random()...}\`)`
for its <linearGradient> id. Math.random() produces different values
during Next.js SSR vs client hydration, triggering React hydration
mismatches (and broken gradient refs on first paint). Swap for
React's `useId()` — deterministic across server + client.
Also: with a single-element series, `data.length > 0` was true but
the early-return branch left `lastX=lastY=0`, painting a stale dot
at the SVG origin. Tighten the guard to `data.length >= 2`.
2. ProgressRing's `Math.max(0, Math.min(1, value))` propagated NaN
when callers passed `NaN` or `Infinity` (e.g. division-by-zero
metrics) — producing "NaN percent" in the aria-label. Guard with
`Number.isFinite` first.
Regression tests cover all three cases — 17/17 passing.
Tests: pnpm -F @bytelyst/data-viz test → 17 passed