The 3-Hour Physics Session
Date: February 1, 2026 Duration: ~3 hours Issue: Knowledge graph felt mechanical, not organic Root Cause: All edges were the same length
The Problem
For months, the ArgoBox knowledge graph worked but felt wrong.
Nodes settled too quickly. Clusters were uniform. It had a mechanical quality that Obsidian’s graph never has.
I’d tweaked centerForce, repelForce, damping… nothing fixed the underlying deadness.
Today I decided to figure it out once and for all.
Hour 1: Research
Opened Obsidian. Stared at my vault’s graph. Actually looked at it.
What I noticed:
- Tags form central hubs
- Posts radiate outward like spokes
- Hubs are far apart from each other
- The whole thing has a “sea urchin” or “dandelion” shape
My graph:
- Everything clumped together
- No clear hub/spoke pattern
- Uniform spacing everywhere
Hypothesis: Obsidian uses variable edge lengths.
Hour 2: Implementation
The key insight: not all connections are equal.
Spines - Connections to leaf nodes (low degree)
- Should be short
- Should be stiff
- Creates tight satellite orbits around hubs
Bridges - Connections between hubs (high degree)
- Should be long
- Should be loose
- Creates separation between clusters
let isLeafConnection = sourceDegree <= 2 || targetDegree <= 2;
let length = isLeafConnection ? spineLength : bridgeLength;
let weight = isLeafConnection ? 1.5 : 0.1;
First test: spineLength=10, bridgeLength=150.
The graph reorganized. Hubs formed. Satellites radiated outward.
It looked… right.
Hour 3: Refinement
Added interactive sliders:
- Spine Length (1-50, default 10)
- Bridge Length (50-400, default 150)
- Node Scale (0.3-3.0, default 1.0)
- Label Threshold (1-15, default 3)
Found optimal values:
Spine Length: 3-5
Bridge Length: 200-300
Node Scale: 0.5-0.7
Label Threshold: 8-10
Repel Force: 4000-6000
Center Force: 0.05
Also fixed text clutter:
- Posts: show label only if node > 4px
- Tags: show label only if degree > 5
And added bounding box constraint:
- Prevents nodes from flying to infinity
- Allows near-zero gravity without explosion
The Result
Before: Static, mechanical, dead on arrival
After: Organic, floating, actually feels like Obsidian
The difference is night and day. Same underlying library (Cytoscape.js), completely different feel.
Issues Fixed Along the Way
Graph disappearing after load
- Cause: Zero gravity + high repulsion = nodes at infinity
- Fix: Bounding box constraint
No visible change when toggling Obsidian mode
- Cause: Layout not re-running after edge data update
- Fix: Call
setLayout('cose')after modifying edges
Physics panel not scrollable
- Cause: Missing overflow CSS
- Fix:
max-height: calc(100vh - 120px); overflow-y: auto;
Files Modified
| File | Changes |
|---|---|
KnowledgeGraph.astro | Spine/bridge logic, new sliders, bounding box |
| CSS | Physics panel scrolling, constellation popup |
Lessons
Variable edge lengths are the secret. I could have saved months if I’d analyzed Obsidian’s graph more carefully.
Interactive tuning is essential. Without the sliders, I would have spent 10x longer finding good values.
Bounding boxes solve the gravity problem. I thought I needed to tune gravity perfectly. Nope, just contain the nodes.
Next Steps
- Add more tag hierarchy relationships
- Consider cluster coloring by parent tag
- Save slider values to localStorage
- Extract this as the Tendril open-source library
Victory
At some point during hour 3, I just sat back and watched the graph float.
Posts drifted gently around their tag hubs. Hubs maintained respectful distance from each other. The whole thing breathed.
That was the moment I knew it was done.
Three hours. Variable edge lengths. That’s all it took.