Some checks failed
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been cancelled
68 lines
2.6 KiB
TypeScript
68 lines
2.6 KiB
TypeScript
// Утилиты страницы sale-share: цвет/размер тепловых маркеров + форматтеры.
|
||
|
||
/**
|
||
* Цвет «тепла» доли в продаже: низкая (норма) → зелёный, высокая (сигнал
|
||
* расселения / инвест-выхода / проблемного дома) → красный. null → серый.
|
||
* Пороги согласованы с корзинами гистограммы (HISTOGRAM_BUCKETS на бэкенде).
|
||
*/
|
||
export function heatColor(pct: number | null): string {
|
||
if (pct === null) return "#9ca3af"; // gray-400 — знаменатель неизвестен
|
||
if (pct < 5) return "#16a34a"; // green-600
|
||
if (pct < 10) return "#65a30d"; // lime-600
|
||
if (pct < 20) return "#ca8a04"; // yellow-600
|
||
if (pct < 30) return "#ea580c"; // orange-600
|
||
if (pct < 50) return "#dc2626"; // red-600
|
||
if (pct <= 100) return "#b91c1c"; // red-700
|
||
return "#7f1d1d"; // red-900 — over_100
|
||
}
|
||
|
||
/** Радиус маркера на карте: 5..14 px, растёт с долей. null → минимум. */
|
||
export function markerRadius(pct: number | null): number {
|
||
if (pct === null) return 5;
|
||
const clamped = Math.min(Math.max(pct, 0), 100);
|
||
return 5 + (clamped / 100) * 9;
|
||
}
|
||
|
||
export function fmtRub(v: number | null | undefined): string {
|
||
return v === null || v === undefined ? "—" : v.toLocaleString("ru-RU");
|
||
}
|
||
|
||
export function fmtPct(v: number | null | undefined): string {
|
||
if (v === null || v === undefined) return "—";
|
||
return v >= 100 ? `${Math.round(v)}%` : `${v.toFixed(1)}%`;
|
||
}
|
||
|
||
export function fmtDays(v: number | null | undefined): string {
|
||
return v === null || v === undefined ? "—" : `${Math.round(v)} дн`;
|
||
}
|
||
|
||
const HOUSE_TYPE_LABELS: Record<string, string> = {
|
||
panel: "Панель",
|
||
brick: "Кирпич",
|
||
monolith: "Монолит",
|
||
monolith_brick: "Монолит-кирпич",
|
||
block: "Блочный",
|
||
wood: "Дерево",
|
||
stalin: "Сталинка",
|
||
other: "Другое",
|
||
};
|
||
|
||
/** Гуманизация типа дома; неизвестное значение отдаём как есть. */
|
||
export function houseTypeLabel(t: string | null | undefined): string {
|
||
if (!t) return "—";
|
||
return HOUSE_TYPE_LABELS[t] ?? t;
|
||
}
|
||
|
||
const SOURCE_LABELS: Record<string, string> = {
|
||
cian: "Циан",
|
||
avito: "Avito",
|
||
yandex: "Я.Недв",
|
||
domklik: "ДомКлик",
|
||
rosreestr: "Росреестр",
|
||
n1: "N1.ru",
|
||
};
|
||
|
||
export function sourceLabel(s: string | null | undefined): string {
|
||
if (!s) return "—";
|
||
return SOURCE_LABELS[s] ?? s;
|
||
}
|