import { useState } from "react"; import { useSearchParams } from "react-router"; import type { Graph } from "../api"; import { useFetch } from "../hooks"; import { ErrorBox, Loading } from "../components/ui"; import { LayeredGraph } from "../components/Graph"; export default function GraphPage() { const [sp, setSp] = useSearchParams(); const focus = sp.get("focus") ?? ""; const depth = Number(sp.get("depth") ?? 2); const [f, setF] = useState(focus); const { data, error, loading } = useFetch(`graph?focus=${encodeURIComponent(focus)}&depth=${depth}`); const types = data ? Array.from(new Set(data.nodes.map((n) => n.type))) : []; return (

Knowledge Graph

Relational entities and lineage edges. Columns are entity types; click a node to open it. Focus on one node (type:id) to trim the neighbourhood.

{ e.preventDefault(); setSp({ focus: f, depth: String(depth) }); }}> setF(e.target.value)} list="nodes" /> {data?.nodes.slice(0, 500).map((n) => )} {focus && }
{loading && } {data && <>
{data.nodes.length} nodes · {data.edges.length} edges · types: {types.join(", ") || "none"}
}
); }