マーメイド#12 状態遷移図2

**ひとりマーメイド12日目**
**状態遷移図2**

## 概要
マーメイドエンジニアのひろきです。こんにちは。
最近流行り（流行らせたい）のマーメイドについて理解を深めていこうと思います。

この記事では状態遷移図の記述について紹介します！

↓↓前回の記事はこちら

https://qiita.com/hirokiwa/private/fd4296e8ae087d67ad43

## まーめいど！じょうたいせんい！
前回の記事では状態遷移図の見方と基本的な記法を紹介しました！
引き続き状態遷移図の記法を見ていきます！

## 分岐
分岐ノードの宣言には`<<choice>>`を使用します。

`state STATE_ID <<choice>>`
```:mermaid
stateDiagram-v2
    state if <<choice>>
```
```mermaid
stateDiagram-v2
    state if <<choice>>
```

**状態遷移の分岐**
分岐ノードにテキストを挿入することはできません。

```:mermaid
stateDiagram-v2
    state if <<choice>>
    [*] --> if
    if  --> s1: n >= 0
    if  --> s2: n < 0
    s1  --> [*]
    s2  --> [*]
```
```mermaid
stateDiagram-v2
    state if <<choice>>
    [*] --> if
    if  --> s1 : n >= 0
    if  --> s2: n ＜ 0
    s1  --> [*]
    s2  --> [*]
```
## 並列プロセス
`<<fork>>`, `<<join>>`を用いて並列プロセスを定義することができます。

記述中ではforkポイントとjoinポイントを定義し、通常の状態ノードと同様に扱います。
`state FORK_STATE <<fork>>`
`state JOIN_STATE <<join>>`

```:mermaid
stateDiagram-v2
    state fork_point <<fork>>
    state join_point <<join>>
    
    [*]         --> fork_point
    fork_point  --> s1
    fork_point  --> s2

    s1          --> join_point
    s2          --> join_point
    join_point  --> [*]
```
```mermaid
stateDiagram-v2
    state fork_point <<fork>>
    state join_point <<join>>
    
    [*]         --> fork_point
    fork_point  --> s1
    fork_point  --> s2

    s1          --> join_point
    s2          --> join_point
    join_point  --> [*]
```

forkポイントとjoinポイントを複数定義することで多重並列プロセスの記述も可能です。
```:mermaid
stateDiagram-v2
    state fork_point1 <<fork>>
    state join_point1 <<join>>
    state fork_point2 <<fork>>
    state join_point2 <<join>>
    state fork_point3 <<fork>>
    state join_point3 <<join>>
    
    [*]         --> fork_point1

    fork_point1 --> fork_point2
    fork_point2 --> s1
    fork_point2 --> s2

    s1          --> join_point2
    s2          --> join_point2
    join_point2 --> join_point1
    
    fork_point1 --> fork_point3
    fork_point3 --> s3
    fork_point3 --> s4

    s3          --> join_point3
    s4          --> join_point3
    join_point3 --> join_point1

    join_point1 --> [*]
```
```mermaid
stateDiagram-v2
    state fork_point1 <<fork>>
    state join_point1 <<join>>
    state fork_point2 <<fork>>
    state join_point2 <<join>>
    state fork_point3 <<fork>>
    state join_point3 <<join>>
    
    [*]         --> fork_point1

    fork_point1 --> fork_point2
    fork_point2 --> s1
    fork_point2 --> s2

    s1          --> join_point2
    s2          --> join_point2
    join_point2 --> join_point1
    
    fork_point1 --> fork_point3
    fork_point3 --> s3
    fork_point3 --> s4

    s3          --> join_point3
    s4          --> join_point3
    join_point3 --> join_point1

    join_point1 --> [*]
```
## 並行プロセス
並行プロセスを定義することができます。
複合状態の中で`--`を用いて記述を区切ります。
```:mermaid
stateDiagram-v2
    [*] --> Process

    state Process {
        [*] --> s1
        s1  --> [*]
        --
        [*] --> s2
        s2  --> [*]
        --
        [*] --> s3
        s3  --> [*]
    }
```
```mermaid
stateDiagram-v2
    [*] --> Process

    state Process {
        [*] --> s1
        s1  --> [*]
        --
        [*] --> s2
        s2  --> [*]
        --
        [*] --> s3
        s3  --> [*]
    }
```

 ## ノート
