PlantUMLにおけるガントチャートの書き方


PlantUMLでガントチャートを書く際の記法を機能別にまとめる。
内容的には下記参考ページの公式Documentに書かれていることを書き直し、タスクに関する事項とチャート全体に関わる事項で分けて並べ替えただけのものに近い。

各機能のうち、気になる点については、実際に確認して補足を加えてある。
- 参考ページ
    
    [ガントチャート](https://plantuml.com/ja/gantt-diagram)
    
## 発端
Excel上に入力したタスクについてのデータ(開始日、依存関係など)から、ガントチャートを作るプログラムを書いている。
各種ダイアグラムをまとめてくれているkroki.ioの[examples](https://kroki.io/examples.html)では、ガントチャートはmermaidのものを使っているので、最初はmermaidのものを使おうと思ったんだが、mermaidの公式サイトを見ても記法について十分な説明も無いし、依存するタスク間を結ぶ線も書かれないなど、イマイチだと感じた。
よく探すと、PlantUMLでもガントチャートが書け、ほぼ十分な機能を持ってることが分かった。

PlantUMLの公式Documentに書かれている説明は、ほぼ十分でなものではあるのだが、並び順が機能別になりきっていないのと、細かい仕様で書かれていない点が気になった。

各使用例をなるべく、説明したい事項に沿ったシンプルなものとし、私の気になって確認した事項を含めて書いたものがこの記事である。

# 基本構文

- SVC文型のように書く
- 最初の行：`@startgantt`
- 最後の行：`@endgantt`
- タスク: `[タスク名]`
- リソース: {`リソース名}`または`{リソース名:専任率}`
- 宣言の合成：`and`

---
# タスクの宣言
### 主な動詞

- `lasts` : タスクの期間
- `starts` : タスクの開始
- `ends` : タスクの終了
- `happens`: マイルストーンの設定日

## 期間、開始日、終了日の宣言(他タスクに依存しない場合)

```
[TaskA] lasts 10 days
[TaskA] starts at 2023/1/2
[TaskA] ends at 2023/2/1
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/cf682fb8-040d-3c96-617a-b0c17ae930d5.png)

<aside>
⚠️ 以下に注意

- 日にちを指定する場合、`starts`, `ends`の後ろの`at`は省略可
- 末尾の`s`を忘れないように
- 期間、開始日、終了日の3つ共を宣言した場合、期間は無視される
</aside>

## 依存関係

以下の様に動詞と名詞のstartとendを用いて、タスク間の依存関係を定義できる

<aside>
⚠️ 動詞の三単現のsは省略できないので注意
</aside>

```
@startgantt
[TaskA] lasts 5 days
[TaskB] lasts 10 days
[TaskC] lasts 8 days
[TaskD] lasts 6 days
[TaskE] lasts 7 days
Project start 2023/1/1
[TaskA] starts at 2023/1/10
[TaskB] starts at [TaskA]'s end
[TaskC] starts at [TaskA]'s start
[TaskD] ends at [TaskA]'s end
[TaskE] ends at [TaskA]'s start
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/4e87f2b5-8300-ed85-f47a-219a5005d6b7.png)


- 終了―開始型（FS型：Finish to Start）
    
    単純に継続するタスクはキーワード`then`を用いて下記の様にも書ける
    
    ```
    @startgantt
    [TaskA] lasts 5 days
    then [TaskB] lasts 2 days
    then [TaskC] lasts 3 days 
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/f0477d63-d60f-c955-ea5c-2445d0ac5f74.png)

    これは、矢印`->を用いて下記のようにも書ける`
    
    ```
    @startgantt
    [TaskA] lasts 5 days
    [TaskB] lasts 4 days
    [TaskC] lasts 3 days 
    [TaskA] -> [TaskB]
    [TaskB] -> [TaskC]
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/55f5818e-a548-6304-fe07-985d74eaa151.png)

    
- 開始―開始型（SS型：Start to Start）
    
    <aside>
    💡 この場合、TaskAとTaskBの依存関係の線は書かれない場合がある(プロジェクト開始前にはみ出た場合と思われる)
    
    </aside>
    
- 終了―終了型（FF型：Finish to Finish）
- 開始―終了型（SF型：Start to Finish）

<aside>
⚠️ 試行した結果より、タスクを記述する順序に関して以下と推測する

- タスクの宣言が先に出現した順にガントチャートは作られる
- 依存関係の宣言で参照されるタスクの日程が先に確定していないと、エラーやおかしな結果となる
- 上記を考慮すれば、上の例の様に依存関係だけをまとめて後ろに並べても良いし、下の例の様に各タスクの期間や開始日などの宣言と依存関係はタスクごとにまとめても良い
    
    ```
    @startgantt
    Project start 2023/1/1
    [TaskA] lasts 5 days
    [TaskA] starts at 2023/1/10
    [TaskB] lasts 10 days
    [TaskB] starts at [TaskA]'s end
    [TaskC] lasts 8 days
    [TaskC] starts at [TaskA]'s start
    [TaskD] ends at [TaskA]'s end
    [TaskD] lasts 6 days
    [TaskE] lasts 7 days
    [TaskE] ends at [TaskA]'s start
    @endgantt
    ```
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/19136769-191b-ad07-4f35-b3016b2e0cda.png)


    
- タスクのチャート上の並び順は、宣言の出現順序であるため、依存関係を後ろにまとめる場合、必要であれば先にダミーでタスク宣言をすると良い
    
    ```
    @startgantt
    project start 2023/1/30
    [TaskA] lasts 1 days
    [TaskB] lasts 5 days
    [TaskA] starts at [TaskB]'s end
    [TaskA] ends 2023/2/10
    @endgant
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/e900a1dd-4f6a-e755-d540-23312910a274.png)

    
</aside>

## 遅延日数、先行日数

キーワード`after`, `before`を用いて、下記の様に開始日、終了日から指定日数だけずれた日を指定できる

```
@startgantt
[TaskA] lasts 5 days
[TaskB] lasts 10 days
[TaskC] lasts 8 days

