Cytoscape.js is a really nice and efficient library to handle, display and manipulate graphs in JavaScript.
Update 2020/11/16: Added the pies to please scorfi. For that I also added a parameter to have a style file.
Demo (playable)
Data file
The data file reside in the article directory (name of the article without md). Here called graph.json.
[
{ "data": { "id": "a", "label": "A", "foo": 3, "bar": 5, "baz": 2 } },
{ "data": { "id": "b", "label": "B", "foo": 3, "bar": 5, "baz": 20 } },
{ "data": { "id": "c", "label": "C", "foo": 3, "bar": 50, "baz": 2 } },
{
"data": {
"id": "ab",
"source": "a",
"target": "b"
}
},
{
"data": {
"id": "bc",
"source": "b",
"target": "c"
}
},
{
"data": {
"id": "ca",
"source": "c",
"target": "a"
}
},
{
"data": {
"id": "ac",
"source": "a",
"target": "c"
}
}
]
Shortcode in page
That you insert in the page using the shortcode:
{{<cytoscape id="bacd" file="graph.json" style="style.json" height="200">}}
Shortcode definition (in your theme)
<button onClick="document.getElementById('cyto-{{ .Get "id" }}').cy.reset();">Reset</button>
<button onClick="document.getElementById('cyto-{{ .Get "id" }}').cy.layout({name: 'cose'}).run();">Layout the nodes</button>
<div class="cytoshort" id="cyto-{{ .Get "id" }}">
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
var element = document.getElementById("cyto-{{ .Get "id" }}");
element.style.height = 'calc({{ .Get "height" }}px)'
element.cy = cytoscape({
container: element,
elements: {{ resources.Get (printf "content/%s%s/%s" (.Page.Dir) (.Page.File.BaseFileName) (.Get "file")) }},
style: {{ resources.Get (printf "content/%s%s/%s" (.Page.Dir) (.Page.File.BaseFileName) (.Get "style")) }},
});
});
</script>
And this is what you need to add in the footer
Of course your page will need to have cytoscapeOn = true in its header. That’s a trick I use to limit the amount of javascript loaded on each page (I use Mermaid on other pages and it doesn’t have to be loaded everytime).
{{ if eq .Params.cytoscapeOn true }}
<script src="https://cdn.jsdelivr.net/npm/cytoscape@3.17.0/dist/cytoscape.min.js">
</script>
{{ end }}
There is a minimal css needed as well
You need to give a size to the div, this is usually done with some css.
.cytoshort {
width: 800px;
height: 600px;
}