D3-Graphviz Remark presentations
D3-graphviz is a Javascript library for visualising dot graphs. I have a new theme for my Windows app Remarkpy that allows for displaying these kinds of graphs in a Remark-based presentation.
As an example, I can add to the presentation markdown file a dot diagrams with the following syntax:
.d3graphviz[
digraph {a -> b}
]
Remarkpy theme
A Remarkpy theme has a well-defined structure, a directory with three files:
- base.html, which normally doesn't have to be modified.
- slideshow.html, where most of the customisations are included.
- theme.md, a default presentation file.
Inside the slideshow.html file I have the following script tags:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
<script src="https://unpkg.com/@hpcc-js/wasm@0.3.11/dist/index.min.js"></script>
<script src="https://unpkg.com/d3-graphviz@3.0.5/build/d3-graphviz.js"></script>
The @hpcc-js/wasm script provides a compiled WASM version of Graphviz, while the D3 script will load the D3 JavaScript library.
Integrating another Javascript library to a Remark presentation is notoriously tricky and, in this case, it requires some Javascript/jQuery code.
The function below allows more than one dot graph inside a single slide.
...
function D3graphviz(s) {
const elements = document.querySelectorAll(".remark-slide")[s.getSlideIndex()]
?.querySelectorAll('.d3graphviz p:not([data-processed="true"])');
if (elements) {
for (let i = 0; i < elements.length; i++) {
elements[i].setAttribute("id","graphviz"+s.getSlideIndex()+i)
let id = d3.select("#graphviz"+s.getSlideIndex()+i).graphviz();
id.zoom(false)
id.renderDot(elements[i].textContent);
$('p#graphviz'+s.getSlideIndex()+i).contents().filter(function(){
return this.nodeType === 3;
}).remove();
}
}
}
// Render D3graphviz diagrams
D3graphviz(slideshow.getSlides()[slideshow.getCurrentSlideIndex()]);
// Render diagrams in the next slide
slideshow.on("afterShowSlide", D3graphviz);
...
This theme requires an active internet connection.