gendesign/frontend/src/components/analytics/VelocityScatter.tsx
lekss361 8d3a0874ef add interactive analytics dashboard for Sverdlovsk market and PRINZIP
3 pages (market, PRINZIP drilldown, developers leaderboard) on top of
existing v_developer_full_metrics + domrf_realization views. ECharts on
the frontend, FastAPI router /api/v1/analytics on the backend.
2026-04-27 16:55:30 +03:00

76 lines
2.1 KiB
TypeScript

"use client";
import { useMemo } from "react";
import { useTopDevelopers } from "@/lib/analytics-api";
import { ChartShell } from "./ChartShell";
export function VelocityScatter() {
const { data, isLoading } = useTopDevelopers(30);
const option = useMemo(() => {
const rows = data ?? [];
return {
tooltip: {
trigger: "item",
formatter: (info: { data: [number, number, string, number] }) => {
const [x, y, name, sold] = info.data;
return `<b>${name}</b><br/>Объём: ${x} тыс м²<br/>Δ sold: ${y > 0 ? "+" : ""}${y} пп<br/>текущий sold%: ${sold}%`;
},
},
grid: { left: 56, right: 32, top: 32, bottom: 56 },
xAxis: {
name: "Объём, тыс м²",
nameLocation: "middle",
nameGap: 32,
type: "value",
},
yAxis: {
name: "Δ sold % (пп)",
nameLocation: "middle",
nameGap: 36,
type: "value",
axisLine: { show: true },
},
series: [
{
type: "scatter",
symbolSize: 14,
data: rows
.filter((r) => r.sold_delta_pp != null && r.sverdl_sqm_th != null)
.map((r) => [
r.sverdl_sqm_th,
r.sold_delta_pp,
r.developer_name,
r.sold_pct ?? 0,
]),
itemStyle: {
color: (p: { data: [number, number, string, number] }) =>
p.data[1] > 5
? "#0a7a3a"
: p.data[1] < -5
? "#b3261e"
: "#5b6066",
},
label: {
show: true,
position: "right",
formatter: (p: { data: [number, number, string, number] }) =>
p.data[2],
fontSize: 11,
color: "#374151",
},
markLine: {
silent: true,
symbol: "none",
lineStyle: { color: "#cbd5e1", type: "dashed" },
data: [{ yAxis: 0 }],
},
},
],
};
}, [data]);
return <ChartShell option={option} loading={isLoading} height={420} />;
}