状態ノードの左または右にノートを配置して説明文を挿入することができます。

|POSITION|配置|
|---|---|
|left|左|
|right|右|


ノートの定義には2種類の記法があります。
```:記法1
note POSITION of STATE_ID
    NOTE_TEXT
end note
```

```:記法2
note POSITION of STATE_ID: NOTE_TEXT
```

s1には記法1, s2には記法2を適用します。
```:mermaid
stateDiagram-v2
    s1
    s2

    note left of s1
        This is the note.
    end note

    note right of s2 : This is the note.
```
```mermaid
stateDiagram-v2
    s1
    s2

    note left of s1
        This is the note.
    end note

    note right of s2 : This is the note.
```

単独の状態ノードに対しては左右に正しくノートが配置されますが、状態に遷移を付与するとレンダラーは左右を見失います。

```:mermaid
stateDiagram-v2
    s1 --> s2

    note left of  s1: This is the note.
    note right of s2 : This is the note.
```
```mermaid
stateDiagram-v2
    s1 --> s2

    note left of  s1: This is the note.
    note right of s2 : This is the note.
```
挿入位置の指定が意味をなしていません。そのうち改善されると思うので気にせず使いましょう。

## ダイアグラムの向き
`direction`でダイアグラムの向きを指定することができます。

`direction TB`(または`direction TD`)で上から下へのグラフになります。

```:mermaid
stateDiagram-v2
    direction TB
    s1 --> s2
```

```mermaid
stateDiagram-v2
    direction TB
    s1 --> s2
```

`direction LR`で左から右へのグラフになります。

```:mermaid
stateDiagram-v2
    direction LR
    s1 --> s2
```

```mermaid
stateDiagram-v2
    direction LR
    s1 --> s2
```

以下のように自由自在に向きを変更することができます。

|記述|向き|
|---|---|
|TB|↓|
|TD|↓|
|BT|↑|
|LR|→|
|RL|←|

## スタイリング
※`cssDef`による状態遷移図のスタイリングはマーメイドver.9.3.0以降でレンダリング可能です。

ダイアグラムをスタイリングすることができます。基本的な概念はHTML/cssと同様です。

**クラスの宣言**
`cssDef`によりクラスを定義します。同一クラス内のスタイル定義は全て1行で記述する必要があります。すごく読みづらいですが、改行するとエラーを吐きます。
```
cssDef CLASS_NAME fill:#fff, color:#333,...
```

主なstyleパラメータは以下の通りです。

|||
|---|---|
|fill|ノードの背景色|
|stroke|ノードの縁の色|
|stroke-width|ノードの縁の太さ|
|color|文字の色|
|stroke-dasharray|縁の点線の長さの割合|


**スタイルの適用**
スタイルの適用には2種類の記法があります。
```:記法1
class STATE_ID CLASS_NAME
```

```:mermaid
stateDiagram
    direction LR

    [*]  --> s1
    s1   --> s2
    s2   --> [*]

    classDef style_s1 fill:#00FF00, color:black, stroke:#FF22FF, stroke-width:10px,
    classDef style_s2 fill:#f00, stroke:#fff,stroke-width:4px, color:yellow, stroke-dasharray:6 4

    class s1 style_s1
    class s2 style_s2
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/075150e0-0c62-db40-3d5a-b8595469a6c0.png" width=400px>

```:記法2
STATE_ID::: CLASS_NAME
```

```:mermaid
stateDiagram
    direction LR

    [*]  --> s1::: style_s1
    s1   --> s2::: style_s2
    s2   --> [*]

    classDef style_s1 fill:#00FF00, color:black, stroke:#FF22FF, stroke-width:10px,
    classDef style_s2 fill:#f00, stroke:#fff,stroke-width:4px, color:yellow, stroke-dasharray:6 4

```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/075150e0-0c62-db40-3d5a-b8595469a6c0.png" width=400px>

## まとめ
状態遷移図の記法を紹介しました。

↓↓次回の記事はこちら！！

https://qiita.com/hirokiwa/items/5dd3a3109a5e6ae8b251

## 参考

https://mermaid-js.github.io/mermaid/#/