Basic Examples (2)

Generate a flowchart from a Mermaid specification:

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

Create a Graphics expression from a class diagram:

["
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 (9)

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:

[gr]

Here is a left-to-right version:

[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:

[spec]

Create a Sequence Diagram:

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

State diagram:

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

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

Entity Relationship Diagram:

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

User Journey -- PNG image is obtained and cropped:

["
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:

["
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:

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

Requirement Diagram:

["
    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 (3)

DropMarkdownFences (2)

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

["
```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:

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

MermaidDirectives (1)

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

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

Applications (2)

Create a Markdown-related conversions flowchart:

["
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:

["
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 (3)

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"]

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

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

A diagram that clarifies the execution of 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/>”:

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

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

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

Neat Examples (2)

Larger flowchart with some styling:

["
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:

["
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!
"]