import { useTranslation } from "react-i18next"; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, } from "recharts"; import { useUsageTrends } from "@/lib/query/usage"; import { Loader2 } from "lucide-react"; import { fmtInt, fmtUsd, getLocaleFromLanguage, parseFiniteNumber, } from "./format"; import { resolveUsageRange } from "@/lib/usageRange"; import type { UsageRangeSelection } from "@/types/usage"; interface UsageTrendChartProps { range: UsageRangeSelection; rangeLabel: string; appType?: string; refreshIntervalMs: number; } export function UsageTrendChart({ range, rangeLabel, appType, refreshIntervalMs, }: UsageTrendChartProps) { const { t, i18n } = useTranslation(); const { startDate, endDate } = resolveUsageRange(range); const { data: trends, isLoading } = useUsageTrends(range, appType, { refetchInterval: refreshIntervalMs > 0 ? refreshIntervalMs : false, }); if (isLoading) { return (
); } const durationSeconds = Math.max(endDate - startDate, 0); const isHourly = durationSeconds <= 24 * 60 * 60; const language = i18n.resolvedLanguage || i18n.language || "en"; const dateLocale = getLocaleFromLanguage(language); const chartData = trends?.map((stat) => { const pointDate = new Date(stat.date); const cost = parseFiniteNumber(stat.totalCost); return { rawDate: stat.date, label: isHourly ? pointDate.toLocaleString(dateLocale, { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", }) : pointDate.toLocaleDateString(dateLocale, { month: "2-digit", day: "2-digit", }), hour: pointDate.getHours(), inputTokens: stat.totalInputTokens, outputTokens: stat.totalOutputTokens, cacheCreationTokens: stat.totalCacheCreationTokens, cacheReadTokens: stat.totalCacheReadTokens, cost: cost ?? null, }; }) || []; const displayData = chartData; const CustomTooltip = ({ active, payload, label }: any) => { if (active && payload && payload.length) { return (

{label}

{payload.map((entry: any, index: number) => (
{entry.name}: {entry.dataKey === "cost" ? fmtUsd(entry.value, 6) : fmtInt(entry.value, dateLocale)}
))}
); } return null; }; return (

{t("usage.trends", "使用趋势")}

{rangeLabel}

`${(value / 1000).toFixed(0)}k`} /> `$${value}`} /> } />
); }