Obsidian Graph Panel

Display an Obsidian-style relationship graph of Markdown files in VS Code. It can visualize link relationships between Markdown files, and open the selected Markdown file directly with a single click.
✨ Features
Auto Parsing
- Recursively scans all
.md files in the workspace (skips hidden directories such as .obsidian)
- Recognizes Obsidian double brackets:
[[filename]], [[filename|alias]], [[filename#heading]]
- Recognizes standard Markdown links (
text + path in parentheses): 3 forms — root / subdirectory / folder style
- Subdirectory files are fully supported: node IDs use relative paths (e.g.
sub/file), click to open the correct file
- Link resolution strategy: exact match → folder fallback (
[[foo]] → foo/index.md) → basename fuzzy match → same-directory priority
- Dangling links (pointing to non-existent files) are silently ignored
- Edges are automatically deduplicated — no duplicate links between the same pair of nodes
Visualization Layout
- Nodes start randomly scattered within a circular area (uniform distribution)
- Force-directed simulation: repulsion between nodes + spring forces along edges + weak center attraction
- After release, all nodes are pulled back to a uniform circular layout by the circular restoring force
- Zoom level is fully independent from graph shape
Interaction
- Scroll wheel zoom: centered on the cursor, with a smooth step
- Drag a node: the dragged node is pinned; its edges stretch like rubber bands and pull connected nodes along
- Click a node: opens the corresponding Markdown file's VS Code native preview via
markdown.showPreview
- Drag empty background: pan the whole graph without changing zoom or shape
- Mouse hover: shows a glassmorphism filename label above the hovered node (visible at any zoom level)
UI Features
- Dark / light theme: auto-adapts to the current VS Code theme on open; can be toggled manually with the button in the top-left corner
- Glassmorphism label: semi-transparent background + double-layer stroke + text shadow
- When zoomed in past
zoom > 1.5, file names stay displayed below nodes; hidden when zoomed out to reduce visual clutter
🚀 Usage
Open the Graph (4 ways)
- Editor title bar icon — open any
.md file; a graph icon appears on the right of the title bar
- Explorer title bar icon — a graph icon appears at the top of the Explorer panel
- Explorer context menu — right-click a
.md file or folder → choose "Open Obsidian Graph Panel"
- Command Palette —
Ctrl+Shift+P (macOS: Cmd+Shift+P) → type "Open Obsidian Graph Panel"
In-graph Operations
| Action |
Behavior |
| Scroll wheel up / down |
Zoom in / out centered on the cursor |
| Press and drag a node |
Move the node; connected edges produce a rubber-band effect; layout restores to a circle on release |
| Click a node (no drag) |
Open the corresponding Markdown file in VS Code's native preview |
| Hover a node |
Show a glassmorphism label with the file name |
| Press and drag empty background |
Pan the whole graph panel |
| Top-left "🌙 / ☀️" button |
Manually toggle dark / light theme |
⚙️ Configuration
Open Settings (Ctrl+,, macOS: Cmd+,) → search "Obsidian Graph Panel" to independently control the visibility of the three graph entry buttons:
| Setting |
Type |
Default |
Description |
obsidianGraphPanel.showInEditorTitle |
boolean |
true |
Show the "Open Obsidian Graph Panel" icon in the Markdown editor title bar |
obsidianGraphPanel.showInExplorerTitle |
boolean |
true |
Show the "Open Obsidian Graph Panel" icon in the Explorer panel title bar |
obsidianGraphPanel.showInExplorerContext |
boolean |
true |
Add "Open Obsidian Graph Panel" to the Explorer right-click menu |
Changes take effect immediately — no VS Code restart required. The Command Palette entry is always available and is not affected by these settings.
🙈 Ignoring Files (.panelignore)
The relationship graph, the tag sidebar, and the file-type sidebar all scan your entire workspace. To exclude paths or files you don't want them to see (build outputs, dependencies, OS junk, Obsidian internal folders, etc.), drop a .panelignore file at the root of your workspace.
.panelignore follows the same syntax as .gitignore:
# Comments and blank lines are ignored.
# Lines written before any [section] header apply to ALL three views.
node_modules/
.DS_Store
dist/
[graph] # Patterns here apply ONLY to the relationship graph
.hg/
.svn/
[tags] # Patterns here apply ONLY to the tag sidebar
[types] # Patterns here apply ONLY to the file-type sidebar
| Behavior |
Detail |
| Default section |
Lines before any [section] header are merged into every view's pattern set. |
| Section header |
[graph], [tags], [types] — case-insensitive, unknown names are silently ignored. |
| Section patterns |
Added on top of the default section, scoped to that view only. |
| Missing file |
If .panelignore is absent or unreadable, no filtering is applied (all files are shown). |
| Negation |
A leading ! un-ignores a path that would otherwise be ignored (same semantics as .gitignore). |
A ready-to-use starter
Create a .panelignore file at the root of your workspace. A recommended starter covers common noise (.DS_Store, editor backups, node_modules/, dist/, out/, build/, .git/, .obsidian/, .trash/, Python / Node / framework build artifacts, common IDE folders, etc.) and adds a few view-specific extras in [graph] and [types]. Adjust it to fit your needs:
# OS / editor metadata
.DS_Store
Thumbs.db
*.swp
*~
*.bak
# Temp / logs
*.tmp
*.log
.cache/
# Version control
.git/
# Dependencies
node_modules/
bower_components/
# Build artifacts
dist/
out/
build/
coverage/
.next/
.nuxt/
.astro/
# Python
__pycache__/
.venv/
venv/
# IDEs
.idea/
.vscode-test/
# Obsidian vault internals
.obsidian/
.trash/
[graph]
.hg/
.svn/
[types]
*.swp
*.swo
⚠️ Known Limitations
- Edges are undirected (no arrows)
- Dangling links (pointing to non-existent
[[file]]) are silently ignored
- Double bracket aliases (
[[name|alias]]) currently use only the name part as the node ID
- When multiple files share the same name, "same directory first" disambiguation is used; in other cases an unintended file may be picked
If you encounter any issues, find bugs, or have feature suggestions, please open an issue on GitHub: