Node Tree Graph

approved

by Zheng YUAN

Visualize your vault as a hierarchical heading-based graph. Break notes into granular nodes based on their internal heading structure. - This plugin has not been manually reviewed by Obsidian staff.

↓ 26 downloadsUpdated 12d agoGPL-3.0

Node Tree Graph

Plugin type: Graph View Obsidian min version

Visualize your vault as a hierarchical heading-based graph. Break notes into granular nodes based on their internal heading structure.

πŸ“Œ User Guides

Core Concepts

By default, Obsidian’s built-in graph view treats each .md file as a single node. This plugin breaks down your markdown documents into a hierarchical node tree:

  1. Root Node: The markdown file itself (just like Obsidian’s default graph).
  2. Leaf Nodes: Level $N$ headings ($H_1$ to $H_6$) inside the file, representing sub-topics and sections.

This gives you control over how granular your graph visualization can be, allowing you to trace connections between specific sections of different notes without losing context.

Key Features

  1. Max Heading Levels: Choose how deep the graph searches (from $H_1$ up to $H_6$).
  2. Flexible Link Rollup: When headings are hidden, links associated with those hidden sections can automatically roll up to the nearest visible ancestor node or be cleanly discarded.
  3. Hover Filtering: Highlight related nodes when hovering:
    1. Neighbor Direction: Search Downward (children), Upward (parents), or Both.
    2. Neighbor Depth: Limit how many connections away the search reaches.
  4. Fully customizable Visuals & Physics.
    1. Nodes: coloring mode, base node radius, and relative scales for ($H_1$ to $H_6$).
    2. Edges: width, color, style, and alpha.
    3. Font: font family, size, color, option to scale with node size, and size multiplier.
    4. Physics: simulation related settings.

Example

The following example is created using a obsidian-test-vault.

Demo

Installation

From the Community Plugin Directory [TBD]

  1. Open Obsidian β†’ Settings β†’ Community plugins
  2. Search for Node Tree Graph
  3. Click Install, then Enable

Manual Installation

  1. Download main.js, manifest.json, and styles.css from the latest release
  2. Copy them into {vault}/.obsidian/plugins/node-tree-graph/
  3. Enable the plugin in Settings β†’ Community plugins

Search Filter Syntax

The search input in the Filters section follows Obsidian's official search syntax to filter which file trees appear in the graph:

SyntaxMatchesExample
path:textFile path contains textpath:cs101
file:textFile name contains textfile:Algorithm
tag:nameFile has exact tag nametag:exam
[property]File has frontmatter property property[author]
[property:val]Property equals val exactly[status:draft]
[property:<n]Numeric property less than n[count:<5]
[property:>n]Numeric property greater than n[count:>3]
[property:null]Property exists but is empty[author:null]
"multi word"Quoted strings preserve spacesfile:"Algorithm Complexity"
ORMatch any of the adjacent termstag:exam OR tag:homework
-Exclude matching files-tag:draft
SpaceAND logic between groupstag:cs file:Algorithm

Examples

QueryResult
tag:examFiles with the exam tag
tag:exam OR tag:homeworkFiles with either exam or homework tag
tag:cs tag:beginnerFiles with BOTH cs AND beginner tags
path:cs101 tag:examFiles under cs101/ AND tagged exam
-tag:draftFiles NOT tagged draft
[author]Files that have an author property
[course:cs201]Files where course equals cs201
file:"Data Structures"File named exactly "Data Structures"

