Fix: remap hyperedges in community-aggregated meta-graph view#1006
Merged
safishamsi merged 1 commit intoMay 27, 2026
Merged
Conversation
When a graph exceeds the viz node limit, to_html() builds a community-aggregated meta-graph and recursively calls itself. The recursive call never carried hyperedges onto the meta-graph, so graph.html always emitted const hyperedges = [] even when graph.json contained plenty. This fix remaps hyperedge node references from semantic node IDs to community IDs before the recursive call, so hyperedge regions render correctly in the aggregated view. Hyperedges that collapse to fewer than 2 distinct communities are dropped (they wouldn't render as a polygon anyway). Fixes Graphify-Labs#1005
safishamsi
reviewed
May 25, 2026
safishamsi
left a comment
Collaborator
There was a problem hiding this comment.
The fix is correct and surgical — remapping logic handles both key variants, orphaned nodes, and collapsed-to-one-community edges properly. Two small requests before merge:
-
Unique hyperedge IDs:
he.get('id', '')produces duplicate empty-string IDs when multiple hyperedges lack anidfield. A simplef'he_{i}'fallback would be safer for any downstream JS that keys onid. -
Regression test: the broken path (graph over node limit + non-empty hyperedges) had no coverage — that's why it shipped silently. A unit test that creates a graph over the limit with hyperedges, calls
to_html(), and asserts the output HTML contains non-empty hyperedge data would lock this in.
Otherwise looks good to merge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a graph exceeds
GRAPHIFY_VIZ_NODE_LIMIT(default 1000 via_viz_node_limit(), falling back toMAX_NODES_FOR_VIZ= 5000),to_html()builds a community-aggregated meta-graph and recursively calls itself. The recursive call never carried hyperedges onto the meta-graph, so the renderedgraph.htmlalways emitsconst hyperedges = [];— even whengraph.jsoncontains plenty.The visible result: the
afterDrawinghandler that renders hyperedge regions silently no-ops on every large project, even though hyperedges are extracted, persisted tograph.json, and merged correctly through the rest of the pipeline.Root Cause
In
graphify/export.py—to_htmlat the over-limit branch builds a fresh meta-graph and recursively calls itself, but never setsmeta.graph["hyperedges"]. Even if forwarded as-is, the hyperedges reference semantic node IDs (e.g.,"UserService") that don't exist in the meta-graph (which uses community IDs like"3"as node IDs).Fix
Remap hyperedges from semantic node IDs to community IDs before the recursive call. Drop entries that collapse to <2 distinct communities — they wouldn't render as a polygon anyway.
"nodes"and"members"keys for backward compatibility with different hyperedge formatslabeltorelationfor display text when label is missingmeta.graph["hyperedges"]so the recursive call picks them upTesting
tests/test_export.pyandtests/test_hypergraph.pypassFixes #1005