Traversal¶
Traversal is how Trail follows relations to build the trees you see in the Trail pane. Understanding traversal helps you configure groups effectively and predict what you'll see.
The Basics¶
When you open a note, Trail traverses the graph for each group:
- Start at the current note
- Follow edges of the specified relation types
- Stop when reaching depth limit or no more edges
- Return the tree of discovered notes
Traversal Direction¶
Trail follows edges in the direction they point:
Outgoing Edges¶
From the current note to others:
This is how up relations work—you see notes you linked to.
Incoming Edges (via Implied)¶
If you only have up relations but want to see children, implied relations help:
The child linked up to you. Trail's implied relation creates a down edge pointing to the child.
Depth¶
Depth controls how far traversal goes:
Depth 0 (Unlimited)¶
Follow the chain as far as it goes:
Good for hierarchies where you want full context.
Depth 1¶
Only direct connections:
Good for immediate context without deep ancestry.
Depth N¶
Up to N levels:
Balance between context and focus.
Cycle Handling¶
Your graph might have cycles:
Trail handles this by tracking visited notes. Each note appears only once in the tree, preventing infinite loops.
Tree Building¶
Traversal builds a tree structure:
Current Note
├── [up] Parent
│ └── [up] Grandparent
└── [up] Other Parent
└── [up] Other Grandparent
Multiple Paths¶
If the same note is reachable via different paths, it appears only once (first path found wins).
Tree vs Graph¶
The underlying data is a graph (can have cycles, multiple paths). The display is a tree (hierarchical, no cycles). Traversal converts graph to tree.
Visual Direction and Tree Orientation¶
Relations have a visual direction that affects how the tree is rendered:
Ascending (e.g., up)¶
Tree is inverted—deepest nodes become roots:
Graph edges: Display tree:
Current → Parent Grandparent
Parent → Grandparent └── Parent
└── (current note)
You see ancestors above you, with the highest at the top.
Descending (e.g., down)¶
Tree shows direct connections at root:
Children appear at the top, their children nested below.
Sequential (e.g., next, prev)¶
Tree is flattened to a list:
Graph edges: Display tree:
Current → Next1 Prev2
Next1 → Next2 Prev1
Current → Prev1 Next1
Prev1 → Prev2 Next2
All items at the same level, sorted appropriately.
Group Members¶
Groups can have multiple members, each with its own relation and depth:
Group: "Context"
| Relation | Depth |
|---|---|
up |
0 |
related |
1 |
Traversal runs for each member:
- Follow
uprelations (unlimited depth) - Follow
relatedrelations (depth 1) - Combine results into one tree
Extend¶
The extend feature chains traversals:
Member configuration:
| Relation | Depth | Extend |
|---|---|---|
next |
1 | Ancestors |
This means:
- Find notes via
next(depth 1) - For each found note, run "Ancestors" group's traversal
- Attach ancestor results as children
Use case: See siblings and their ancestry for context.
Performance¶
Traversal is optimized for speed:
Lazy Evaluation¶
Only computes what's needed for visible groups.
Caching¶
Results are cached until the graph changes.
Early Termination¶
Stops as soon as depth limit is reached.
Efficient Graph Storage¶
Uses adjacency lists for O(1) edge lookup.
Debugging Traversal¶
Nothing Showing Up¶
- Check relation exists: Is the relation type defined?
- Check alias: Does the relation have an alias matching your frontmatter?
- Check direction: Are you looking for incoming edges without implied relations?
- Check filters: Are group filters hiding the results?
Unexpected Results¶
- Check implied relations: Implied edges might create unexpected paths
- Check depth: Limited depth might cut off expected results
- Check cycles: A cycle might cause notes to appear in unexpected places (first path wins)
Too Many Results¶
- Reduce depth: Use depth 1-2 instead of 0
- Add filters: Filter by properties
- Split groups: Create focused groups for specific relation types
Example: Full Traversal¶
Setup:
- Note: "Task A"
- Relations: Task A →
up→ Project, Project →up→ Epic - Group: "Ancestors" with
updepth 0
Traversal:
- Start: "Task A"
- Follow
up: Find "Project" - Continue from "Project", follow
up: Find "Epic" - Continue from "Epic", follow
up: No more edges - Build tree: Epic → Project → Task A (inverted for ascending)
Display:
The current note (Task A) isn't shown—it's implied as the starting point.