Autocomplete suggestions appear automatically when typing tag:, file:, path:, or [.

Developer Guides

Project Structure

src/
β”œβ”€β”€ main.ts                     # Plugin entry point
β”œβ”€β”€ settings.ts                 # PluginSettingTab + DEFAULT_SETTINGS
β”œβ”€β”€ types.ts                    # TypeScript type definitions
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ graph-view.ts           # ItemView (graph pane)
β”‚   β”œβ”€β”€ graph-renderer.ts       # PixiJS renderer + simulation
β”‚   β”œβ”€β”€ popup-panel.ts          # Settings/filter popup overlay
β”‚   β”œβ”€β”€ node-sprites.ts         # Node shape + label creation
β”‚   β”œβ”€β”€ physics.ts              # Force-directed simulation
β”‚   β”œβ”€β”€ search-autocomplete.ts  # Autocomplete for search filters
β”‚   β”œβ”€β”€ control-panel.ts        # Sidebar control panel (stub)
β”‚   β”œβ”€β”€ debug-overlay.ts        # Performance metrics overlay (stub)
β”‚   β”œβ”€β”€ legend.ts               # Mini legend (stub)
β”‚   └── onboarding.ts           # First-run onboarding (stub)
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ tree-manager.ts         # Cache + treeβ†’graph conversion + search filter
β”‚   β”œβ”€β”€ parser.ts               # Markdown β†’ NodeTree parser
β”‚   β”œβ”€β”€ cache.ts                # LRU cache manager
β”‚   β”œβ”€β”€ colors.ts               # Color resolution
β”‚   β”œβ”€β”€ shapes.ts               # Shape resolution
β”‚   β”œβ”€β”€ sanitize.ts             # Label formatting
β”‚   β”œβ”€β”€ constants.ts            # Plugin constants
β”‚   └── rollup.ts               # Link rollup logic
└── commands/
    └── index.ts                # Command palette commands

Components

  1. Settings panel.
  2. Popup panel: the popup panel by clicking the gear icon from canvas.
    1. Tooltip panel: the popup panel when typing in search input box.

How It Works

  1. Parser (src/utils/parser.ts): Each markdown file is parsed into a NodeTree: headings form the hierarchy, wiki links and embeds are assigned to their owning heading block based on line position. Frontmatter properties and tags are extracted.
  2. Tree Manager (src/utils/tree-manager.ts): Maintains an LRU cache of parsed trees, listens for vault metadata changes, and regenerates graph nodes and edges on demand. The search filter operates at this level β€” excluded trees never become graph nodes.
  3. Graph Renderer (src/ui/graph-renderer.ts): PixiJS WebGL renderer draws nodes as colored geometric shapes with text labels, connected by tree edges (parent→child) and link edges (wiki links). Node visibility is driven by the pipeline: orphan/file-level filtering → tag/attachment toggles → hover dimming.
  4. Force Simulation (src/ui/physics.ts): Semi-implicit Euler integration with many-body repulsion, spring attraction, centering force, tree separation multiplier, and simulated annealing (alpha decay).

Development Build

git clone https://github.com/zhengyuan-public/obsidian-node-tree-graph.git
cd obsidian-node-tree-graph
npm install
npm run build

Then symlink or copy the repo into your vault's .obsidian/plugins/ directory.

Localization (i18n)

Node Tree Graph supports multiple languages. The interface language is automatically detected from your Obsidian settings.

Supported languages:

LanguageCodeCoverage
Englishenβœ“
Chinese Simplifiedzhβœ“
Chinese Traditionalzh-TWβœ“
Germandeβœ“
Japanesejaβœ“
Frenchfrβœ“
Koreankoβœ“
Spanishesβœ“
Portuguese (Brazil)pt-BRβœ“
Russianruβœ“

Contributing translations

The initial translations were translated by AI from English and may contain inaccuracies. If you're a native speaker of any of these languages, we'd love your help improving them! To contribute:

  1. Copy src/i18n/en.ts as a reference for all available keys
  2. Edit the translation file for your language in src/i18n/<code>.ts
  3. Submit a pull request with your changes

New languages are also welcome, just create a new file following the same format and register it in src/i18n/index.ts.

Adding a new language:

// src/i18n/it.ts
const it: Record<string, string> = {
  'view.display-name': 'Grafo ad Albero',
  'filter.tags': 'Etichette',
  // ...translate all keys from en.ts
};
export default it;

Then register it in index.ts:

import it from './it';
const locales = { ..., it };

Tech Stack

Known Issues & Roadmap

Needs Fixing

#IssueDetails
1Search filter bugsSome filter combinations produce incorrect results. The tokenizer and OR/AND grouping logic need review against real-world queries.
2Simulation tuningDefault physics parameters (repulsion, attraction, damping) need further tuning. The author is having trouble finding optimal combinations for different vault sizes.
3Mobile supportThe plugin has not been tested on Obsidian Mobile (iOS/Android). PixiJS WebGL rendering and touch interactions may need adjustments.
4Large vault performanceNot tested on vaults with 1000+ notes or 10,000+ headings. Progressive viewport loading is implemented but untuned.
5Search syntax gapOR operator uses , internally; should align with Obsidian's OR keyword. Property exact match uses = instead of :. Grouping with () is not yet supported.
6Tag edges in orphan detectionGlossary.md-style files with tags are incorrectly treated as non-orphans because tag edges count as wiki links.
7Popup panel stylingCustom CSS overrides on sliders/toggles can conflict with Obsidian themes. Needs theme-variable-only approach.

Not Yet Implemented

#FeatureDetails
8Physics presetsThe Presets dropdown (Default / Compact / Spread) is a placeholder. It should save and restore physics parameter snapshots.
9Control panelsrc/ui/control-panel.ts stub only. Sidebar with quick-access controls.
10Debug overlaysrc/ui/debug-overlay.ts stub only. FPS counter, node count, memory usage overlay.
11Legendsrc/ui/legend.ts stub only. Mini legend showing shape/color meanings.
12Onboardingsrc/ui/onboarding.ts stub only. First-run welcome modal with quick setup.
13property: filterObsidian's native property:value syntax is not supported yet (only bracket [prop] syntax works).
14line: / section: filtersObsidian's content-level filters not implemented β€” our filters operate at file level only.
15Regex search/pattern/ syntax from Obsidian's search is not supported.
16content: filterFile body content search not implemented.
17Export graph stateGraphStateExport type is defined but no export UI exists.

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.