import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, } from '@/components/ui/chart' import { memo, useMemo } from 'react' import { useYAxisWidth, chartTimeData, cn, formatShortDate, decimalString, chartMargin, toFixedFloat, getSizeAndUnit, toFixedWithoutTrailingZeros, } from '@/lib/utils' // import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $containerFilter } from '@/lib/stores' import { ChartData } from '@/types' import { Separator } from '../ui/separator' export default memo(function ContainerChart({ dataKey, chartData, chartName, unit = '%', }: { dataKey: string chartData: ChartData chartName: string unit?: string }) { const filter = useStore($containerFilter) const { yAxisWidth, updateYAxisWidth } = useYAxisWidth() const { containerData, ticks, domain, chartTime } = chartData const isNetChart = chartName === 'net' const chartConfig = useMemo(() => { let config = {} as Record< string, { label: string color: string } > const totalUsage = {} as Record for (let stats of containerData) { for (let key in stats) { if (!key || key === 'created') { continue } if (!(key in totalUsage)) { totalUsage[key] = 0 } if (isNetChart) { totalUsage[key] += (stats[key]?.nr ?? 0) + (stats[key]?.ns ?? 0) } else { // @ts-ignore totalUsage[key] += stats[key]?.[dataKey] ?? 0 } } } let keys = Object.keys(totalUsage) keys.sort((a, b) => (totalUsage[a] > totalUsage[b] ? -1 : 1)) const length = keys.length for (let i = 0; i < length; i++) { const key = keys[i] const hue = ((i * 360) / length) % 360 config[key] = { label: key, color: `hsl(${hue}, 60%, 55%)`, } } return config satisfies ChartConfig }, [chartData]) const { toolTipFormatter, dataFunction, tickFormatter } = useMemo(() => { const obj = {} as { toolTipFormatter: (item: any, key: string) => React.ReactNode | string dataFunction: (key: string, data: any) => number | null tickFormatter: (value: any) => string } // tick formatter if (chartName === 'cpu') { obj.tickFormatter = (value) => { const val = toFixedWithoutTrailingZeros(value, 2) + unit return updateYAxisWidth(val) } } else { obj.tickFormatter = (value) => { const { v, u } = getSizeAndUnit(value, false) return updateYAxisWidth(`${toFixedFloat(v, 2)}${u}${isNetChart ? '/s' : ''}`) } } // tooltip formatter if (isNetChart) { obj.toolTipFormatter = (item: any, key: string) => { try { const sent = item?.payload?.[key]?.ns ?? 0 const received = item?.payload?.[key]?.nr ?? 0 return ( {decimalString(received)} MB/s rx {decimalString(sent)} MB/s tx ) } catch (e) { return null } } } else { obj.toolTipFormatter = (item: any) => decimalString(item.value) + unit } // data function if (isNetChart) { obj.dataFunction = (key: string, data: any) => (data[key]?.nr ?? 0) + (data[key]?.ns ?? 0) } else { obj.dataFunction = (key: string, data: any) => data[key]?.[dataKey] ?? 0 } return obj }, []) // console.log('rendered at', new Date()) return (
formatShortDate(data[0].payload.created)} // @ts-ignore itemSorter={(a, b) => b.value - a.value} content={} /> {Object.keys(chartConfig).map((key) => { const filtered = filter && !key.includes(filter) let fillOpacity = filtered ? 0.05 : 0.4 let strokeOpacity = filtered ? 0.1 : 1 return ( ) })}
) })