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";
interface UsageTrendChartProps {
days: number;
appType?: string;
refreshIntervalMs: number;
}
export function UsageTrendChart({
days,
appType,
refreshIntervalMs,
}: UsageTrendChartProps) {
const { t, i18n } = useTranslation();
const { data: trends, isLoading } = useUsageTrends(days, appType, {
refetchInterval: refreshIntervalMs > 0 ? refreshIntervalMs : false,
});
if (isLoading) {
return (
);
}
const isToday = days === 1;
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: isToday
? 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", "使用趋势")}
{isToday
? t("usage.rangeToday", "今天 (按小时)")
: days === 7
? t("usage.rangeLast7Days", "过去 7 天")
: t("usage.rangeLast30Days", "过去 30 天")}
`${(value / 1000).toFixed(0)}k`}
/>
`$${value}`}
/>
} />
);
}