Project start 2023/1/1
[TaskA] starts at 2023/1/10
[TaskB] starts 2 days after [TaskA]'s end
[TaskC] ends 1 day before [TaskB]'s end
@endgantt
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/108630d9-3db1-7bdc-1ee5-58410c78b7ed.png)


## 進捗状況

`is xx% completed`を用いて、タスクの完了率を設定し、塗りつぶし量で表示させることができる

```
@startgantt
[TaskA] lasts 20 days
[TaskB] lasts 10 days
[TaskB] starts 5 days after [TaskA]'s start
[TaskA] is 50% completed
[TaskB] is 40% completed
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/caae5780-167d-9cca-9c80-18480d10eda5.png)


## **タスクの中断**

`pauses on`を用いて、タスクの中断する期間、曜日を宣言できる

```
@startgantt
Project starts 2023/2/1
saturday are closed
sunday are closed
[TaskA] lasts 15 days
[TaskA] pauses on 2023/2/8
[TaskA] pauses on monday
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/6740800e-221c-c397-f919-60b651e34b64.png)


## リソース

- キーワード`on`を用いて各タスクで使用されるリソースを指定することができる
- リソースは`{ }`で囲む
- 1つのタスクに複数のリソースを割り当てる場合は、それを並べて指定する
- 各1日分の使用率を指定することができる
- リソースが使用できない期間(人であれば休暇の期間)を`is off`として定義できる
    - リソースの使用率は、1つのタスクを1日分完了する分を100%と解釈される
    - キーワード`last`で指定された期間は、タスクの継続期間ではなく、そのタスクを完了するのに必要な作業量を日数で表したものであり、割り当てたリソースが足りなければタスクの継続期間**は**延長される

