Summary
In graph.html, clicking a neighbour link in the NODE INFO panel updates the panel but silently does nothing to the canvas when the target node's community is currently filtered out. Two of focusNode()'s three actions become no-ops, so the graph never moves and there is no feedback explaining why.
Reproduce
- Build a graph large enough to render the aggregated community view (mine is 28,959 nodes → 2,218 communities).
- Open
graphify-out/graph.html.
- Untick Select All to hide every community.
- Tick a single community — I used
MySQLWrapper.
- Click that node to populate the NODE INFO panel.
- Click any neighbour in the Neighbors (N) list whose community is still unticked.
Expected: the graph focuses the clicked node, or the UI indicates why it cannot.
Actual: the panel navigates to the new node and lists its neighbours, but the canvas is unchanged. The node stays invisible, nothing is selected, the camera does not move, and no message is shown. It reads as a dead click.
Cause
focusNode() has no notion that a node may currently be filtered out:
function focusNode(nodeId) {
network.focus(nodeId, { scale: 1.4, animation: true });
network.selectNodes([nodeId]);
showInfo(nodeId);
}
The community filter hides nodes rather than removing them:
const updates = RAW_NODES.filter(n => n.community === c.cid)
.map(n => ({ id: n.id, hidden: !cb.checked }));
nodesDS.update(updates);
So for a node carrying hidden: true:
| call |
result |
network.focus(nodeId, …) |
no rendered position — silent no-op |
network.selectNodes([nodeId]) |
selects something invisible |
showInfo(nodeId) |
works, reads the underlying data |
Only the panel updates. Both files: graphify/exporters/html.py.
Suggested fix
Reveal the target's community before focusing, by firing the legend checkbox's existing change handler rather than duplicating its body — that keeps hiddenCommunities, the dimmed styling, nodesDS and the Select-All tri-state consistent through one code path.
Register the checkboxes as the legend is built:
const CB_BY_CID = new Map();
// …in the LEGEND.forEach loop, after `cb.checked = true;`
CB_BY_CID.set(c.cid, cb);
Then:
function focusNode(nodeId) {
const n = RAW_NODES.find(x => x.id === nodeId);
if (n && hiddenCommunities.has(n.community)) {
const cb = CB_BY_CID.get(n.community);
if (cb) { cb.checked = true; cb.dispatchEvent(new Event('change')); }
}
network.focus(nodeId, { scale: 1.4, animation: true });
network.selectNodes([nodeId]);
showInfo(nodeId);
}
I have been running this patch locally against 0.9.55. With it, the repro above takes the checked-community count from 1 → 2 and visible nodes from 1 → 2, and the two nodes render with the edge between them.
If you would rather not have a click implicitly change the filter, an alternative is to leave the filter alone and surface the state instead — for example, disabling or annotating neighbour links whose community is hidden, so the click is visibly unavailable rather than inert. Happy to send a PR for whichever behaviour you prefer.
Notes
- Reproduced on the aggregated community view. The same logic runs for the node-level view, so it should reproduce there too whenever a community is filtered out.
- Regenerating after editing the exporter needs
graphify cluster-only <path>; graphify update <path> --force re-extracts but stops at "No code-graph topology changes detected; outputs left untouched" and leaves the old graph.html in place. That was mildly confusing while testing, and may be worth a mention in the docs.
Environment
- graphify 0.9.55 (
uv tool install "graphifyy[sql,mcp,bedrock,leiden]")
- macOS 15 (Darwin 25.6.0), arm64, Python 3.11
- Corpus: 4,181 files, 28,959 nodes / 61,576 edges / 2,218 communities
Summary
In
graph.html, clicking a neighbour link in the NODE INFO panel updates the panel but silently does nothing to the canvas when the target node's community is currently filtered out. Two offocusNode()'s three actions become no-ops, so the graph never moves and there is no feedback explaining why.Reproduce
graphify-out/graph.html.MySQLWrapper.Expected: the graph focuses the clicked node, or the UI indicates why it cannot.
Actual: the panel navigates to the new node and lists its neighbours, but the canvas is unchanged. The node stays invisible, nothing is selected, the camera does not move, and no message is shown. It reads as a dead click.
Cause
focusNode()has no notion that a node may currently be filtered out:The community filter hides nodes rather than removing them:
So for a node carrying
hidden: true:network.focus(nodeId, …)network.selectNodes([nodeId])showInfo(nodeId)Only the panel updates. Both files:
graphify/exporters/html.py.Suggested fix
Reveal the target's community before focusing, by firing the legend checkbox's existing
changehandler rather than duplicating its body — that keepshiddenCommunities, thedimmedstyling,nodesDSand the Select-All tri-state consistent through one code path.Register the checkboxes as the legend is built:
Then:
I have been running this patch locally against 0.9.55. With it, the repro above takes the checked-community count from 1 → 2 and visible nodes from 1 → 2, and the two nodes render with the edge between them.
If you would rather not have a click implicitly change the filter, an alternative is to leave the filter alone and surface the state instead — for example, disabling or annotating neighbour links whose community is hidden, so the click is visibly unavailable rather than inert. Happy to send a PR for whichever behaviour you prefer.
Notes
graphify cluster-only <path>;graphify update <path> --forcere-extracts but stops at "No code-graph topology changes detected; outputs left untouched" and leaves the oldgraph.htmlin place. That was mildly confusing while testing, and may be worth a mention in the docs.Environment
uv tool install "graphifyy[sql,mcp,bedrock,leiden]")