67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { useMemo } from "react";
|
|
|
|
import { useDeveloperHistory } from "@/lib/analytics-api";
|
|
|
|
const PALETTE = [
|
|
"#1d4ed8",
|
|
"#0a7a3a",
|
|
"#c2410c",
|
|
"#9333ea",
|
|
"#0891b2",
|
|
"#5b6066",
|
|
];
|
|
|
|
import { ChartShell } from "./ChartShell";
|
|
|
|
interface Props {
|
|
developerIds: string[];
|
|
developerNames: Record<string, string>;
|
|
}
|
|
|
|
export function PrinzipVelocityChart({ developerIds, developerNames }: Props) {
|
|
const { data, isLoading } = useDeveloperHistory(developerIds);
|
|
|
|
const option = useMemo(() => {
|
|
const points = data ?? [];
|
|
const byDev: Record<string, { date: string; sold: number | null }[]> = {};
|
|
for (const p of points) {
|
|
if (!byDev[p.developer_id]) byDev[p.developer_id] = [];
|
|
byDev[p.developer_id].push({
|
|
date: p.snapshot_date.slice(0, 7),
|
|
sold: p.sold_perc,
|
|
});
|
|
}
|
|
const dates = Array.from(
|
|
new Set(points.map((p) => p.snapshot_date.slice(0, 7))),
|
|
).sort();
|
|
const series = developerIds.map((id, i) => ({
|
|
name: developerNames[id] ?? id,
|
|
type: "line",
|
|
smooth: true,
|
|
symbol: "circle",
|
|
lineStyle: {
|
|
width: id === "6208_0" ? 3 : 2,
|
|
color: PALETTE[i % PALETTE.length],
|
|
},
|
|
itemStyle: { color: PALETTE[i % PALETTE.length] },
|
|
data: dates.map(
|
|
(d) => byDev[id]?.find((p) => p.date === d)?.sold ?? null,
|
|
),
|
|
connectNulls: true,
|
|
}));
|
|
return {
|
|
tooltip: { trigger: "axis", valueFormatter: (v: number) => `${v}%` },
|
|
legend: { data: series.map((s) => s.name as string) },
|
|
grid: { left: 48, right: 32, top: 40, bottom: 28 },
|
|
xAxis: { type: "category", data: dates },
|
|
yAxis: { type: "value", axisLabel: { formatter: "{value}%" } },
|
|
series,
|
|
};
|
|
}, [data, developerIds, developerNames]);
|
|
|
|
return (
|
|
<ChartShell option={option} loading={isLoading} height={360} notMerge />
|
|
);
|
|
}
|