Skip to content

Instantly share code, notes, and snippets.

@xRyul
Created February 22, 2024 21:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xRyul/c127482641144bb0263060cb729ca1be to your computer and use it in GitHub Desktop.
Save xRyul/c127482641144bb0263060cb729ca1be to your computer and use it in GitHub Desktop.
Automated Mermaid Graph from Backlinks N levels deep - ObsidianMD
```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