Skip to content

Fix: remap hyperedges in community-aggregated meta-graph view#1006

Merged
safishamsi merged 1 commit into
Graphify-Labs:v8from
aadi-novice:fix/hyperedges-aggregated-view
May 27, 2026
Merged

Fix: remap hyperedges in community-aggregated meta-graph view#1006
safishamsi merged 1 commit into
Graphify-Labs:v8from
aadi-novice:fix/hyperedges-aggregated-view

Conversation

@aadi-novice

Copy link
Copy Markdown
Contributor

Summary

When a graph exceeds GRAPHIFY_VIZ_NODE_LIMIT (default 1000 via _viz_node_limit(), falling back to MAX_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 rendered graph.html always emits const hyperedges = []; — even when graph.json contains plenty.

The visible result: the afterDrawing handler that renders hyperedge regions silently no-ops on every large project, even though hyperedges are extracted, persisted to graph.json, and merged correctly through the rest of the pipeline.

Root Cause

In graphify/export.pyto_html at the over-limit branch builds a fresh meta-graph and recursively calls itself, but never sets meta.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.

  • Handles both "nodes" and "members" keys for backward compatibility with different hyperedge formats
  • Deduplicates community IDs per hyperedge
  • Falls back from label to relation for display text when label is missing
  • Attaches remapped hyperedges to meta.graph["hyperedges"] so the recursive call picks them up

Testing

  • All 37 existing tests in tests/test_export.py and tests/test_hypergraph.py pass

Fixes #1005

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 safishamsi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Unique hyperedge IDs: he.get('id', '') produces duplicate empty-string IDs when multiple hyperedges lack an id field. A simple f'he_{i}' fallback would be safer for any downstream JS that keys on id.

  2. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: hyperedges always empty in graph.html when graph exceeds viz node limit (aggregated meta-graph drops them)

2 participants