```
@startgantt
project start 2023/2/1
projectscale daily zoom  2
[TaskA] on {person1} lasts 4 days
[TaskB] on {person2:50%} {person3:50%} lasts 10 days
{person1} is off on 2023/2/3 to 2023/2/4
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/46735be9-51f3-6e98-1b16-18875e544626.png)

- `hide ressources names`と宣言することにより各タスクにリソースが表示されないようにできる
    
    ```
    @startgantt
    project start 2023/2/1
    projectscale daily zoom  2
    hide ressources names
    [TaskA] on {person1} lasts 4 days
    [TaskB] on {person2:50%} {person3:50%} lasts 10 days
    {person1} is off on 2023/2/3 to 2023/2/4
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/fd565b9f-8569-fb53-1d3f-0c9ae6563b7e.png)

    
- `hide ressources footbox`と宣言することにより、リソースごとの使用率のサマリーを非表示にできる
    
    ```
    @startgantt
    project start 2023/2/1
    projectscale daily zoom  2
    hide ressources footbox
    [TaskA] on {person1} lasts 4 days
    [TaskB] on {person2:50%} {person3:50%} lasts 10 days
    {person1} is off on 2023/2/3 to 2023/2/4
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/5ec83b8a-e50e-226e-7387-e36693ed7e12.png)


## マイルストーン

動詞`happens`を用いてマイルストーンを定義できる

- 依存関係に基づくマイルストーン
    
    ```
    @startgantt
    Project start 2023/1/1
    [TaskA] lasts 3 days
    [Milestone] happens at [TaskA]'s end
    [TaskB] lasts 2 days
    [TaskB] starts at [TaskA]'s end
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/ed278bdd-dae2-af4d-6a70-f2aa7f1c80fe.png)

    
    <aside>
    ⚠️ タスクとマイルストーンの宣言の順序通りに表示されるゆえ、順序を注意のこと
    
    </aside>
    
    <aside>
    💡 マイルストーンを上にまとめたい時は下例のようにダミーの宣言を入れる(日数は何日でも後続の`happens`でマイルストーンになる
    
    ```
    @startgantt
    Project start 2023/1/1
    [Milestone] lasts 1 days
    [TaskA] lasts 3 days
    [TaskB] lasts 2 days
    [TaskB] starts at [TaskA]'s end
    [Milestone] happens at [TaskA]'s end
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/d07b21da-a9fc-aa67-645a-9cb16d790d52.png)

    
    </aside>
    
- 日付指定のマイルストーン
    
    ```
    @startgantt
    Project start 2023/1/1
    [Milestone] happens 2023/1/4
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/1e555376-be4d-88fb-2308-d77ef330469d.png)

    
- 複数タスク完了のマイルストーン
    
    指定されたタスク全てが完了したところにマイルストーンが置かれる
    
    ```
    @startgantt
    Project start 2023/1/1
    [TaskA] lasts 6 days
    [TaskB] lasts 8 days
    [Milestone] happens at [TaskA]'s end
    [Milestone] happens at [TaskB]'s end
    [TaskC] lasts 2 days
    [TaskC] starts at [TaskA]'s end
    @endgantt
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/3207754a-5b76-0f74-b6ce-c9b6e6671205.png)

    
- 2つのマイルストーンに挟まれたタスク
    
    下記の様に`occurs from [A] to [B]`と書くことで、2つのマイルストーンで開始と終了が定義されるタスクを宣言できる
    
    (他の書き方でも書けるので、この記法を使わなくても良い)
    
    ```
    @startgantt
    Project starts 2023/2/1
    [PrjStart] happens 2023/2/3
    [PrjEnd] happens 2023/2/28
    [TaskA] occurs from [PrjStart] to [PrjEnd]
    --
    [TaskB] starts at [PrjStart]'s start
    [TaskB] ends at [PrjEnd]'s end
    ' 下記はエラーとなる
    ' [TaskC] occurs from [TaskA]'s start to [PrjEnd]
    @endgantt
    ```
   

    ![taskbetweenmilestones.svg](https://www.plantuml.com/plantuml/png/SoWkIImgIK_CAodX2YZApqfDBb402nKh61aO6UiRwHjoHGSKPGM3n68LCX8B2bBpu7B6O3dNl1GC6ICBhkYGnE9inrY5_EJaqg9YXRIY_5m59ADAyXLWchbqTI6gdM9XbYUM8AbLBuO8mnMbvgM0bC0C02e02N6fAppPqVrYnOp7ZUiVDwrutBpoSVEUnuqh7ZUkUjpK3PG5QtT6TH74bN0hK9pb03GK73G0)
    

## 区切り線

`--` で区切り線を入れることができる

`-- strings --`の形で区切り線上に説明語句などを入れることができる

```
@startgantt
project start 2023/1/30
[TaskA] lasts 10 days
**--**
[TaskB] lasts 6 days
-- sub task 2 --
[TaskC] lasts 3 days
[TaskC] starts 2 days after [TaskB]'s end
@endgant
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/0770722d-344e-dfde-d376-eafbeea472e4.png)

