Graph Plugin (@lapis-notes/graph)
Source: packages/plugins/plugin-graph/src/
Manifest: id lapis-graph, version 0.0.1, min app version 1.7.7.
The graph package owns registry-installable global and local graph views driven by the metadata cache and a D3 force simulation. The package remains in the monorepo for building official release artifacts, but the workspace no longer bundles or registers it by default.
Runtime Surface
- View types:
graph,graph-local. - Commands:
open-graph-view,open-local-graph,focus-active-file-in-graph. - Official registry identity:
lapis-graph. - Install location:
/.obsidian/plugins/lapis-graph; listed under Core plugins when installed provenance is official. - Package exports: plugin runtime entry at
@lapis-notes/graph, read-only embed helpers at@lapis-notes/graph/embed, and standalone stylesheet artifact at@lapis-notes/graph/styles.css.
Key Behaviors
- Builds the note graph from resolved links, unresolved links, markdown embeds, and cached tags.
- Rebuilds after the metadata cache
loadedevent, which now fires after app-database restore, portable backup hydration, or first-open rebuild, so restored graph leaves populate during desktop cold boot without a manual refresh. - Exposes filters for tags, attachments, unresolved nodes, orphan visibility, and search-query label/path/tag matches.
- Provides a local graph centered on the active note with configurable BFS depth, including deferred initial centering when a restored or hidden graph surface becomes visible after startup. The local graph no longer rebuilds on every metadata event: it reacts to the active file, files already present in the current local graph, and direct reference neighbors of the active file, while the global graph remains vault-wide.
- Auto-fit and auto-center run after the force simulation settles and when a deferred surface first receives non-zero dimensions; fit-then-center is used when focusing a node before the viewport has been fitted. Window or split-pane resize refits the graph when the user has not manually adjusted the view, otherwise it preserves the world point at the previous viewport center.
- Uses
d3-forcefor simulation, link distance, repel force, collision spacing, and centering. - Supports pan, wheel zoom, keyboard navigation, hover neighbor highlighting, click-to-open, and node context menus.
- Node clicks resolve a navigation leaf before opening files: local graph clicks use the workspace default document leaf (
getLeaf()/activeRootLeaf), while global graph clicks prefer an existing non-graph root leaf when one is available and only replace the graph tab when it is the sole root navigation target. - Records graph leaves in leaf history so view-header Back can restore a graph view after in-tab file navigation; restored graph surfaces rebuild when the leaf becomes active again.
- Persists graph display settings through the plugin settings file.
- Exports a read-only
GraphEmbedsurface plusGraphRenderer, graph settings helpers, and graph data types so external hosts can render precomputed graph data without a workspace leaf or plugin lifecycle.
CSS Ownership
The package owns graph-... namespaced overlay styling and follows the shared Plugin CSS Contract for first-party plugin chrome. The .graph-view surface owns plugin-local graph role variables for links, node fills, node strokes, and labels, and those variables default to the shared graph/theme tokens instead of hardcoded canvas colors.
Testing
Focused Vitest coverage lives with the package for graph assembly, orphan filtering, local-graph depth derivation from metadata fixtures, and navigation-leaf resolution. Workspace e2e coverage in packages/workspace/e2e/graph-navigation.spec.ts exercises demo-vault graph clicks, local-graph routing to the main leaf, and view-header history restore for global graph tabs.