MermaidInk

Get an image corresponding to a Mermaid-js specification via the web Mermaid-ink interface of Mermaid-js

DefinitionResourceCreateNotebook

Clear[MermaidInk]

MermaidInk::args="The first argument is expected to be a string or Graph object; the second argument is expected to be one of \"PNG\", \"PDF\", \"SVG\", or Automatic.";

MermaidInk::nmd="The value of the option MermaidDirectives is expected to be a string.";

Options[MermaidInk]={"URL"->"https://mermaid.ink/img","MermaidDirectives"->"TD","DropMarkdownFences"->True};

MermaidInk[mSpec_String,opts:OptionsPattern[]]:=
Block[{res,url,mSpec2=mSpec},
If[TrueQ[OptionValue[MermaidInk,"DropMarkdownFences"]],
mSpec2=StringReplace[StringTrim[mSpec],{StartOfString~~"```mermaid","```"~~EndOfString}->""]
];
url=OptionValue[MermaidInk,"URL"];
res=ExportString[StringTrim[mSpec2], "Base64"];
Import[URLBuild[{url,res}]]
];

MermaidInk[gr_Graph,opts:OptionsPattern[]]:=
Block[{spec="graph",lsEdges,lsEdges2,directives},

directives=OptionValue[MermaidInk,"MermaidDirectives"];
If[!StringQ[directives],
ResourceFunction["ResourceFunctionMessage"][MermaidInk::nmd];
directives="";
];

lsEdges=EdgeList[gr];
lsEdges2=lsEdges/.{
DirectedEdge[x_,y_]:>ToString[x]<>" --> "<>ToString[y],
DirectedEdge[x_,y_,t_]:>ToString[x]<>" --> |"<>ToString[t]<>"|"<>ToString[y],
UndirectedEdge[x_,y_]:>ToString[x]<>" --- "<>ToString[y],
UndirectedEdge[x_,y_,t_]:>ToString[x]<>" --- |"<>ToString[t]<>"|"<>ToString[y]
};
spec=spec<>" "<>directives<>"\n"<>StringRiffle[Map["  "<>#&,lsEdges2],"\n"];
MermaidInk[spec,opts]
];

MermaidInk[___]:=(ResourceFunction["ResourceFunctionMessage"][MermaidInk::args];$Failed);

Documentation

UsageResourceCreateNotebook

Details & OptionsResourceCreateNotebook

Mermaid lets you create diagrams and visualizations using text and code.

Mermaid has different types of diagrams: Flowchart, Sequence Diagram, Class Diagram, State Diagram, Entity Relationship Diagram, User Journey, Gantt, Pie Chart, Requirement Diagram, and others. It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically.

MermaidInk uses the Mermaid's functionalities via the Web interface "https://mermaid.ink/img".

The first argument can be a string (that is, a mermaid-js specification) or a Graph object.

The option "MermaidDirectives" can be used to control the layout of Mermaid diagrams if the first argument is a Graph object. The accepted orientations are given below:

({{TB, top to bottom}, {TD, top-down}, {BT, bottom to top}, {RL, right to left}, {LR, left to right}})

MermaidInk produces images.

ExamplesResourceCreateNotebook

Basic Examples

Generate a flowchart from a Mermaid specification:

MermaidInk["
graph TD
    WL --> |ZMQ|Python --> |ZMQ|WL
"]

Create a Graphics expression from a class diagram:

MermaidInk["
classDiagram
    Animal <|-- Duck
    Animal <|-- Fish
    Animal <|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
        +String beakColor
        +swim()
        +quack()
    }
    class Fish{
        -int sizeInFeet
        -canEat()
    }
    class Zebra{
        +bool is_wild
        +run()
    }
"]

Scope

The first argument can be a Graph object -- the corresponding Mermaid-js graph is produced. Here is a random graph that has both directed and undirected edges (some edges have tags):

SeedRandom[45];
gr=GraphUnion[RandomGraph[{3,2},DirectedEdges->True],RandomGraph[{4,4},DirectedEdges->False]];
gr=Graph[Map[RandomChoice[{#,Append[#,RandomWord[]]}]&,EdgeList[gr]],VertexLabels->"Name",EdgeLabels->"EdgeTag"];
gr

Here is the corresponding mermaid-js image:

MermaidInk[gr]

Here is a left-to-right version:

MermaidInk[gr,"MermaidDirectives"->"LR"]

Very often Large Language Models (LLMs) produce Mermaid-JS code as a Markdown fenced code block. By default the fences are removed. Here we generate a Mermaid-JS diagram:

spec=LLMSynthesize[{"Give a concise Mermaid-JS diagram of continents' land connections.",LLMPrompt["NothingElse"]["Mermaid-JS"]}]

Here we generate the corresponding diagram:

MermaidInk[spec]

Create a Sequence Diagram:

MermaidInk["sequenceDiagram
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!
    Alice-)John: See you later!"]

State diagram:

MermaidInk["
stateDiagram-v2
    [*] --> Still
    Still --> [*]

    Still --> Moving
    Moving --> Still
    Moving --> Crash
    Crash --> [*]
"]

Entity Relationship Diagram:

MermaidInk["
erDiagram
    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
"]

User Journey -- PNG image is obtained and cropped:

MermaidInk["
journey
    title My working day
    section Go to work
      Make tea: 5: Me
      Go upstairs: 3: Me
      Do work: 1: Me, Cat
    section Go home
      Go downstairs: 5: Me
      Sit down: 5: Me
"]

Gantt chart:

MermaidInk["
gantt
    title A Gantt Diagram
    dateFormat  YYYY-MM-DD
    section Section
    A task           :a1, 2014-01-01, 30d
    Another task     :after a1  , 20d
    section Another
    Task in sec      :2014-01-12  , 12d
    another task      : 24d
"]

Pie chart:

MermaidInk["pie title Pets adopted by volunteers
    \"Dogs\" : 386
    \"Cats\" : 85
    \"Rats\" : 15"]

Requirement Diagram:

MermaidInk["
    requirementDiagram

    requirement test_req {
    id: 1
    text: the test text.
    risk: high
    verifymethod: test
    }

    element test_entity {
    type: simulation
    }

    test_entity - satisfies -> test_req"]

Options

DropMarkdownFences

Very often Large Language Models (LLMs) produce Mermaid-JS code as a Markdown fenced code block. By default the fences are removed:

MermaidInk["
```mermaid
graph LR
    Asia --- Europe
    Asia --- Africa
    North_America --- South_America
    Asia --- North_America
    Europe --- Africa
```"]

Without dropping the Markdown code block fences we get an error:

MermaidInk["
```mermaid
graph LR
    Asia --- Europe
    Asia --- Africa
    North_America --- South_America
    Asia --- North_America
    Europe --- Africa
```","DropMarkdownFences"->False]

MermaidDirectives

The option "MermaidDirectives" is used when the first argument is a Graph object:

SeedRandom[1];
Block[{gr=RandomGraph[{5,6}]},
Association[#->MermaidInk[gr,"MermaidDirectives"->#]&/@{"TB","TD","BT","RL","LR"}]
]

Applications

Create a Markdown-related conversions flowchart:

MermaidInk["
graph TD
    WL[Make a Mathematica notebook] --> E
    E[\"Examine notebook(s)\"] --> M2MD
    M2MD[\"Convert to Markdown with M2MD\"] --> MG
    MG[\"Convert to Mathematica with Markdown::Grammar\"] --> |Compare|E
"]

Create a Sequence Diagram for a blogging app service communication:

MermaidInk["
sequenceDiagram
    participant web as Web Browser
    participant blog as Blog Service
    participant account as Account Service
    participant mail as Mail Service
    participant db as Storage

    Note over web,db: The user must be logged in to submit blog posts
    web->>+account: Logs in using credentials
    account->>db: Query stored accounts
    db->>account: Respond with query result

    alt Credentials not found
        account->>web: Invalid credentials
    else Credentials found
        account->>-web: Successfully logged in

        Note over web,db: When the user is authenticated, they can now submit new posts
        web->>+blog: Submit new post
        blog->>db: Store post data

        par Notifications
            blog--)mail: Send mail to blog subscribers
            blog--)db: Store in-site notifications
        and Response
            blog-->>-web: Successfully posted
        end
    end
"]

Properties and Relations

There is a fairly straightforward correspondence between the edge specifications for Graph and Mermaid graph (or flowchart) specifications:

gr=Graph[{DirectedEdge[A,B,MyTag],UndirectedEdge[A,C]},VertexLabels->"Name",EdgeLabels->"EdgeTag"]

MermaidInk[gr,"MermaidDirectives"->"LR"]

MermaidInk["
graph LR
 A --> |MyTag|B 
 A --- C  
"]

A diagram that clarifies the execution of MermaidInk:

MermaidInk["
graph TD
UI[/User input/]
MS{{Mermaid-ink server}}
WL{{Wolfram Language}}
WLnb>Notebook]
WLIC[[Input cell]]
WLOC[[Output cell]]
MI[MermaidInk]
UI --> WLIC -.- WLnb
WLIC --> MI -.- WL
MI --> |spec|MS
MS --> |image|MI
MI --> WLOC -.- WLnb
WLnb -.- WL
"]

For some textual content MermaidInk specifications should use quotes. Also, a new line character in text can be included using “<br/>”:

MermaidInk["
graph LR
	A[\"Complicated text <br/>(maybe)\"] --> S[Sink <br/> place]
"]

Without the quotes for block "A" the specifications above does not work:

MermaidInk["
graph LR
	A[Complicated text <br/>(maybe)] --> S[Sink <br/> place]
"]

Neat Examples

Larger flowchart with some styling:

MermaidInk["
graph TB
    sq[Square shape] --> ci((Circle shape))

    subgraph A
        od>Odd shape]-- Two line<br/>edge comment --> ro
        di{Diamond with <br/> line break} -.-> ro(Rounded<br>square<br>shape)
        di==>ro2(Rounded square shape)
    end

    %% Notice that no text in shape are added here instead that is appended further down
    e --> od3>Really long text with linebreak<br>in an Odd shape]

    %% Comments after double percent signs
    e((Inner / circle<br>and some odd <br>special characters)) --> f(,.?!+-*ز)

    cyr[Cyrillic]-->cyr2((Circle shape Начало));

     classDef green fill:#9f6,stroke:#333,stroke-width:2px;
     classDef orange fill:#f96,stroke:#333,stroke-width:4px;
     class sq,e green
     class di orange
"]//ImageCrop

Some interesting interaction:

MermaidInk["
sequenceDiagram
    participant Alice
    participant Bob
    Alice->>John: Hello John, how are you?
    loop Healthcheck
        John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts <br/>prevail!
    John-->>Alice: Great!
    John->>Bob: How about you?
    Bob-->>John: Jolly good!
"]

Source & Additional Information

Contributed ByResourceCreateNotebook

Anton Antonov

KeywordsResourceCreateNotebook

Mermaid

Graph

Class diagram

Sequence diagram

Flow chart

User journey

Entity Relationship Diagram

Pie chart

Gantt chart

UML

Categories

Related SymbolsResourceCreateNotebook

ExportString

Graph

Graphics

Import

URLBuild

Related Resource ObjectsResourceCreateNotebook

ProjectDataGanttChart

CircleFlowChart

Source/Reference CitationResourceCreateNotebook

Source, reference or citation information

LinksResourceCreateNotebook

GitHub - mermaid-js/mermaid: Generation of diagram and flowchart from text in a similar manner as markdown

mermaid - Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.

GitHub - mermaid-js/mermaid-cli: Command line tool for the Mermaid library

Online FlowChart & Diagrams Editor - Mermaid Live Editor

TestsResourceCreateNotebook

Should pass

MermaidInk["graph LR
A-->B"]

MermaidInk["graph LR
A-->B"]

Head[MermaidInk["graph LR
A-->B"]]==Image

Should fail

MermaidInk["graph LR
A-->"]

MermaidInk[]

CompatibilityResourceCreateNotebook

Wolfram Language VersionResourceCreateNotebook

13.0+

Operating SystemResourceCreateNotebook

Required FeaturesResourceCreateNotebook

EnvironmentsResourceCreateNotebook

Cloud SupportResourceCreateNotebook

Author NotesResourceCreateNotebook

Additional information about limitations, issues, etc.

Submission NotesResourceCreateNotebook

Removing Markdown code block fences so it would be easier to deal LLM outputs.