### 同じ行にタスクを並べる

下記の様に`displays on same row as`とすることで、複数のタスクやマイルストーンを同じ行に並べることができる

```
@startgantt
[TaskA] lasts 5 days
[TaskB] lasts 6 days
[TaskB] starts 2 days after [TaskA]'s end
[TaskC] lasts 7 days
[TaskC] starts at [TaskB]'s end
[TaskB] displays on same row as [TaskA]
[TaskC] displays on same row as [TaskB]
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/68ce02e6-23a4-7096-3849-30fba3146338.png)

## 色

`is colored in`を用いて、塗りつぶし色と線の色を指定できる

```
[TaskA] is colored in GreenYellow/Green
```

- 参考ページ
    
    [Choosing colors](https://plantuml.com/ja/color)
    
- 色見本は下記を表示させることで得られる
    
    ```
    @startuml
    colors
    @enduml
    ```
    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/f9db1037-70ae-b77c-5d2f-18b36a035017.png)

## タスクの短い名前

期間などの宣言文中でキーワード`as`を用いて短い名前を定義できる

```
[TaskA] as [A] lasts 15 days
```

### タスク、マイルストーンの削除

下記の様に、削除予定のタスクやマイルストーンを区別するように示すことが出来る

```
@startgantt
[TaskA] lasts 20 days
then [TaskB] lasts 4 days
then [TaskC] lasts 5 days
[Milestone1] happens at [TaskA]'s end
[Milestone2] happens at [TaskC]'s start
[TaskB] is deleted
[Milestone1] is deleted
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/04c81fcb-8668-a237-25ee-1623bafd824e.png)


---
# チャート全体に関する宣言

## プロジェクトの開始日

特定の日付をプロジェクトの開始日時に指定できる。この指定が無い場合、一番最初のタスクが指定した日付が開始日となる。

```
@startgantt
project start 2023/1/1
[TaskA] lasts 5 days
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/4ac3229e-475b-39e8-e01c-e9300fd36236.png)


## 日付に色

特定の日付、あるいは期間に対して色を付けることができる

```
@startgantt
Project starts the 2020/09/01 

2020/09/07 is colored in salmon
2020/09/13 to 2020/09/16 are colored in lightblue
[TaskA] lasts 5 days
[TaskB] lasts 20 days
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/a4d9cd58-e873-b707-0fcf-fe6f356ac29a.png)


## 今日に色

下記の様に、今日の日付を指定し、そこに色を付けることができる

```
@startgantt
Project starts 2023/2/1
[TaskA] lasts 20 days
[TaskB] lasts 8 days
[TaskB] starts after [TaskA]'s end
today is 2023/2/15 and is colored in red
' 下記表現も可
' today is 10 days after start and is colored in #AAF
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/4835f8d7-51ec-917b-77f1-594fbf1271df.png)


## スケール(表示単位)の指定

`printscale`、`ganttscale`、`projectscale`のいずれかに対して、時間スケールを表すキーワード`daily`、`weekly`、`monthly`、`quarterly`、`yearly`を指定することで表示されるスケールを指定できる(デフォルトは`daily`)

```
@startgantt
projectscale weekly
Project starts 2023/1/1
[TaskA] lasts 40 days
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/70c68442-95f6-3b59-327d-0313d82e79b5.png)


