Interactive Mermaid diagrams generation via Markdown evaluation

Introduction

In this document (and related presentation) we discuss the interactive making of Mermaid-JS diagrams via evaluation of code cells in Markdown documents.

The “interactive” changes are possible because of the following package updates:

Further, the “interactivity” relies on the automatic re-rendering of the used Integrate Development Environments (IDEs), like, IntelliJ IDEACommaide, or Visual Studio Code.

Remark: The preparation of this document and in the presentation, we use Command Line Interface (CLI) script file-code-chunks-eval provided by “Text::CodeProcessing”.

Remark: “Text::CodeProcessing” also provides the script cronify that facilitates periodic execution of a shell command (with parameters.) It heavily borrows ideas and code from the chapter “Silent Cron, a Cron Wrapper” of the book, “Raku Fundamentals” by Moritz Lenz, [ML1].

Remark: After some experimentation the script cronify was not found to be that useful for the “interactive” effect.


Presentation plan

Here is a flowchart of the presentation:


UML diagram

Here we load the package “UML::Translators”, [AAp2], and derive the Mermaid-JS spec for “ML::Clustering”:

use UML::Translators;
to-uml-spec('ML::Clustering', format => 'mermaid')

# classDiagram
# class ML_Clustering_KMeans {
#   +BUILDALL()
#   +args-check()
#   +bray-curtis-distance()
#   +canberra-distance()
#   +chessboard-distance()
#   +cosine-distance()
#   +distance()
#   +euclidean-distance()
#   +find-clusters()
#   +hamming-distance()
#   +manhattan-distance()
#   +norm()
#   +squared-euclidean-distance()
# }
# ML_Clustering_KMeans --|> ML_Clustering_DistanceFunctions
# 
# 
# class ML_Clustering_DistanceFunctions {
#   <<role>>
#   +args-check()
#   +bray-curtis-distance()
#   +canberra-distance()
#   +chessboard-distance()
#   +cosine-distance()
#   +distance()
#   +euclidean-distance()
#   +manhattan-distance()
#   +squared-euclidean-distance()
# }
# 
# 
# class k_means {
#   <<routine>>
# }
# k_means --|> Routine
# k_means --|> Block
# k_means --|> Code
# k_means --|> Callable
# 
# 
# class find_clusters {
#   <<routine>>
# }
# find_clusters --|> Routine
# find_clusters --|> Block
# find_clusters --|> Code
# find_clusters --|> Callable

Here we create directly a Mermaid cell into the Markdown file:

use UML::Translators;
to-uml-spec('ML::Clustering', format => 'mermaid')

Remark: We use above the Markdown cell arguments perl6, outputLang=mermaid, outputPrompt=NONE.


Pie chart

Here we generate a dataset with random numerical columns

use Data::Generators;
use Data::Reshapers;
my @tbl = random-tabular-dataset(12, 3, 
        column-names-generator => { &random-pet-name($_, method => &pick) },
        generators => [
            { random-variate(NormalDistribution.new( µ => 10, σ => 20), $_ ) },
            { random-variate(NormalDistribution.new( µ => 2, σ => 2), $_ ) },
            { random-variate(NormalDistribution.new( µ => 32, σ => 10), $_ ) }]);
say to-pretty-table(@tbl);

# +-----------+-----------+------------+
# |  Schmidt  | Loch Ness |  Atticus   |
# +-----------+-----------+------------+
# | -1.640302 | 28.378750 | 15.904661  |
# |  2.385714 | 38.302540 | 24.213946  |
# |  0.493925 | 38.725973 | 40.612606  |
# |  4.505899 | 30.662067 | 18.584966  |
# |  0.434399 | 16.541336 | 16.912362  |
# |  3.721586 | 44.420603 | 33.003731  |
# |  2.167267 | 34.555019 |  9.839326  |
# |  0.816624 | 25.008163 | -36.824675 |
# |  0.473044 | 32.095658 | 38.149468  |
# |  3.436236 | 23.021088 | 24.750144  |
# |  5.754028 | 38.892485 | 20.964051  |
# | -0.590391 | 23.630289 | -8.537537  |
# +-----------+-----------+------------+

