"use client"; import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from "recharts"; import { formatTokens } from "@/lib/utils"; import { useI18n } from "@/lib/i18n"; interface TrendPoint { date: string; calls: number; total_tokens: number; prompt_tokens: number; completion_tokens: number; } export function TrendChart({ data, metric = "total_tokens" }: { data: TrendPoint[]; metric?: "total_tokens" | "calls" }) { const { t, locale } = useI18n(); if (!data.length) return
{t("common.noData")}
; // 本地化日期格式 const formatDateLabel = (dateStr: string) => { const d = new Date(dateStr); if (locale === "zh") { return `${d.getMonth() + 1}/${d.getDate()}`; } return d.toLocaleDateString("en-US", { month: "short", day: "numeric" }); }; const tooltipStyle = { background: "var(--surface)", border: "1px solid var(--surface-border)", borderRadius: "8px", color: "var(--foreground)", fontSize: "12px", backdropFilter: "blur(16px)", }; // Token 模式:输入和输出数量级差距大,用双 Y 轴 if (metric === "total_tokens") { return ( {/* 左 Y 轴:输入 */} formatTokens(v)} tick={{ fontSize: 10 }} stroke="var(--chart-grid)" label={{ value: t("th.input"), angle: -90, position: "insideLeft", style: { fontSize: 10, fill: "var(--text-muted)" } }} /> {/* 右 Y 轴:输出 */} formatTokens(v)} tick={{ fontSize: 10 }} stroke="var(--chart-grid)" label={{ value: t("th.output"), angle: 90, position: "insideRight", style: { fontSize: 10, fill: "var(--text-muted)" } }} /> { const d = new Date(String(label)); return locale === "zh" ? `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}` : d.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" }); }} formatter={(value, name) => [ formatTokens(Number(value)), name === t("th.input") ? t("th.input") : t("th.output"), ]} /> ); } // 调用量模式:单 Y 轴 return ( formatTokens(v)} tick={{ fontSize: 11 }} stroke="var(--chart-grid)" /> { const d = new Date(String(label)); return locale === "zh" ? `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}` : d.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" }); }} formatter={(value, name) => [ formatTokens(Number(value)), name === t("th.calls") ? t("th.calls") : String(name), ]} /> ); }