# How the Understand-Anything Dashboard Handles Large Graphs with 3000+ Nodes

> Discover how Understand-Anything's dashboard delivers a responsive experience for 3000+ node knowledge graphs using ELK layout, clustering, and adaptive physics.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: performance
- Published: 2026-06-16

---

**The Understand-Anything dashboard combines a two-stage ELK layout, container clustering with size estimation, and adaptive force-directed physics to keep 3000+ node knowledge graphs responsive and interactive.**

The Egonex-AI/Understand-Anything repository provides an open-source dashboard for visualizing complex knowledge graphs. When dealing with massive datasets containing 3000+ nodes, naive rendering approaches cause browser lag and layout instability. The dashboard solves this through a sophisticated multi-stage architecture that balances initial load performance with interactive detail.

## Two-Stage ELK Layout Architecture

The core strategy uses a **two-stage ELK layout** that separates coarse global positioning from detailed local computation.

### Stage 1 - Coarse Layout with Estimated Container Sizes

During initial load, the system in [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx) (lines 1005-1016) invokes `applyElkLayout` to compute a coarse layout for the entire graph. Rather than processing thousands of individual nodes, it treats containers as single atoms with estimated dimensions. In [`layout.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layout.ts) (lines 98-102), the code enforces maximum estimated sizes of `STAGE1_MAX_CONTAINER_WIDTH = 800` and `STAGE1_MAX_CONTAINER_HEIGHT = 600` pixels. This estimation prevents the layout engine from allocating excessive space for containers holding hundreds of nodes, keeping the Stage 1 computation fast regardless of underlying graph size.

### Stage 2 - Lazy Layout for Expanded Containers

When users expand a container, the `useLayerDetailGraph` hook triggers Stage 2. This effect assembles the container's children into a sub-graph (`stage2Input`) and runs a fresh ELK layout only for that specific subset. The results are cached in `containerLayoutCache`, ensuring that reopening an already-expanded container avoids redundant computation. This lazy approach means the browser only calculates precise positions for nodes the user actually wants to see.

### Automatic Re-layout on Size Deviation

After Stage 2 completes, the dashboard compares the actual container size against the Stage 1 estimate (lines 10664-10666 in [`GraphView.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/GraphView.tsx)). If the deviation exceeds 20%, the system calls `bumpStage1Tick()` to re-run Stage 1, reflowing surrounding atoms to accommodate the newly revealed accurate dimensions. This feedback loop ensures the global layout remains coherent without overly pessimistic initial estimates.

## Container Clustering and Edge Aggregation

To reduce visual noise, the dashboard implements **container clustering** that collapses entire layers into single "layer-cluster" nodes.

In `useOverviewGraph` (lines 1125-1170), the `clusterNodes` and `aggEdges` arrays are constructed by aggregating nodes and edges by layer. Edges between layers are consolidated into single weighted connections rendered with logarithmically scaled stroke widths. The `useLayerDetailTopology` hook further applies `aggregateLayerEdges` and `aggregateContainerEdges` to minimize rendered elements. This aggregation dramatically reduces the number of painted nodes from thousands to dozens, while count labels preserve the semantic weight of dense inter-layer relationships.

## Adaptive Force-Directed Layout for Knowledge Graphs

When displaying pure knowledge graphs without architectural layers, the system falls back to a **force-directed layout** with size-aware physics.

The `applyForceLayout` function in [`layout.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layout.ts) (lines 26-30) automatically adjusts simulation parameters based on graph size. For large graphs exceeding 100 nodes, it reduces charge strength from `-350` to `-600` and increases link distance from `150` to `250`. These adjustments prevent the "explosion" effect common in large force simulations and maintain layout stability without manual tuning.

## Testing with 3000-Node Graphs

The repository includes utilities to verify performance at scale. You can generate and load a 3000-node test graph using the provided CLI:

```bash

# Generate synthetic graph with 3000 nodes

pnpm run generate-large-graph 3000

# Starts dev server at http://localhost:3000

pnpm dev:dashboard

```

The script at `scripts/generate-large-graph.mjs` writes the graph to [`.understand-anything/knowledge-graph.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/.understand-anything/knowledge-graph.json). Upon loading, the dashboard displays top-level layer clusters; clicking a cluster triggers Stage 2 layout for that specific container's children, demonstrating the lazy loading architecture.

## Summary

- **Two-stage ELK layout** separates coarse global positioning from detailed local layouts, with Stage 1 using capped size estimates (800×600 px) to keep initial computation fast.
- **Lazy loading** computes precise layouts only for expanded containers, caching results in `containerLayoutCache` to optimize re-expansion.
- **Deviation detection** triggers Stage 1 re-layout when actual container sizes differ by >20% from estimates, maintaining layout coherence.
- **Container clustering** reduces 3000+ nodes to manageable layer clusters with aggregated edges, minimizing DOM elements.
- **Adaptive force-directed physics** automatically scale charge strength and link distance for graphs exceeding 100 nodes, preventing simulation instability.

## Frequently Asked Questions

### Does the dashboard render all 3000 nodes at once?

No. The dashboard only renders visible container atoms and eagerly expanded children. By representing collapsed layers as single cluster nodes and lazily computing Stage 2 layouts, the browser typically paints fewer than 100 SVG elements initially, regardless of total graph size.

### What happens if I expand multiple large containers?

Each expansion triggers an independent Stage 2 layout for that container's children, stored in `containerLayoutCache`. If the cumulative size deviation exceeds 20% of Stage 1 estimates, `bumpStage1Tick()` automatically re-runs the coarse layout to reflow surrounding atoms and prevent overlap.

### Can I adjust the size estimation caps for my specific data?

Yes. The constants `STAGE1_MAX_CONTAINER_WIDTH` and `STAGE1_MAX_CONTAINER_HEIGHT` in [`understand-anything-plugin/packages/dashboard/src/utils/layout.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/dashboard/src/utils/layout.ts) (lines 98-102) control the maximum estimated dimensions. Adjusting these values changes the trade-off between initial layout speed and the frequency of Stage 1 re-computation.

### How does the force-directed layout handle graphs larger than 3000 nodes?

The `applyForceLayout` function scales physics parameters based on the `isLarge` flag (triggered at >100 nodes). For very large graphs, it uses weaker charge strength (`-600`) and longer link distances (`250`), which prevents node repulsion from overwhelming the simulation and keeps the layout calculation performant.