import { t } from "@lingui/core/macro" import { Area, AreaChart, CartesianGrid, YAxis } from "recharts" import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart" import { useYAxisWidth, cn, formatShortDate, toFixedWithoutTrailingZeros, decimalString, chartMargin, convertNetworkSpeed, convertDiskSpeed, } from "@/lib/utils" // import Spinner from '../spinner' import { ChartData } from "@/types" import { memo, useMemo } from "react" import { useLingui } from "@lingui/react/macro" import { useStore } from "@nanostores/react" import { $userSettings } from "@/lib/stores" /** [label, key, color, opacity] */ type DataKeys = [string, string, number, number] const getNestedValue = (path: string, max = false, data: any): number | null => { // fallback value (obj?.stats?.cpum ? 0 : null) should only come into play when viewing // a max value which doesn't exist, or the value was zero and omitted from the stats object. // so we check if cpum is present. if so, return 0 to make sure the zero value is displayed. // if not, return null - there is no max data so do not display anything. return `stats.${path}${max ? "m" : ""}` .split(".") .reduce((acc: any, key: string) => acc?.[key] ?? (data.stats?.cpum ? 0 : null), data) } export default memo(function AreaChartDefault({ maxToggled = false, unit = " MB/s", chartName, chartData, max, tickFormatter, contentFormatter, }: { maxToggled?: boolean unit?: string chartName: string chartData: ChartData max?: number tickFormatter?: (value: number) => string contentFormatter?: (value: number) => string }) { const { yAxisWidth, updateYAxisWidth } = useYAxisWidth() const { i18n } = useLingui() const userSettings = useStore($userSettings) const { chartTime } = chartData const showMax = chartTime !== "1h" && maxToggled // Determine if this is a network chart or disk chart and adjust unit accordingly const isNetworkChart = chartName === "bw" const isDiskChart = chartName === "dio" || chartName.startsWith("efs") const displayUnit = useMemo(() => { if (isNetworkChart) { const { symbol } = convertNetworkSpeed(1, userSettings.networkUnit) return symbol } else if (isDiskChart) { const { symbol } = convertDiskSpeed(1, userSettings.diskUnit) return symbol } return unit }, [isNetworkChart, isDiskChart, userSettings.networkUnit, userSettings.diskUnit, unit]) const dataKeys: DataKeys[] = useMemo(() => { // [label, key, color, opacity] if (chartName === "CPU Usage") { return [[t`CPU Usage`, "cpu", 1, 0.4]] } else if (chartName === "dio") { return [ [t({ message: "Write", comment: "Disk write" }), "dw", 3, 0.3], [t({ message: "Read", comment: "Disk read" }), "dr", 1, 0.3], ] } else if (chartName === "bw") { return [ [t({ message: "Sent", comment: "Network bytes sent (upload)" }), "ns", 5, 0.2], [t({ message: "Received", comment: "Network bytes received (download)" }), "nr", 2, 0.2], ] } else if (chartName.startsWith("efs")) { return [ [t`Write`, `${chartName}.w`, 3, 0.3], [t`Read`, `${chartName}.r`, 1, 0.3], ] } else if (chartName.startsWith("g.")) { return [chartName.includes("mu") ? [t`Used`, chartName, 2, 0.25] : [t`Usage`, chartName, 1, 0.4]] } return [] }, [chartName, i18n.locale]) // console.log('Rendered at', new Date()) if (chartData.systemStats.length === 0) { return null } return (