How to use DiagrammeR+Mermaid?

Short answer: Don’t!

Mermaid.js
Diagrams
Author

José R. Ferrer-Paris

Published

July 1, 2024

What I want to do

I want to use the R package DiagrammeR to customise a Mermaid.js diagram.

Challenges

I learned to use Mermaid.js to embed reproducible diagrams in quarto documents. Mermaid.js in under active development, syntax and features change from version to version.

Usually Mermaid code can be embeded in a quarto document like this:

```{mermaid}
%%| label: fig-mermaid
%%| fig-cap: A mermaid graph
graph LR
  A[qmd] --> B(Knitr)
  A[qmd] --> C(Jupyter)
  B(Knitr) --> D[md]
  C(Jupyter) --> D[md]
  D[md] --> E(pandoc)
  E(pandoc) --> F(HTML)
  E(pandoc) --> G(PDF)
  E(pandoc) --> H(Word)
  E(pandoc) --> I{and more}
```
graph LR
  A[qmd] --> B(Knitr)
  A[qmd] --> C(Jupyter)
  B(Knitr) --> D[md]
  C(Jupyter) --> D[md]
  D[md] --> E(pandoc)
  E(pandoc) --> F(HTML)
  E(pandoc) --> G(PDF)
  E(pandoc) --> H(Word)
  E(pandoc) --> I{and more}
Figure 1: A mermaid graph

This is the same diagramm code as the figure shown here.

However, when loading the library DiagrammeR in a document, it will call a fixed version of mermaid. This means that it is stuck with a slightly outdated syntax, and that usually means sacrificing some features. Mixing mermaid code blocks and diagrams created within R code blocks in the same document will have unexpected results.

I am slightly inclined against using DiagrammeR for mermaid plots, but I am still testing options.

Sources

  • https://rdrr.io/cran/DiagrammeR/src/R/mermaid.R
  • https://www.reddit.com/r/github/comments/100mbuh/mermaid_diagram_not_working/
  • https://stackoverflow.com/questions/58689080/mermaid-diagrams-not-rendering-correctly-in-rmarkdown-xaringan-presentations

Steps in R

Load the libraries:

library(DiagrammeR)
library(widgetframe)
Loading required package: htmlwidgets
example1 <- DiagrammeR::mermaid("
graph LR;
A((Orange)) --> B((Grey));

classDef orange fill:#f96;
classDef grey fill:#d3d3d3;
class A orange;
class B grey;
")
example2 <- DiagrammeR("
graph LR
  A[qmd] --> B(Knitr)
  A[qmd] --> C(Jupyter)
  B(Knitr) --> D[md]
  C(Jupyter) --> D[md]
  D[md] --> E(pandoc)
  E(pandoc) --> F(HTML)
  E(pandoc) --> G(PDF)
  E(pandoc) --> H(Word)
  E(pandoc) --> I{and more}"
     )
example3 <- mermaid("
sequenceDiagram
  participant ParticipantA
  participant ParticipantB
  participant ParticipantC
  ParticipantA->>ParticipantB: I want something
  ParticipantB->>ParticipantC: he want something
  ParticipantC->>ParticipantB: here is something
  ParticipantB->>ParticipantA: he got something for you
  ", height = '100%', width = '100%')

Direct output (no <iframe>):

example1
# same as: widgetframe::frameableWidget(example1)

With an <iframe> created with widgetframe:

widgetframe::frameWidget(example1, height=200)
widgetframe::frameWidget(example2, height=300)
widgetframe::frameWidget(example3, height=500)