Mermaid JS Nedir?

Akış çizelgeleri, sıra (sekans) diyagramları, sınıf diyagramları, gantt çizelgeleri ve git grafikleri

Yazılar içerisinde ve/veya sunumlarda akış çizelgeleri için ilk akla gelen seçenek çoğu durumda grafik uygulamaları üzerine oluyor. Ancak, güncelleme gereksinimleri nedeniyle programlar aracılığı ile gerçekleştirilen işlemler çok efektif olamayabiliyor. Peki, alternatif çözümler nedir?

AA

Akış çizelgeleri, sıra (sekans) diyagramları, sınıf diyagramları, gantt çizelgeleri ve git grafikleri gibi gereksinimlerde tasarım programları öncelikli bir seçenek olsa da çeşitli uygulamalar ve/veya programlama dilleri aracılığı ile de işlemler yapılabilmekte. Bu çözümler sayesinde ilgili grafikler dinamik ve/veya statik olarak çıktı haline getirilebilmekte. Ancak, elbette kendi bağımlılıkları ve sınırlandırmaları çerçevesinde bu yeteneklerden faydalanabilmekteyiz. JavaScript dili ile geliştirilen Mermaid bu seçeneklerden biri. Mermaid JS'i diğerlerinden ayıran özelliği ise farklı ortamlara kolay bir şekilde adapte edilebilmesi ve Markdown benzeri (markdownish) yazım kuralları sayesinde kolay bir şekilde akış çizelgeleri, sıra diyagramları, sınıf diyagramları, gantt çizelgeleri ve git grafikleri oluşturabilmemizi mümkün kılması. Elbette mermaid dışında da PlantUML1 ve Kroki2 gibi seçenekler mevcut.

Mermaid JS

Mermaid-js, markdown yazım stiline benzer yazım kuralları aracılığı ile kolay bir şekilde akış çizelgeleri, sıra diyagramları, sınıf diyagramları, gantt çizelgeleri ve git grafikleri oluşturabilmemizi sağlayan, açık kaynak, JavaScript tabanlı bir diyagram ve grafik aracıdır3.

Temel biçimlendirme tanımları aracılığı ile hızlı ve dinamik bir şekilde karmaşık diyagramlar oluşturmak ve değiştirmek mümkün hale gelmektedir. Aşağıda yer alan örnekleri Mermaid Live Editor aracılığı ile hızlı bir şekilde uygulayabilir ve düzenleyebilirsiniz4.

Mermaid JS
Şekil 1

Örnek bir akış çizelgesi oluşturarak ilerleyelim.

graph LR;
    A-->B;
    A-->C;
    B-->D;
    C-->D;

Yukarıdaki örnekte yer alan graph belirttiğimiz ifadelerin bir akış diyagramı (flowcart) biçiminde ele alınması gerektiğini belirtmektedir. TD ise ilgili biçimin nasıl yönlendirileceğini (orientation) gösterir5. A, B, C ve D ilgili noktaları --> ise bu noktalar arasındaki ilişkiyi tanımlar. Özetle, yukarıdaki mermaid tanımı yorumlanır (render) ve bize SVG formatında sunulur6. Yukarıdaki örneğin çıktısını Şekil 1 (a)'da görebilirsiniz.

%%{init: { 'theme': 'dark' } }%%
graph LR;
    A[/Lorem/]-.->|X| B(Ipsum);
    A--> C[Dolor];
    B-->D[fa:fa-car Sit Amet];
    C==>|Y| D;
%%{init: {'theme':'base'}}%%
flowchart TB;
    A(Lorem)-.->|X| B(Ipsum);
    A--xC(Dolor);
    B--oD((fa:fa-car Sit Amet));
    C<==>|Y| B & D;
subgraph section
            B
            C
          end

