diff --git a/backend/resources/app/templates/graph-console.tmpl b/backend/resources/app/templates/graph-console.tmpl index ad4b7a1aa4..53e981fcb0 100644 --- a/backend/resources/app/templates/graph-console.tmpl +++ b/backend/resources/app/templates/graph-console.tmpl @@ -570,9 +570,16 @@ Graph Console // Legend glyph characters mirroring the G6 node types above. const GLYPH_CHARS = { diamond: "◆", rect: "■", hexagon: "⬢", circle: "●", triangle: "▲", star: "★" }; - // Above this many nodes the view is not rendered automatically; the - // "Render anyway" button forces it (~1.5 s per 2k nodes, measured). + // Above this many nodes/edges the view is not rendered automatically; + // the "Render anyway" button forces it (~1.5 s per 2k nodes, measured; + // edges gate the guard too since plugin/combo cost scales with them). + // Escape hatch: /dbg/graph?safe disables auto-render entirely, so a + // page that hung on render can always be re-entered. const RENDER_GUARD_NODES = 4000; + const RENDER_GUARD_EDGES = 8000; + // Edge bundling is iteration-heavy in the number of edges — a + // page-freezing cost at scale; bundle only small graphs. + const BUNDLE_MAX_EDGES = 300; // G6's entrance/update animation is nice didactics on small graphs but // the performance killer at scale (>2 min at 1700 nodes vs ~1.5 s off); // keep it only below this node count. @@ -910,7 +917,7 @@ Graph Console // empty canvas clears. Runs alongside the node:click inspector. { type: "click-select", degree: 1, state: "selected", neighborState: "active", unselectedState: "inactive" }], - plugins: [{key: "edge-bundling", type: "edge-bundling"},{ + plugins: [{ key: "toolbar", type: "toolbar", position: "top-left", @@ -936,6 +943,9 @@ Graph Console }] }; if (layoutCfg) opts.layout = layoutCfg; + if (g6data.edges.length <= BUNDLE_MAX_EDGES) { + opts.plugins.unshift({ key: "edge-bundling", type: "edge-bundling" }); + } g6graph = new G6.Graph(opts); // Re-attached on every instance creation (layout/animation switches // destroy and recreate the graph). @@ -1070,9 +1080,14 @@ Graph Console ? " — query filter: " + data.nodes.length + " of " + lastGraphData.nodes.length + " nodes" : ""; - if (shown.nodes.length > RENDER_GUARD_NODES && !renderForced) { + const safeMode = new URLSearchParams(location.search).has("safe"); + if ((safeMode + || shown.nodes.length > RENDER_GUARD_NODES + || shown.edges.length > RENDER_GUARD_EDGES) && !renderForced) { graphViewStatus.textContent = - graphStatusText(data) + filterNote + " — too large to render automatically"; + graphStatusText(data) + filterNote + + (safeMode ? " — safe mode (?safe): auto-render off" + : " — too large to render automatically"); if (anywayBtn) anywayBtn.style.display = "inline"; return; }