JavaScript Rendered Diagramming

A variety of JavaScript based text to diagram tools exist that can be used to render diagrams from simple text based source scripts. Examples include:

The innovationOUtside/nb_js_diagrammers Python package provides a range of IPython magics for supporting the generation of diagrams using all these packages using simple cell block magics.

The generated assets are rendered into the srcdoc attribute of an embedded IFrame returned via the _repr_html_ method on the diagram generator object.


The Markdown preview enhanced VS Code extension provides a wide range of power tools to support the editing and previewing of native markdown documents. Among other things, the extension will offer rendered previews of diagrams from appropriate scripts using the mermaid and wavedrom JavaScript packages.

See also: Previewing Sphinx and Jupyter Book Rendered Mermaid and Wavedrom Diagrams in VS Code

%load_ext nb_js_diagrammers

Generating Timing Diagrams With wavedrom

%%wavedrom_magic -h 100 -o wavedrom.html

{ signal : [
  { name: "clk",  wave: "p......" },
  { name: "bus",  wave: "x.34.5x",   data: "head body tail" },
  { name: "wire", wave: "0.1..0." },

Generating Diagrams Using mermaid.js

Several diagram types can be generated using the mermaid.js package.

For example, we can generate simple flow charts:

%%mermaid_magic -h 500

flowchart TD
    A[Start] --> B{Is it?};
    B -->|Yes|C[OK];
    C --> D[Rethink];
    D --> B;
    B ---->|No| E[End];

More generally, we can also create simple graph diagrams:

%%mermaid_magic -h 250

graph TD;

We can also generate sequence diagrams:

%%mermaid_magic -h 350

    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!
    Alice-)John: See you later!

And entity relationship diagrams:

%%mermaid_magic -h 330

    CUSTOMER ||--o{ ORDER : places
        string name
        string custNumber
        string sector
    ORDER {
        int orderNumber
        string deliveryAddress

Visualising Audio Files with wavesurfer

%wavesurfer_magic -o wavesurfer.html -f

Flow Charts

As well as flow charts generated using mermaid.js we can also use the flowchart.js package.

In an interactive notebook, we can simply use the %%flowchart_magic block magic to render a flowchart from a flowchart definition.


For an earlier attempt at embedding flowchart.js diagrams in notebooks as an ipywidget, see flowchart_js_jp_proxy_widget.

%%flowchart_magic -h 100

st=>start: Start
e=>end: End
op1=>operation: Generate
op2=>parallel: Evaluate
op2(path1, top)->op1
op2(path2, right)->e

It is also possible to generate a flowchart based on the contents of a code cell (in an interactive notebook, we can do this directly using the %%pyflowchart_magic block magic):

%%pyflowchart_magic -h 800 -x
import time

def demo(msg='demo'):
    for i in range(10):
        print(f'{msg} loopcount is {i}')

The -x / --execute flag executes the code in the current notebook scope. Without the flag, the code is not executed.

Another, less friendly approach, is to have a normal code cell:

import time

def demo(msg='demo'):
    for i in range(10):
        print(f'{msg} loopcount is {i}')

And then capture the code from this code cell and render it.

%%capture code
# This gets the content of the previous cell
# and stores it in the variable: code
%history -l 1
from pyflowchart import Flowchart

from nb_js_diagrammers.flowchartjs import TEMPLATE_FLOWCHARTJS
from nb_js_diagrammers.magics import js_ui, JSDiagram

# Generate a flowchart from the grabbed code
fc = Flowchart.from_code(code.stdout)

# Render the flowchart
#js_ui({"src":fc.flowchart()}, TEMPLATE_FLOWCHARTJS,
#      out_fn='pyflowchart_grab.html', height=800)
diagram = JSDiagram({"src":fc.flowchart()}, TEMPLATE_FLOWCHARTJS, height=800)