Yukarıdaki iki marmaid tanımına ait çıktıyı sırası ile Şekil 1 (b) ve Şekil 1 (c)'de görebilirsiniz. graph esasında flowchart'ın daha sade bir kullanımı denebilir. Tanımların daha detaylı işlemek gerektiği durumlarda flowchart tercih edilebilir. Bu yazının yazıldığı tarihte flowchart'in beta modunda olduğunu belirtmeliyim. init direktifi konfigürasyon üzerinde değişiklikler yapabilmemizi sağlar7. Yorumlama sürecine dair güvenlik tanımları, tema tanımları ve log işlemi gibi parametreleri taşır. En temel kullanımı aşağıdaki gibidir.

%%{init: { <argümanlar> }}%%

Daha kapsamlı bir kullanım için aşağıdaki örneği Mermaid Live Editor ile görüntüleyebilir ve güncelleyebilirsiniz.

graph LR
A[Campaign]
B[LP: lp-1]
C[LP: lp-2]
D[Order Form: bp-1]
E[Order Form: bp-2]
F[Order Form: of-1]
G[Order Form: of-2]
H[Up-sell 1]
I[Up-sell 2]
J[Order Completed]

A --> B & C

subgraph s11 [split testing - 1]
B & C
end

subgraph st2 [split testing - 2]
    B-->|%50|D & E
    C-->|%50|E & D
end

subgraph st3 [split testing - 3]
    D-->|%70|F & G
    E-->|%30|G & F
end

F & G --> H
H --> I
I --> J

Unutmadan ekleyeyim, mermaid ile ilgili uçları etkileşimli hale de getirebilmekteyiz. Ancak, bu özellik securityLevel='strict' tanımında kullanılamaz. Bu nedenle güvenlik tanımının securityLevel='loose' olarak düzenlenmesi gerekecektir8.

var callback = function(){
    alert('A callback was triggered');
}
graph LR;
    A-->B;
    B-->C;
    C-->D;
    click A callback "Tooltip for a callback"
    click B "http://www.github.com" "This is a tooltip for a link"
    click A call callback() "Tooltip for a callback"
    click B href "http://www.github.com" "This is a tooltip for a link"

Mermaid ile kullanabileceğimiz biçimler elbette flowchart ve graph ile sınırlı değil.

Mermaid JS - sequenceDiagram
Şekil 2 - sequenceDiagram

sequenceDiagram ile sıra (sekans) diyagramları oluşturabilmekteyiz. sequenceDiagram, iş sistemlerinin nasıl modellenebileceğini belirleyen ve açıklayan, basit düzey bir Unified Modelling Language (UML) çözümü olarak da değerlendirilebilir9.

Kişiler arasındaki diyaloglar ya da servisler arasındaki istek ve yanıtlar sekans akışı için örnek gösterilebilir.

sequenceDiagram
    participant John
    participant Alice
    participant Ela
    Alice->>John: Hello John, how are you?
    Alice->>Ela: Hi
    John-->>Alice: Great!
    Ela ->> John: Hello!

Yukarıdaki sekans akışını notlar ve döngüler ile zenginleştirelim. Aşağıdaki kod parçacığını Mermaid Live Editor ile diyagramdaki değişimi görebilirsiniz4.

sequenceDiagram
    participant John
    participant Alice
    participant Ela
    Alice->>John: Hello John, how are you?
    Note right of John: Text in note
    Alice->>Ela: Hi
    John-->>Ela: Fine!
    loop Every minute
        John->>Alice: Great!
    end
    Ela ->> John: Hello!
Mermaid JS - classDiagram
Şekil 3 - classDiagram

Sınıf diyagramları, ilgili Wikipedia sayfasında da belirtildiği üzere; yazılım mühendisliğinde, Birleşik Modelleme Dilindeki (UML) bir sınıf diyagramı (class diagram), sistemin sınıflarını, özniteliklerini, işlemlerini (veya yöntemlerini) ve nesneler arasındaki ilişkileri göstererek bir sistemin yapısını tanımlayan bir tür statik yapı diyagramıdır.10

class ile biçimlendirmeye başlayabileceğimiz sınıf diyagramı, nesne yönelimli modellemenin ana yapı taşıdır. Hayvanlar ile ilgili bir sınıf diyagramı oluşturup farklı türleri ve bu türlerin eylemlerini görselleştirelim11.

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()
      }
