Knowledge Map
The 2D scatter map at /knowledge — zoom, pan, and cluster visualization across the knowledge graph.
Knowledge Map
The knowledge map at /knowledge renders every entity in the graph as a dot on a 2D canvas. Proximity means semantic similarity — neighboring dots share topical content, whether that's "tools that dedupe customer records" or "papers about supply-chain attestation".
Layout pipeline
The map isn't computed in the browser. It's pre-baked from backend embeddings by scripts/build-knowledge-map.py:
- Embeddings — 768-dim vectors per entity, fetched from the backend's knowledge proxy
- UMAP — reduces 768 → 2 dimensions for the plot
- HDBSCAN — clusters at four density tiers so we can show appropriate labels at each zoom level
- k-NN — 8 nearest neighbors per entity, used for the hover-connection feature
- c-TF-IDF — generates human-readable cluster labels from note text
The output is a single JSON file (frontend/public/knowledge-map.json) served as a static asset — no runtime compute.
Interactive controls
| Action | Behavior |
|---|---|
| Scroll / pinch | Zoom in and out (uncapped, so you can drill into dense clusters) |
| Click + drag | Pan the canvas |
| Click a dot | Select the entity, open the detail popover, show 8 k-NN neighbors as halos |
| Click a cluster label | Pan + zoom to fit the cluster's extent |
?focus={id} query param | Deep-link directly to an entity — the map pans and selects that dot on load |
Progressive label density
Labels get crowded at continent-scale zoom. The map cross-fades through four label tiers as the user zooms:
| Tier | When shown | Typical label |
|---|---|---|
| 0 | Fully zoomed out | "Entity Resolution", "Blockchain", "Sanctions" |
| 1 | Medium zoom | "ER benchmarks", "Wallet attribution" |
| 2 | Close zoom | "NC Voter 5K", "BPID Benchmark" |
| 3 | Individual entities | Repo names, paper titles |
The transitions use alpha blending at level boundaries so labels don't snap in or out.
Search integration
The search bar at the top of /knowledge runs against the same backend entity index. Selecting a hit pans the map to the matching dot via ?focus={entityId}. Search and map share state through the useOpenSource hook in frontend/app/knowledge/use-open-source.ts.
Implementation notes
- Canvas uses a non-passive wheel listener attached via
addEventListener— not React'sonWheel— so it canpreventDefault()and intercept the scroll - All
useEffect/useRefhooks must live above anyif (failed) return nullearly return, per React rules-of-hooks - Label collision detection happens per frame; text extents cached per label to avoid repeated measurements