## ズーム

スケールの指定の後ろにキーワードzoomと倍率を指定することでズームされる

```
@startgantt
projectscale weekly zoom 2
Project starts 2023/1/1
[TaskA] lasts 40 days
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/84a520e2-54c4-a930-1982-6c60be05f0e4.png)

## 休業日

特定の曜日を休業日にすること、そのうちの特定の日を稼働日にすること、特定の日を休業日にすることができる(休業日分を含まない形で期間は考慮される)

```
@startgantt
Project starts 2023/2/1
saturday are closed
sunday are closed
2023/2/11 is open
2023/2/9 is closed
[TaskA] lasts 15 days
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/6d3df500-3fa4-8179-2b8f-bdb964f5823c.png)


<aside>
💡 タスクの期間を`week`で指定した場合、日にち指定の休業日は考慮されるが、曜日による休業日によってタスク終了日が延びることはない

```
@startgantt
project start 2023/2/1
sunday are closed
2023/2/2 is closed
[TaskA] lasts 1 day and 1 week 
@endgant
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/ef016fe4-2bb6-31f1-4ebf-e756cc61398b.png)


</aside>

## タイトル、ヘッダ、フッタ、キャプション、凡例

下記の様に、タイトルなどを追加できる

```
@startgantt
header This is header
footer This is footer
title This is title of chart
[TaskA] lasts 13 days

legend
This is a legend
Sentences could be shown
end legend

caption This is caption of chart

@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/bd32547b-a14e-3d06-ca33-50748695a430.png)


## 下部のボックスの非表示

`hide footbox`とすると下部のボックスが非表示となる

```
@startgantt
[TaskA] lasts 4 days
then [TaskB] lasts 4 days
hide footbox
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/ae5bcdb2-f9b5-7e04-b681-b1a40207a088.png)


## 表示言語の指定

下記の様に表示言語を指定できる

指定可能な言語は以下

| en | 英語 |
| --- | --- |
| de | ドイツ語 |
| ja | 日本語 |
| zh | 中国語 |
| ko | 韓国語 |

```
@startgantt
language ja
project starts 2023/2/1
[TaskA] lasts 20 days
then [TaskB] lasts 4 days
@endgantt
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/bbca07f8-d34c-e3a7-c638-bfa07ab220f9.png)


---

## その他

- ハイパーリンク
    
    ```
    @startgantt
    [taskA] lasts 10 days
    [taskA] links to [[http://plantuml.com]]
    @endgantt
    ```
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/40d7ef4a-2561-2292-842a-0b6030c9076f.png)

    
    <aside>
    ⛔ Notion上では、オリジナル画像(pngファイル)へのリンクが有効でハイパーリンクがうまく動かないもよう
    
    </aside>
    
- コメント行
    
    行頭に`'`を置くことでコメント行とできる
    
    `/'` で始まる行から、 `'/` で終わる行までは複数行のコメント行となる
    
    <aside>
    ⛔ どうも、行の途中からコメントとすることは出来ないと思われる(やるとエラーとなる)
    
    </aside>
    
- ノートの追加
    
    下記の様にノートを追加できる
    
    ```
    @startgantt
    
    -- test01 --
    
    [task01] lasts 4 days
    note bottom
    'note left
    memo1 ...
    memo2 ...
    explanations1 ...
    explanations2 ...
    end note
    
    [task02] lasts 8 days
    [task01] -> [task02]
    note bottom
    'note left
    memo1 ...
    memo2 ...
    explanations1 ...
    explanations2 ...
    end note
    -- test02 --
    
    [task03] as [t3] lasts 7 days
    [t3] -> [t4]
    @endgantt
    ```
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199987/57fedffe-5eeb-caa8-35cb-7612b7bf51c6.png)

# 関連ページ
ここでまとめたものを元に、pythonからガントチャートを作り易くするためのクラス定義を作成したものを下記で公開しました。
* [PlantUML gantt用クラス定義](https://qiita.com/asobinin_kinsan/items/97916b5195a5a3f513f7)