fix(analytics): ObjectSaleChart выровнять серии по union месяцев (#1246) #1309

Merged
bot-backend merged 2 commits from fix/object-sale-chart-union-months-1246 into main 2026-06-13 13:22:57 +00:00
Showing only changes of commit e2c8c0e97b - Show all commits

View file

@ -23,31 +23,34 @@ export function ObjectSaleChart({ objId }: { objId: number | string }) {
yAxis: { show: false },
};
}
// Каждый тип (apartments / parking / nonliv) приходит от DOM.RF отдельным
// запросом со СВОИМ набором месяцев — они не обязаны совпадать (parking
// может стартовать позже). Строим ось X из union всех месяцев и маппим
// значения каждого типа по месяцу через Map (а не позиционно), чтобы бары
// и линия цены не «съезжали» на чужие месяцы и точки не обрезались молча.
const byType: Record<
string,
{
months: string[];
realised: number[];
contracted: number[];
price: (number | null)[];
realised: Map<string, number>;
price: Map<string, number | null>;
}
> = {};
for (const p of points) {
const t = p.type;
if (!byType[t])
byType[t] = { months: [], realised: [], contracted: [], price: [] };
byType[t].months.push((p.report_month ?? "").slice(0, 7));
byType[t].realised.push(p.realised ?? 0);
byType[t].contracted.push(p.contracted ?? 0);
byType[t].price.push(p.price_avg);
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 = Object.values(byType)[0]?.months ?? [];
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: d.realised,
data: months.map((m) => d.realised.get(m) ?? null),
itemStyle: { color: type === "apartments" ? "#1d4ed8" : "#9333ea" },
},
{
@ -56,7 +59,10 @@ export function ObjectSaleChart({ objId }: { objId: number | string }) {
yAxisIndex: 1,
smooth: true,
symbol: "circle",
data: d.price.map((v) => (v ? Math.round(v) : null)),
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,