"use client"; import { useMemo } from "react"; import { Area, AreaChart, Bar, BarChart, CartesianGrid, XAxis, YAxis, } from "recharts"; import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, type ChartConfig, } from "../ui/chart"; import { ChartMessage } from "./ChartMessage"; import type { HomepageSummary } from "../../lib/homepageSummary"; import { type ChartState } from "../../lib/homepageChart"; import { buildTimeSeries } from "../../lib/homepageChartData"; import { BAR_GAP } from "./surfaceGap"; // The stacked renderer: area (cumulative/Growth) or bars, optionally 100%-share. // Stacking shows per-series composition *and* the combined total at once — the // honest view when the series add up to a meaningful whole. Skew-handling for // non-stacked views lives in the line / small-multiples / leaderboard charts. export function CrossSiteChart({ summary, state, }: { summary: HomepageSummary; state: ChartState; }) { const { labels, series } = useMemo( () => buildTimeSeries(summary, state), [summary, state], ); const config = useMemo(() => { const c: ChartConfig = {}; for (const s of series) c[s.id] = { label: s.label, color: s.color }; return c; }, [series]); const rows = useMemo( () => labels.map((x, i) => { const row: Record = { x }; for (const s of series) row[s.id] = (s.values[i] as number) ?? 0; return row; }), [labels, series], ); if (labels.length === 0) { return No data for this view yet.; } if (series.length === 0) { return ( Every series is hidden — re-enable one from the cards below. ); } const isArea = state.chartType === "area"; // The marks spec's surface gap between touching bar segments // (charts/surfaceGap.ts): only when there is more than one series to part. const stacked = series.length > 1; const isShare = state.valueMode === "share"; const stackOffset = isShare ? "expand" : undefined; const showLegend = state.breakdown === "channel" && series.length > 1; const margin = { top: 8, right: 12, bottom: 4, left: 4 }; const axes = [ , , `${Math.round(v * 100)}%` : undefined} tick={{ fill: "var(--chart-axis)", fontSize: 12 }} />, } />, showLegend ? ( } /> ) : null, ]; return ( {isArea ? ( {axes} {series.map((s) => ( ))} ) : ( {axes} {series.map((s) => ( ))} )} ); }