Created
February 22, 2024 21:30
-
-
Save xRyul/c127482641144bb0263060cb729ca1be to your computer and use it in GitHub Desktop.
Automated Mermaid Graph from Backlinks N levels deep - ObsidianMD
This file contains 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
```dataviewjs | |
// If too many connections are found, mermaid wont render them. | |
// Thus, we have to limit either how deep we go via "var specifiedDepth = X;" | |
// Or, we can reduce amount of links shown "maxLinks = X" | |
var inlinks = [...new Set(dv.current().file.inlinks.map(link => link.path.split('/').pop().replace('.md', '')))]; | |
var outlinks = [...new Set(dv.current().file.outlinks.map(link => link.path.split('/').pop().replace('.md', '')))]; | |
var graph = []; | |
var classList = []; | |
var nodeNames = {}; | |
var edges = new Set(); | |
// Add the current note to the graph | |
var currentNote = dv.current().file.name; | |
graph.push('AA["' + currentNote + '"]'); | |
classList.push('AA'); | |
nodeNames[currentNote] = 'AA'; | |
// Create a set to store visited notes | |
var visited = new Set(); | |
// If you ever get an error that limit was exceeded, simply modify "maxLinks = 20" | |
// you can increase or decrease this number | |
function getOutgoingLinks(link, parentNode, depth = 0, maxDepth = 10, maxLinks = 20) { | |
if (depth > maxDepth) return; | |
visited.add(link); // Mark the note as visited | |
let linkedPage = dv.page(link); | |
if (linkedPage) { | |
let node = nodeNames[link] || String.fromCharCode(65 + Math.floor(visited.size / 26)) + String.fromCharCode(65 + (visited.size % 26)); // Create a new node for each visited note | |
nodeNames[link] = node; | |
if (!graph.includes(node + '["' + link + '"]')) { | |
graph.push(node + '["' + link + '"]'); | |
} | |
let edge = parentNode + '-->' + node; | |
let reverseEdge = node + '-->' + parentNode; | |
if (inlinks.includes(link) && outlinks.includes(link)) { | |
edge = parentNode + '<-->' + node; | |
reverseEdge = node + '<-->' + parentNode; | |
} | |
if (!edges.has(edge) && !edges.has(reverseEdge)) { | |
graph.push(edge); | |
edges.add(edge); | |
} | |
classList.push(node); | |
let furtherOutlinks = [...new Set(linkedPage.file.outlinks.map(link => link.path.split('/').pop().replace('.md', '')))]; | |
furtherOutlinks.slice(0, maxLinks).forEach(link => getOutgoingLinks(link, node, depth + 1, maxDepth)); | |
let furtherInlinks = [...new Set(linkedPage.file.inlinks.map(link => link.path.split('/').pop().replace('.md', '')))]; | |
furtherInlinks.slice(0, maxLinks).forEach(link => getOutgoingLinks(link, node, depth + 1, maxDepth)); | |
} | |
} | |
// Call the recursive function on each initial outgoing link with a specified depth | |
var specifiedDepth = 3; // Change this to your desired depth | |
outlinks.forEach(link => getOutgoingLinks(link, 'AA', 0, specifiedDepth)); | |
// Add inlinks to the graph | |
for (let i = 0; i < inlinks.length; i++) { | |
let link = inlinks[i]; | |
if (!nodeNames[link]) { // Only add the inlink if it hasn't been added as an outlink | |
let node = String.fromCharCode(65 + Math.floor((visited.size + i) / 26)) + String.fromCharCode(65 + ((visited.size + i) % 26)); // Create a new node for each visited note | |
nodeNames[link] = node; | |
graph.push(node + '["' + link + '"]'); | |
let edge = node + '-->' + 'AA'; | |
if (!edges.has(edge)) { | |
graph.push(edge); | |
edges.add(edge); | |
} | |
classList.push(node); | |
} | |
} | |
// Generate the MERMAID graph | |
dv.paragraph('```mermaid\ngraph LR\n' + graph.join('\n') + '\nclassDef currentNote fill:#2e2e2e,stroke:#292a36,stroke-width:2px;\nclass AA currentNote;\nclass ' + classList.join(',') + ' internal-link;\n```'); | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment