import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Loader2 } from "lucide-react"; import Tips from "@/components/Tips.tsx"; import { sum } from "@/utils/base.ts"; import { DonutChart, Legend } from "@tremor/react"; import { getReadableNumber } from "@/utils/processor.ts"; import { getModelColor } from "@/admin/colors.ts"; type ModelChartProps = { labels: string[]; datasets: { model: string; data: number[]; }[]; }; type DataUsage = { name: string; value: number; }; function ModelUsageChart({ labels, datasets }: ModelChartProps) { const { t } = useTranslation(); const usage = useMemo((): Record => { const usage: Record = {}; datasets.forEach((dataset) => { usage[dataset.model] = sum(dataset.data); }); return usage; }, [datasets]); const data = useMemo((): DataUsage[] => { const models: string[] = Object.keys(usage); const data: number[] = models.map((model) => usage[model]); return models.map( (model, i): DataUsage => ({ name: model, value: data[i] }), ); }, [usage]); const sorted = useMemo(() => { return data.sort((a, b) => b.value - a.value); }, [data]); const categories = useMemo(() => { return sorted.map( (item) => `${item.name} (${getReadableNumber(item.value, 1)})`, ); }, [sorted]); type CustomTooltipTypeDonut = { payload: any; active: boolean | undefined; label: any; }; const customTooltip = (props: CustomTooltipTypeDonut) => { const { payload, active } = props; if (!active || !payload) return null; const categoryPayload = payload?.[0]; if (!categoryPayload) return null; return (

{categoryPayload.name}

{getReadableNumber(categoryPayload.value, 1)} tokens

); }; return (
{t("admin.model-usage-chart")}
{labels.length === 0 && ( )}
getReadableNumber(value, 1)} customTooltip={customTooltip} colors={data.map((item) => getModelColor(item.name))} /> getModelColor(item.name))} />
); } export default ModelUsageChart;