"use client" import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts" import { Frame, FramePanel } from "@/components/reui/frame" import { ChartContainer, ChartTooltip, type ChartConfig } from "@/components/ui/chart" import { formatBytes } from "@/lib/fmt-rate" import type { StatisticsSeriesPoint } from "@mmapp/contracts/statistics" /** * Объём трафика за период — adapt ReUI chart-23 (байты, не live bps). * @see https://reui.io/preview/base/chart-23 */ const chartConfig = { bytes: { label: "Объём", color: "var(--chart-1)" }, } satisfies ChartConfig function formatTick(iso: string, grain: "hour" | "day"): string { const d = new Date(iso) if (Number.isNaN(d.getTime())) return iso.slice(0, 10) if (grain === "hour") { return `${String(d.getHours()).padStart(2, "0")}:00` } return d.toLocaleDateString("ru-RU", { day: "2-digit", month: "short" }) } function CustomTooltip({ active, payload, }: { active?: boolean payload?: { payload: { label: string; bytes: number } }[] }) { if (!active || !payload?.length) return null const row = payload[0]?.payload if (!row) return null return (
{row.label}
{formatBytes(row.bytes)}
) } export function StatisticsVolumeChart({ series, grain, }: { series: StatisticsSeriesPoint[] grain: "hour" | "day" }) { const data = series.map((p) => ({ t: p.t, bytes: p.bytes, label: formatTick(p.t, grain), })) const tickEvery = Math.max(1, Math.ceil(data.length / 8)) return (

Объём по времени

{grain === "hour" ? "по часам" : "по суткам"}
{data.length === 0 ? (

Нет данных за выбранный период

) : ( formatBytes(Number(v))} tickMargin={8} width={72} /> } /> )}
) }