"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),
]}
/>
);
}