"use client"; import { useMemo } from "react"; import { useObjectSaleGraph } from "@/lib/analytics-api"; import { ChartShell } from "./ChartShell"; export function ObjectSaleChart({ objId }: { objId: number | string }) { const { data, isLoading } = useObjectSaleGraph(objId); const option = useMemo(() => { const points = data ?? []; if (points.length === 0) { return { title: { text: "Нет данных по продажам", left: "center", top: "middle", textStyle: { color: "#9ca3af", fontSize: 13, fontWeight: 400 }, }, xAxis: { show: false }, yAxis: { show: false }, }; } // Каждый тип (apartments / parking / nonliv) приходит от DOM.RF отдельным // запросом со СВОИМ набором месяцев — они не обязаны совпадать (parking // может стартовать позже). Строим ось X из union всех месяцев и маппим // значения каждого типа по месяцу через Map (а не позиционно), чтобы бары // и линия цены не «съезжали» на чужие месяцы и точки не обрезались молча. const byType: Record< string, { realised: Map; price: Map; } > = {}; for (const p of points) { const t = p.type; if (!byType[t]) byType[t] = { realised: new Map(), price: new Map() }; const m = (p.report_month ?? "").slice(0, 7); byType[t].realised.set(m, p.realised ?? 0); byType[t].price.set(m, p.price_avg); } const months = Array.from( new Set(points.map((p) => (p.report_month ?? "").slice(0, 7))), ).sort(); const series = Object.entries(byType).flatMap(([type, d]) => [ { name: `${type} · реализовано`, type: "bar", stack: type, data: months.map((m) => d.realised.get(m) ?? null), itemStyle: { color: type === "apartments" ? "#1d4ed8" : "#9333ea" }, }, { name: `${type} · цена ₽/м²`, type: "line", yAxisIndex: 1, smooth: true, symbol: "circle", data: months.map((m) => { const v = d.price.get(m); return v ? Math.round(v) : null; }), lineStyle: { color: type === "apartments" ? "#0a7a3a" : "#c2410c" }, itemStyle: { color: type === "apartments" ? "#0a7a3a" : "#c2410c" }, connectNulls: true, tooltip: { valueFormatter: (v: number | null) => v == null ? "—" : `${v.toLocaleString("ru")} ₽/м²`, }, }, ]); return { tooltip: { trigger: "axis", axisPointer: { type: "cross" } }, legend: {}, grid: { left: 56, right: 64, top: 40, bottom: 36 }, xAxis: { type: "category", data: months }, yAxis: [ { type: "value", name: "шт", position: "left" }, { type: "value", name: "₽/м²", position: "right" }, ], series, }; }, [data]); return ( ); }