MCPcopy Create free account
hub / github.com/Qinbf/groundmap / GraphView

Function GraphView

web/components/GraphView.tsx:271–913  ·  view source on GitHub ↗
({ initialFilters = {} }: GraphViewProps)

Source from the content-addressed store, hash-verified

269}
270
271export function GraphView({ initialFilters = {} }: GraphViewProps) {
272 const t = useT();
273 const router = useRouter();
274
275 const [filterType, setFilterType] = useState<string>(initialFilters.type || "");
276 const [filterTag, setFilterTag] = useState<string>(initialFilters.tag || "");
277 const [includeArchive, setIncludeArchive] = useState<boolean>(!!initialFilters.includeArchive);
278 const [theme, setTheme] = useState<"light" | "dark">("dark"); // 科技感默认深色
279
280 const [data, setData] = useState<ApiGraph | null>(null);
281 const [error, setError] = useState<string | null>(null);
282 const [loading, setLoading] = useState(true);
283
284 const [hoverCard, setHoverCard] = useState<{ api: ApiNode; sx: number; sy: number } | null>(null);
285
286 const wrapRef = useRef<HTMLDivElement>(null);
287 const canvasRef = useRef<HTMLCanvasElement>(null);
288 const simRef = useRef<Simulation<SimNode, SimLink> | null>(null);
289 const nodesRef = useRef<SimNode[]>([]);
290 const linksRef = useRef<SimLink[]>([]);
291 const neighborRef = useRef<Map<string, Set<string>>>(new Map());
292 const transformRef = useRef<ZoomTransform>(zoomIdentity);
293 const zoomRef = useRef<ZoomBehavior<HTMLCanvasElement, unknown> | null>(null);
294 const hoverIdRef = useRef<string | null>(null);
295 const selectedIdRef = useRef<string | null>(null); // 点击选中并持久高亮的节点
296 const draggingRef = useRef<SimNode | null>(null);
297 const dprRef = useRef<number>(1);
298 const sizeRef = useRef<{ w: number; h: number }>({ w: 1, h: 1 });
299 const themeRef = useRef<Palette>(DARK);
300 const pointerDownRef = useRef<{ x: number; y: number; moved: boolean } | null>(null);
301
302 themeRef.current = theme === "dark" ? DARK : LIGHT;
303
304 // ---------- 数据加载 ----------
305 useEffect(() => {
306 let cancelled = false;
307 setLoading(true);
308 setError(null);
309 const sp = new URLSearchParams();
310 if (filterType) sp.set("type", filterType);
311 if (filterTag) sp.set("tag", filterTag);
312 if (includeArchive) sp.set("include_archive", "1");
313 fetch(`/api/graph${sp.toString() ? "?" + sp.toString() : ""}`)
314 .then((r) => r.json())
315 .then((d: ApiGraph & { error?: string }) => {
316 if (cancelled) return;
317 if (d.error) {
318 setError(d.error);
319 setData({ nodes: [], edges: [] });
320 return;
321 }
322 setData({ nodes: d.nodes || [], edges: d.edges || [] });
323 })
324 .catch((e: unknown) => {
325 if (!cancelled) setError(String(e));
326 })
327 .finally(() => {
328 if (!cancelled) setLoading(false);

Callers

nothing calls this directly

Calls 12

useTFunction · 0.90
clampFunction · 0.85
mixWhiteFunction · 0.85
mixBlackFunction · 0.85
truncateToWidthFunction · 0.85
setSizeFunction · 0.85
nodeRadiusFunction · 0.85
shortLabelFunction · 0.85
cardForFunction · 0.85
panelStyleFunction · 0.85
zoomByFunction · 0.85
tFunction · 0.50

Tested by

no test coverage detected