ANG-004: Structural note graph with Cytoscape.js + fCoSE webview rendering#6
Open
yugalkaushik wants to merge 3 commits into
Open
ANG-004: Structural note graph with Cytoscape.js + fCoSE webview rendering#6yugalkaushik wants to merge 3 commits into
yugalkaushik wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a Cytoscape.js-based interactive note graph rendered in a Joplin panel webview, with a new build pipeline for bundling webview-only dependencies and server-side graph construction (nodes/edges) with unit tests.
Changes:
- Introduces a separate
web-targeted webpack build for the webview graph renderer and wires it intonpm run dist. - Adds graph domain types plus
EdgeFactory+GraphBuilder(with unit tests) to assemble Cytoscape-compatible nodes/edges and compute node degree. - Extends the panel webview messaging to support requesting graph data and click-to-navigate from graph nodes.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| webview.webpack.config.js | New webpack config to bundle Cytoscape + fCoSE for the panel webview. |
| src/ui/webview.ts | Adds graph-data request handling and node-click navigation; stores/publishes graph data. |
| src/ui/styles/panel.css | Updates panel layout and adds graph container/status styling. |
| src/ui/graph-view.js | New Cytoscape renderer + layout + resize/theme handling + webview messaging. |
| src/ui/App.ts | Adds graph container + status element to panel HTML. |
| src/services/similarity/EdgeFactory.ts | Builds link/tag edges between notes. |
| src/services/similarity/EdgeFactory.test.ts | Unit tests for edge creation rules. |
| src/services/graph/types.ts | New graph data model used by builder and webview. |
| src/services/graph/GraphBuilder.ts | Builds Cytoscape-ready nodes/edges and computes degree. |
| src/services/graph/GraphBuilder.test.ts | Unit tests for graph node/edge building behavior. |
| src/index.ts | Generates graph data before showing the panel. |
| package.json | Adds Cytoscape deps and a webview build step/script. |
| package-lock.json | Locks new Cytoscape/fCoSE dependencies. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+10
to
+19
| const addEdge = (source: string, target: string, type: EdgeType) => { | ||
| const key = | ||
| source < target | ||
| ? `${source}::${target}::${type}` | ||
| : `${target}::${source}::${type}`; | ||
| if (!edgeSet.has(key)) { | ||
| edgeSet.add(key); | ||
| edges.push({ source, target, type }); | ||
| } | ||
| }; |
Comment on lines
+57
to
+66
| it('creates bidirectional link when notes reference each other', () => { | ||
| const notes = [ | ||
| note('a', 'A', ['b']), | ||
| note('b', 'B', ['a']), | ||
| ]; | ||
|
|
||
| const edges = factory.createEdges(notes); | ||
| expect(edges).toHaveLength(1); | ||
| expect(edges).toContainEqual({ source: 'a', target: 'b', type: 'link' }); | ||
| }); |
Comment on lines
+67
to
+69
| export const postGraphData = async (graphData: GraphData): Promise<void> => { | ||
| currentGraphData = graphData; | ||
| }; |
Comment on lines
+229
to
+235
| if (typeof webviewApi !== 'undefined') { | ||
| webviewApi.onMessage(function (message) { | ||
| if (message && message.type === 'fit-to-screen') { | ||
| cy.fit(undefined, 30); | ||
| } | ||
| }); | ||
| } |
Comment on lines
+131
to
+152
| function renderGraph(message) { | ||
| if (!message || !message.nodes || !message.nodes.length) { | ||
| showStatus('No graph data received'); | ||
| return; | ||
| } | ||
|
|
||
| var nodeCount = message.nodes.length; | ||
| var edgeCount = (message.edges || []).length; | ||
|
|
||
| if (edgeCount === 0) { | ||
| showStatus(nodeCount + ' notes loaded, 0 connections found'); | ||
| return; | ||
| } | ||
|
|
||
| hideStatus(); | ||
|
|
||
| cy.elements().remove(); | ||
| cy.add(message.nodes); | ||
| cy.add(message.edges); | ||
|
|
||
| cy.layout(FCOSE_OPTIONS).run(); | ||
| } |
Comment on lines
+39
to
+44
| for (const [, noteIds] of tagToNotes) { | ||
| for (let i = 0; i < noteIds.length; i++) { | ||
| for (let j = i + 1; j < noteIds.length; j++) { | ||
| addEdge(noteIds[i], noteIds[j], 'tag'); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Renders an interactive graph inside a Joplin panel showing explicit note-to-note links as solid arrowed edges and shared tag relationships as dotted edges.
Preview