'use client'; import 'uplot/dist/uPlot.min.css'; import uPlot from 'uplot'; import { CardShell } from './CardShell'; import { AXIS_BASE, CURSOR_NO_DRAG, makeYScale } from './plotHelpers'; import { usePlot } from './usePlot'; import type { ChartConfig, UpsRow, TimeMode } from '@/lib/types'; import { formatSI } from '@/lib/formatNumber'; interface Props { config: ChartConfig; upsRows: UpsRow[]; timeMode: TimeMode; onEdit: () => void; onDelete: () => void; } export default function UpsChart({ config, upsRows, timeMode, onEdit, onDelete }: Props) { const { containerRef, legendRef } = usePlot( (el, w, h, lRef) => { if (upsRows.length < 2) return null; const sorted = [...upsRows].sort((a, b) => timeMode === 'tick' ? a.game_tick - b.game_tick : new Date(a.real_time).getTime() - new Date(b.real_time).getTime(), ); const xs = sorted.map((r) => timeMode === 'tick' ? r.game_tick : new Date(r.real_time).getTime() / 1000, ); const ys = sorted.map((r) => r.ups); const xAxis: uPlot.Axis = { ...AXIS_BASE, values: timeMode === 'real' ? (_u, vals) => vals.map((v) => (v == null ? '' : new Date(v * 1000).toLocaleTimeString())) : (_u, vals) => vals.map((v) => (v == null ? '' : formatSI(v))), }; return new uPlot( { width: w, height: h, cursor: CURSOR_NO_DRAG, legend: { mount: (_u, legendEl) => { if (lRef.current) lRef.current.appendChild(legendEl); }, }, series: [ { label: timeMode === 'tick' ? 'Tick' : 'Time' }, { label: 'UPS', stroke: '#4ade80', width: 1.5 }, ], axes: [ xAxis, { ...AXIS_BASE, values: (_u, vals) => vals.map((v) => (v == null ? '' : formatSI(v))) }, ], scales: { x: { time: false }, y: makeYScale(config.y_min ?? null, config.y_max ?? null, config.y_scale), }, }, [xs, ys], el, ); }, [upsRows, config.y_min, config.y_max, config.y_scale, timeMode], ); return (
} className="w-full h-full" /> ); }