Here we sum the columns:

@tbl.&transpose.map({ $_.key => [+] $_.value })

# (Loch Ness => 374.233971547851 Schmidt => 21.95802958385876 Atticus => 197.57304922350048)

Plot the sums with a Mermaid pie chart:

say 'pie showData';
say ' title My Great Pie Chart!';
@tbl.&transpose.map({ $_.key => [+] $_.value }).map({ say " {$_.key.raku} : {$_.value}" })

Remark: The pie chart in this blog post is “uploaded” — meaning most likely does not correspond to the table above.


Make trie plot

Here we make a prefix tree (trie) with frequencies:

use ML::TriesWithFrequencies;
my $tr = trie-create-by-split( <bar bark bars balm cert cell> );
trie-say($tr);

# TRIEROOT => 6
# ├─b => 4
# │ └─a => 4
# │   ├─l => 1
# │   │ └─m => 1
# │   └─r => 3
# │     ├─k => 1
# │     └─s => 1
# └─c => 2
#   └─e => 2
#     ├─l => 1
#     │ └─l => 1
#     └─r => 1
#       └─t => 1

Here we just get nodes:

say 'mindmap';
say $tr.form.subst( / '├' | '─' | '└' | '│' | '└' /, ' '):g

mindmap
TRIEROOT => 6
  b => 4
    a => 4
      l => 1
        m => 1
      r => 3
        k => 1
        s => 1
  c => 2
    e => 2
      l => 1
        l => 1
      r => 1
        t => 1

Here we plot it with Mermaid-JS as a mindmap (requires version 9.2.2+):

say 'mindmap';
say $tr.form.subst( / '├' | '─' | '└' | '│' | '└' /, ' '):g;

Here we transform the trie into list of edges:

my @edges = $tr.node-probabilities.root-to-leaf-paths>>.map({ "{$_.key}:{$_.value.Str}" }).map({ $_.rotor(2 => -1).map({ "{$_[0]} --> {$_[1]}" }) }).&flatten;
.say for @edges.unique; 

# TRIEROOT:1 --> b:0.6666666666666666
# b:0.6666666666666666 --> a:1
# a:1 --> r:0.75
# r:0.75 --> s:0.3333333333333333
# r:0.75 --> k:0.3333333333333333
# a:1 --> l:0.25
# l:0.25 --> m:1
# TRIEROOT:1 --> c:0.3333333333333333
# c:0.3333333333333333 --> e:1
# e:1 --> l:0.5
# l:0.5 --> l:1
# e:1 --> r:0.5
# r:0.5 --> t:1

Here we plot it with Mermaid-JS as a graph:

say 'graph TD';
.say for @edges.unique; 

References

Articles

[AA1] Anton Antonov “Text::CodeProcessing”, (2021), RakuForPrediction at WordPress.

[AA2] Anton Antonov “Conversion and evaluation of Raku files”, (2022), RakuForPrediction at WordPress.

[AA3] Anton Antonov, “Generating UML diagrams for Raku namespaces, (2022), RakuForPrediction at WordPress.

Books

[ML1] Moritz Lenz, “Raku Fundamentals: A Primer with Examples, Projects, and Case Studies”, 2nd ed. (2020), Apress.

Packages

[AAp1] Anton Antonov, Text::CodeProcessing Raku package, (2021-2022), Zef ecosystem.

[AAp2] Anton Antonov, UML::Translators Raku package, (2021-2022), Zef ecosystem.

Videos

[AAv1] Anton Antonov “Conversion and evaluation of Raku files”, (2022), Anton Antonov’s channel at YouTube.

Advertisement

2 thoughts on “Interactive Mermaid diagrams generation via Markdown evaluation

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s