Mermaid JS - stateDiagram
Şekil 4 - stateDiagram

Durum (state) diyagramları genellikle sistem davranışları ile ilgili sınırlı sayıdaki durumun tanımlanmasında kullanılır. Mermaid aracılığı ile bir durum diyagramını stateDiagram-v2 ile tanımlayabilmekteyiz. Diyagramın başladığını ve durduğunu gösteren iki özel durum lie ifade edebiliriz. Bu ifadeler [*] sözdizimi ile yazılır ve geçişin yönü onu bir başlangıç veya bir durdurma durumu olarak tanımlar.

stateDiagram-v2
    [*] --> s1
    s1 --> [*]

Akışı iç içe oluşturabilmekteyiz.

stateDiagram-v2
    [*] --> First
    First --> Second
    First --> Third
    First --> Fourth

    state First {
        [*] --> fir
        fir --> [*]
    }
    state Second {
        [*] --> sec
        sec --> [*]
    }
    state Third {
        [*] --> thi
        thi --> [*]
    }

    state Fourth {
        [*] --> Sixth

        state Fifth {
            [*] --> Sixth
            second --> Third

            state Sixth {
                [*] --> third
                third --> [*]
            }
        }
    }

Varlık-bağıntı (ER) diyagramları, belirli bir bilgi kapsamındaki birbiriyle ilişkili konuları açıklar. Genellikle veritabanı oluşturmak için kullanılmaktadır. Örneğin, müşteri verileri bağlamındaki siparişler ve adres tanımlarını varlık ilişki diyagramı ile ele alabiliriz. Temel bir ER modeli, varlık türlerinden (ilgilenilen şeyleri sınıflandıran) oluşur ve varlıklar arasında var olabilecek ilişkileri (bu varlık türlerinin örnekleri) belirtir12.

erDiagram
    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
Mermaid JS - User Journey
Şekil 5 - User Journey

Kullanıcı yolculuğu (user journey) diyagramları, kullanıcıların bir sistem, uygulama veya web sitesindeki tanımlı bir hedefe ulaşmak için hangi adımları attığını takip etmemizi sağlayan bir diyagram türüdür. Örneğin, bir e-ticaret sitesi için sepet ile ödeme sonuç sayfasındaki tüm aşamaları bu diyagram türü aracılığı ile yorumlayabiliriz. journey ile birlikte bu tür diyagramlar oluşturabilmekteyiz.

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

TeamGantt Nedir? başlıklı yazıda TeamGantt bağlamında Gantt diyagramı ile ilgili temel bir bilgi vermiştim. Gantt diyagramı, bu yazıda da bahsi geçtiği üzere, bir proje akışını ve bu projenin bitirilmesi için gereken zamanı gösteren bir tür çubuk grafiğidir. Mermaid bize gantt ile bu tür bir diyagram oluşturma imkanı sunar13.

gantt
    dateFormat  YYYY-MM-DD
    title       Adding GANTT diagram functionality to mermaid
    excludes    weekends
    %% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)

    section A section
    Completed task            :done,    des1, 2014-01-06,2014-01-08
    Active task               :active,  des2, 2014-01-09, 3d
    Future task               :         des3, after des2, 5d
    Future task2              :         des4, after des3, 5d

    section Critical tasks
    Completed task in the critical line :crit, done, 2014-01-06,24h
    Implement parser and jison          :crit, done, after des1, 2d
    Create tests for parser             :crit, active, 3d
    Future task in critical line        :crit, 5d
    Create tests for renderer           :2d
    Add to mermaid                      :1d

    section Documentation
    Describe gantt syntax               :active, a1, after des1, 3d
    Add gantt diagram to demo page      :after a1  , 20h
    Add another diagram to demo page    :doc1, after a1  , 48h

    section Last section
    Describe gantt syntax               :after doc1, 3d
    Add gantt diagram to demo page      :20h
    Add another diagram to demo page    :48h

