import { Area, AreaChart, CartesianGrid, YAxis } from "recharts" import { type ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart" import { memo, useMemo } from "react" import { cn, formatShortDate, chartMargin, toFixedFloat, formatBytes, decimalString } from "@/lib/utils" // import Spinner from '../spinner' import { useStore } from "@nanostores/react" import { $containerFilter, $userSettings } from "@/lib/stores" import type { ChartData } from "@/types" import { Separator } from "../ui/separator" import { ChartType, Unit } from "@/lib/enums" import { useYAxisWidth } from "./hooks" export default memo(function ContainerChart({ dataKey, chartData, chartType, chartConfig, unit = "%", }: { dataKey: string chartData: ChartData chartType: ChartType chartConfig: ChartConfig unit?: string }) { const filter = useStore($containerFilter) const userSettings = useStore($userSettings) const { yAxisWidth, updateYAxisWidth } = useYAxisWidth() const { containerData } = chartData const isNetChart = chartType === ChartType.Network // biome-ignore lint/correctness/useExhaustiveDependencies: not necessary 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 (chartType === ChartType.CPU) { obj.tickFormatter = (value) => { const val = toFixedFloat(value, 2) + unit return updateYAxisWidth(val) } } else { const chartUnit = isNetChart ? userSettings.unitNet : Unit.Bytes obj.tickFormatter = (val) => { const { value, unit } = formatBytes(val, isNetChart, chartUnit, true) return updateYAxisWidth(`${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`) } } // 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 const { value: receivedValue, unit: receivedUnit } = formatBytes(received, true, userSettings.unitNet, true) const { value: sentValue, unit: sentUnit } = formatBytes(sent, true, userSettings.unitNet, true) return ( {decimalString(receivedValue)} {receivedUnit} rx {decimalString(sentValue)} {sentUnit} tx ) } catch (e) { return null } } } else if (chartType === ChartType.Memory) { obj.toolTipFormatter = (item: any) => { const { value, unit } = formatBytes(item.value, false, Unit.Bytes, true) return `${decimalString(value)} ${unit}` } } else { obj.toolTipFormatter = (item: any) => `${decimalString(item.value)} ${unit}` } // data function if (isNetChart) { obj.dataFunction = (key: string, data: any) => (data[key] ? data[key].nr + data[key].ns : null) } else { obj.dataFunction = (key: string, data: any) => data[key]?.[dataKey] ?? null } return obj }, []) // Filter with set lookup const filteredKeys = useMemo(() => { if (!filter) { return new Set() } const filterLower = filter.toLowerCase() return new Set(Object.keys(chartConfig).filter((key) => !key.toLowerCase().includes(filterLower))) }, [chartConfig, filter]) // console.log('rendered at', new Date()) if (containerData.length === 0) { return null } return (
{xAxis(chartData)} formatShortDate(data[0].payload.created)} // @ts-expect-error itemSorter={(a, b) => b.value - a.value} content={} /> {Object.keys(chartConfig).map((key) => { const filtered = filteredKeys.has(key) const fillOpacity = filtered ? 0.05 : 0.4 const strokeOpacity = filtered ? 0.1 : 1 return ( ) })}
) })