feat: add Obsidian-style graph visualization
Implement force-directed graph view for visualizing note connections:
- Add graph data model parsing [[wiki-style links]]
- Implement Fruchterman-Reingold layout algorithm
- Create character-based canvas renderer with highlights
- Add interactive filtering by tag/folder
- Support navigation (h/j/k/l), zoom (+/-), and node selection
- New commands: :IdeaGraph, :IdeaGraphFilter
New files:
- lua/ideaDrop/ui/graph/{init,types,data,layout,renderer}.lua
Updated documentation in README.md, CHANGELOG.md, and llms.txt
This commit is contained in:
@@ -115,12 +115,15 @@ M.ICONS = {
|
||||
SEARCH = "🔍",
|
||||
TAG = "🏷️",
|
||||
TREE = "🌳",
|
||||
GRAPH = "🕸️",
|
||||
SUCCESS = "✅",
|
||||
ERROR = "❌",
|
||||
WARNING = "⚠️",
|
||||
INFO = "ℹ️",
|
||||
SAVE = "💾",
|
||||
REFRESH = "🔄",
|
||||
NODE = "●",
|
||||
LINK = "─",
|
||||
}
|
||||
|
||||
-- Key mappings (default)
|
||||
@@ -129,6 +132,78 @@ M.DEFAULT_KEYMAPS = {
|
||||
REFRESH_FILE = "<C-r>",
|
||||
CLOSE_WINDOW = "q",
|
||||
SELECT_ITEM = "<CR>",
|
||||
-- Graph keymaps
|
||||
GRAPH_CLOSE = "q",
|
||||
GRAPH_SELECT = "<CR>",
|
||||
GRAPH_FILTER_TAG = "t",
|
||||
GRAPH_FILTER_FOLDER = "f",
|
||||
GRAPH_RESET_FILTER = "r",
|
||||
GRAPH_TOGGLE_LABELS = "l",
|
||||
GRAPH_CENTER = "c",
|
||||
GRAPH_ZOOM_IN = "+",
|
||||
GRAPH_ZOOM_OUT = "-",
|
||||
}
|
||||
|
||||
-- Graph visualization settings
|
||||
M.GRAPH_SETTINGS = {
|
||||
-- Layout algorithm parameters
|
||||
LAYOUT = {
|
||||
-- Fruchterman-Reingold parameters
|
||||
REPULSION_STRENGTH = 5000, -- How strongly nodes repel each other
|
||||
ATTRACTION_STRENGTH = 0.01, -- Spring constant for connected nodes
|
||||
IDEAL_EDGE_LENGTH = 50, -- Ideal distance between connected nodes
|
||||
GRAVITY = 0.1, -- Pull toward center
|
||||
DAMPING = 0.85, -- Velocity damping per iteration
|
||||
MIN_VELOCITY = 0.01, -- Stop threshold
|
||||
MAX_ITERATIONS = 300, -- Maximum layout iterations
|
||||
COOLING_RATE = 0.95, -- Temperature cooling per iteration
|
||||
INITIAL_TEMPERATURE = 100, -- Initial movement freedom
|
||||
},
|
||||
|
||||
-- Visual settings
|
||||
VISUAL = {
|
||||
NODE_CHAR = "●", -- Character for nodes
|
||||
NODE_CHAR_SMALL = "•", -- Character for small nodes
|
||||
EDGE_CHAR_H = "─", -- Horizontal edge
|
||||
EDGE_CHAR_V = "│", -- Vertical edge
|
||||
EDGE_CHAR_DR = "┌", -- Down-right corner
|
||||
EDGE_CHAR_DL = "┐", -- Down-left corner
|
||||
EDGE_CHAR_UR = "└", -- Up-right corner
|
||||
EDGE_CHAR_UL = "┘", -- Up-left corner
|
||||
EDGE_CHAR_CROSS = "┼", -- Crossing edges
|
||||
EDGE_CHAR_SIMPLE = "·", -- Simple edge dot
|
||||
MIN_NODE_SIZE = 1, -- Minimum node visual size
|
||||
MAX_NODE_SIZE = 3, -- Maximum node visual size (based on degree)
|
||||
LABEL_MAX_LENGTH = 20, -- Maximum label length
|
||||
PADDING = 2, -- Canvas padding
|
||||
},
|
||||
|
||||
-- Window settings
|
||||
WINDOW = {
|
||||
WIDTH_RATIO = 0.8, -- Window width as ratio of editor
|
||||
HEIGHT_RATIO = 0.8, -- Window height as ratio of editor
|
||||
BORDER = "rounded",
|
||||
TITLE = " 🕸️ Graph View ",
|
||||
},
|
||||
|
||||
-- Colors (highlight group names)
|
||||
COLORS = {
|
||||
NODE_DEFAULT = "IdeaDropGraphNode",
|
||||
NODE_SELECTED = "IdeaDropGraphNodeSelected",
|
||||
NODE_ORPHAN = "IdeaDropGraphNodeOrphan",
|
||||
NODE_HIGH_DEGREE = "IdeaDropGraphNodeHighDegree",
|
||||
EDGE = "IdeaDropGraphEdge",
|
||||
LABEL = "IdeaDropGraphLabel",
|
||||
BACKGROUND = "IdeaDropGraphBackground",
|
||||
FILTER_ACTIVE = "IdeaDropGraphFilterActive",
|
||||
},
|
||||
|
||||
-- Node size thresholds (degree-based)
|
||||
NODE_DEGREE_THRESHOLDS = {
|
||||
SMALL = 2, -- 0-2 connections = small
|
||||
MEDIUM = 5, -- 3-5 connections = medium
|
||||
-- > 5 = large
|
||||
},
|
||||
}
|
||||
|
||||
-- Notification messages
|
||||
@@ -146,6 +221,12 @@ M.MESSAGES = {
|
||||
NO_ACTIVE_FILE = "❌ No active idea file. Open an idea first.",
|
||||
PROVIDE_TAG = "❌ Please provide a tag name",
|
||||
PROVIDE_QUERY = "❌ Please provide a search query",
|
||||
GRAPH_BUILDING = "🕸️ Building graph...",
|
||||
GRAPH_LAYOUT = "🕸️ Computing layout for %d nodes...",
|
||||
GRAPH_COMPLETE = "🕸️ Graph ready: %d nodes, %d edges",
|
||||
GRAPH_REFRESHED = "🕸️ Graph refreshed",
|
||||
GRAPH_NO_NODES = "🕸️ No notes found to visualize",
|
||||
GRAPH_NO_SELECTION = "🕸️ No node selected",
|
||||
}
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user