import { memo, useMemo } from "react" import { CartesianGrid, Line, LineChart, YAxis } from "recharts" import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, xAxis, } from "@/components/ui/chart" import { chartMargin, cn, decimalString, formatShortDate, toFixedFloat } from "@/lib/utils" import type { ChartData, GPUData } from "@/types" import { useYAxisWidth } from "./hooks" import type { DataPoint } from "./line-chart" export default memo(function GpuPowerChart({ chartData }: { chartData: ChartData }) { const { yAxisWidth, updateYAxisWidth } = useYAxisWidth() const packageKey = " package" const { gpuData, dataPoints } = useMemo(() => { const dataPoints = [] as DataPoint[] const gpuData = [] as Record[] const addedKeys = new Map() const addKey = (key: string, value: number) => { addedKeys.set(key, (addedKeys.get(key) ?? 0) + value) } for (const stats of chartData.systemStats) { const gpus = stats.stats?.g ?? {} const data = { created: stats.created } as Record for (const id in gpus) { const gpu = gpus[id] as GPUData data[gpu.n] = gpu addKey(gpu.n, gpu.p ?? 0) if (gpu.pp) { data[`${gpu.n}${packageKey}`] = gpu addKey(`${gpu.n}${packageKey}`, gpu.pp ?? 0) } } gpuData.push(data) } const sortedKeys = Array.from(addedKeys.entries()) .sort(([, a], [, b]) => b - a) .map(([key]) => key) for (let i = 0; i < sortedKeys.length; i++) { const id = sortedKeys[i] dataPoints.push({ label: id, dataKey: (gpuData: Record) => { return id.endsWith(packageKey) ? (gpuData[id]?.pp ?? 0) : (gpuData[id]?.p ?? 0) }, color: `hsl(${226 + (((i * 360) / addedKeys.size) % 360)}, 65%, 52%)`, }) } return { gpuData, dataPoints } }, [chartData]) if (chartData.systemStats.length === 0) { return null } return (
{ const val = toFixedFloat(value, 2) return updateYAxisWidth(`${val}W`) }} tickLine={false} axisLine={false} /> {xAxis(chartData)} b.value - a.value} content={ formatShortDate(data[0].payload.created)} contentFormatter={(item) => `${decimalString(item.value)}W`} // indicator="line" /> } /> {dataPoints.map((dataPoint) => ( ))} {dataPoints.length > 1 && } />}
) })