"use client"; import { Bar, BarChart, CartesianGrid, Cell, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis, } from "recharts"; type Translator = (key: string, vars?: Record) => string; type TooltipPayload = { payload?: T; name?: string; value?: number | string }; type SimpleTooltipProps = { active?: boolean; payload?: Array>; label?: string | number; }; type ChartPoint = { ts: string; label: string; value: number }; type CycleHistogramRow = { label: string; count: number; rangeStart?: number; rangeEnd?: number; overflow?: "low" | "high"; minValue?: number; maxValue?: number; }; function CycleTooltip({ active, payload, t }: SimpleTooltipProps & { t: Translator }) { if (!active || !payload?.length) return null; const p = payload[0]?.payload; if (!p) return null; let detail = ""; if (p.overflow === "low") { detail = `${t("reports.tooltip.below")} ${p.rangeEnd?.toFixed(1)}s`; } else if (p.overflow === "high") { detail = `${t("reports.tooltip.above")} ${p.rangeStart?.toFixed(1)}s`; } else if (p.rangeStart != null && p.rangeEnd != null) { detail = `${p.rangeStart.toFixed(1)}s - ${p.rangeEnd.toFixed(1)}s`; } const extreme = p.overflow && (p.minValue != null || p.maxValue != null) ? `${t("reports.tooltip.extremes")}: ${p.minValue?.toFixed(1) ?? "--"}s - ${p.maxValue?.toFixed(1) ?? "--"}s` : ""; return (
{p.label}
{t("reports.tooltip.cycles")}: {p.count}
{detail ? (
{t("reports.tooltip.range")}: {detail}
) : null} {extreme ?
{extreme}
: null}
); } function DowntimeTooltip({ active, payload, t, }: SimpleTooltipProps<{ name?: string; value?: number }> & { t: Translator }) { if (!active || !payload?.length) return null; const row = payload[0]?.payload ?? {}; const label = row.name ?? payload[0]?.name ?? ""; const value = row.value ?? payload[0]?.value ?? 0; return (
{label}
{t("reports.tooltip.downtime")}: {Number(value)} min
); } export default function ReportsCharts({ oeeSeries, downtimeSeries, downtimeColors, cycleHistogram, scrapSeries, lossRows, locale, t, }: { oeeSeries: ChartPoint[]; downtimeSeries: { name: string; value: number }[]; downtimeColors: Record; cycleHistogram: CycleHistogramRow[]; scrapSeries: ChartPoint[]; lossRows: Array<{ label: string; value: string }>; locale: string; t: Translator; }) { return ( <>
{t("reports.oeeTrend")}
{oeeSeries.length ? ( { const row = payload?.[0]?.payload; return row?.ts ? new Date(row.ts).toLocaleString(locale) : ""; }} formatter={(val: number | string | undefined) => [ val == null ? "--" : `${Number(val).toFixed(1)}%`, "OEE", ]} /> ) : (
{t("reports.noTrend")}
)}
{t("reports.downtimePareto")}
{downtimeSeries.length ? ( } /> {downtimeSeries.map((row, idx) => ( ))} ) : (
{t("reports.noTrend")}
)}
{t("reports.cycleDistribution")}
{cycleHistogram.length ? ( } /> ) : (
{t("reports.noCycle")}
)}
{t("reports.scrapTrend")}
{scrapSeries.length ? ( { const row = payload?.[0]?.payload; return row?.ts ? new Date(row.ts).toLocaleString(locale) : ""; }} formatter={(val: number | string | undefined) => [ val == null ? "--" : `${Number(val).toFixed(1)}%`, t("reports.scrapRate"), ]} /> ) : (
{t("reports.noDowntime")}
)}
{t("reports.topLossDrivers")}
{lossRows.map((row) => (
{row.label} {row.value}
))}
); }