Skip to main content
Features

Knowledge Graph Obsidian Preset

One-click Obsidian demo preset, full-graph fit behavior, and admin persistence for Arcturus-Prime's Tendril-powered graph

March 1, 2026 Updated March 1, 2026

Knowledge Graph Obsidian Preset

Arcturus-Prime now includes a dedicated Obsidian-style preset path for the KnowledgeGraph component, with both live and persistent workflows:

  • Live apply: Obsidian Preset button in the graph physics panel
  • Persistent apply: Apply Obsidian Preset button in /admin/graph-settings

This is designed for demo quality: clean visual hierarchy, calmer motion, and reliable full-graph framing after settle.

Where it lives

SurfaceFile
Graph runtime + UIsrc/components/KnowledgeGraph.astro
Admin persistent presetsrc/pages/admin/graph-settings.astro

Preset behavior

The preset applies a tuned package of settings:

  • Physics: center/repel/link/distance/damping, settle behavior, bounding box
  • Styling: low-noise text and edge treatment for a cleaner Obsidian-like look
  • Node sizing: compact min/max sizing and tag ratio
  • Layout startup mode: obsidian-circle (consumer-handled startup path)
  • Container: wider demo framing (min(96vw, 1280px), 16 / 10)

Fit and framing improvements

A dedicated helper now fits and centers the graph after key transitions:

  • when physics settles
  • when reset is clicked
  • when fullscreen toggles
  • when static layout modes are selected
  • after Obsidian preset application

A zoom cap is also applied post-fit to avoid over-zooming dense graphs.

2026-03-01 follow-up: startup centering hardening

After the first Obsidian preset release, a real-world issue still appeared in some sessions: the graph loaded tiny in a corner and looked offset from center.

Root cause

Container dimensions (clientWidth, clientHeight) weren’t ready when enableObsidianMode() ran at initialization. The circle layout seeding depends on knowing the viewport size.

What changed (March 1, 2026)

  1. Triple-resize with delays: Startup now does multiple resize cycles with setTimeout delays to ensure container dimensions are ready before applying the layout
  2. Multiple fit passes: Calls fitGraphForDemo() three times with increasing delays to handle CSS/viewport settling
  3. Forced Obsidian by default: Blog (/blog) and tag pages (/tag/*) now load with Obsidian circle layout automatically - no need to click the button
// Before: single call
enableObsidianMode();

// After: delayed multi-pass
setTimeout(() => {
    graph.resize();
    setTimeout(() => {
        graph.resize();
        enableObsidianMode();
    }, 150);
}, 50);

User-visible result

  • Graph starts centered and properly sized on page load
  • Obsidian circle + dandelion visible immediately without clicking any buttons
  • No more zoomed-out/corner view on fresh page load

Two Obsidian Layout Modes

obsidian-circle (Global View)

The original dandelion pattern:

  • Center: highest-degree tag
  • Inner ring: other major tags
  • Outer rings: posts grouped by their primary tag anchor
  • Best for: overview of entire knowledge base

obsidian-local (Local View) — New

Compact organic cluster like Obsidian’s actual local graph:

  • Center: Index node or highest-degree node

  • Inner ring: direct connections (1 hop) in tight cluster

  • Second ring: 2-hop connections grouped near their parents

  • Outer: remaining nodes

  • Best for: exploring local neighborhood of connected notes

  • Feels like: spider web around current note

Default: Blog and tag pages now use obsidian-local by default.

Layout and behavior correctness fixes

Initial layout now honors config

Graph initialization now reads config.layout.initialLayout instead of hardcoding a specific startup layout path.

Non-layout mode buttons no longer trigger invalid layout calls

Controls that use data-mode are handled as mode actions and no longer call setLayout(undefined).

Single-use tag filtering is config-driven

Tag filtering now follows behavior.filterSingleUseTags instead of being always-on.

Known technical nuance

Tendril’s current runtime physics loop is driven by global linkDistance. Per-edge length metadata is present but not fully authoritative in force calculation yet. To improve observed behavior, Arcturus-Prime maps spine/bridge slider values into a weighted global link distance at runtime.

For full per-edge spring realism, the next step is a library-level enhancement in @tendril/graph to use edge-specific length/weight during link force computation.

knowledge-graphtendril-graphobsidianvisualizationdemograph-settings