Pasta grafiği (pie chart), birbirleriyle ilişkili sayısal değerler arasındaki oranı göstermek amacıyla kullanılan bir grafik biçimidir. Pasta grafiğinde, her dilimin yay uzunluğu (ve dolayısıyla merkez açısı ve alanı) temsil ettiği miktarla orantılıdır. Mermaid pie ile bu tür grafikleri oluşturabilmemizi sağlar. Diğer diyagramlara kıyasla çok daha temel özellikler barındırır.

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

Git grafikleri (deneysel) deneysel düzeyde sunulan, geliştirilmeye devam eden ve bir git reposundaki değişimleri görselleştirmek amacıyla kullanılabilecek diyagram biçimidir. gitGraph ile oluşturulabilir3.

gitGraph:
options
{
    "nodeSpacing": 150,
    "nodeRadius": 10
}
end
commit
branch newbranch
checkout newbranch
commit
commit
checkout master
commit
commit
merge newbranch

Yazının giriş bölümünde de bahsettiğim üzere, diyagramlar SVG formatında sunulmaktadır. Bu sayede doğrudan ya da dolaylı olarak pek çok özelleştirme işlemini de gerçekleştirebilmek mümkün hale gelmektedir. init ile ifade edebileceğimiz konfigürasyon tanımlarının yetersiz olduğu durumlarda CSS ile biçimlere müdahale edebilmekteyiz. Aşağıdaki yeni tema geçiş sürecini özetlemek amacıyla oluşturduğum diyagrama ait kodu görebilirsiniz14.

Mermaid JS - User Journey
Şekil 6 - Flowcart
div.mermaid {
    background: #1c2230;
}
div.mermaid .edgeLabel,
div.mermaid .label {
    padding: 15px 10px;
}
%%{
    init: {
        'theme': 'base',
        'themeVariables': {
            'primaryColor': '#48556d',
            'primaryBorderColor': '#151920',
            'lineColor': '#135cff',
            'edgeLabelBackground':'#135cff',
            'tertiaryColor': '#151920',
            'nodeTextColor': '#ffffff',
            'arrowheadColor': '#ffffff'
        }
    }
}%%

graph TD
A(WordPress v.1)  -- CMS ve Tema Değişikliği --> B(Grav CMS)
B ==>|Light| C(v.2 Gliese 667 Cb)
B --> |Dark| D(v.3 HD 189733 b)

subgraph Geliştirmeler
    B
    C
end

C ==>|Modüller| D
C -- Geri Bildirimler --> E[A/B Testi]
C -- Online Ürünler --> F[MVT]
E -- Sayfa İçi Özellikler --> C

subgraph Testler
    B
    C
    E
    F
end

E ==>|UI Geliştirme| D
F ==>|Modüler Sayfalar| D

linkStyle 0 stroke-width:2px,fill:none,stroke:blue;
linkStyle 1 stroke-width:2px,fill:none,stroke:green;
linkStyle 2 stroke-width:2px,fill:none,stroke:yellow;
linkStyle 3 stroke-width:2px,fill:none,stroke:pink;
linkStyle default stroke-width:2px,fill:none,stroke:red;

Görüldüğü üzere linkStyle ile direktiflere ait biçimlere müdahale ederken init kapsamında da tema ile ilgili genel tanımlara yer verilmiş durumda. Arka plan ve label padding değeri ise CSS aracılığı ile gerçekleştirilmekte15.

GitHub ve GitLab gibi platformlar şu an için mermaid desteğine sahip değiller. Ancak, topluluk tarafından gelişmeler özellikle takip edilmekte16 17. Diğer yandan, bu süreçte kullanılmak üzere çeşitli eklentilerden yararlanmak mümkün18. Ayrıca, Jekyll gibi statik site araçları için de çeşitli eklentiler mevcut19.

Eğer Notion kullanıyorsanız, mermaid diyagramlarını kolaylıkla içeriklere dahil edebilirsiniz20 21.

Yakın zamanda karşılaştığım ve kısa zaman içerisinde pek çok kez kullandığım mermaid ile ilgili öğrenme sürecim devam ettikçe farklı yazım biçimleri ve özelleştirmeler ile ilgili eklemeler yapacağım.