【12/24にGitLab対応!】テキストで自在に「描く」- KrokiではじめるDiagram as Code

これは、 [NTTコミュニケーションズ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nttcom) 25日目の記事です。
昨日は @tnoyama さんの「[TEKTONとArgoを比較してみた](https://zenn.dev/tnoyama/articles/d3358cc82f6173)」でした。お楽しみいただけましたか？

## Krokiとは

本記事では、テキストからの図表生成ツール Krokiを紹介します。最新バージョンは0.9.0です。

- 公式docs: [Kroki!](https://kroki.io/)
- GitHub: [yuzutech/kroki: Creates diagrams from textual descriptions!](https://github.com/yuzutech/kroki)

### 概要

Kroki!は、テキストから統一的なAPIで、

- UML
- C4
- データ可視化
- その他図表

を、PNG, SVG, JPG等でレンダリングしてくれます。

対応するのは実に30種以上。何を言っているのかわかりませんが、本当です。例えば以下のダイアグラムに対応しており、対象もまだ増えています。つい先日12/22に、[Excalidraw](https://github.com/excalidraw/excalidraw)に対応しました :tada:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/d27b05e5-03c7-66f3-e77d-56aad07bd428.png)


> https://kroki.io/examples.html より一部改変


### 利用できる環境、プラグイン

Krokiは、以下２つの方法で使えます。

- Dockerコンテナをローカルやプライベート環境で動かす
- 無償のWeb API(kroki.io)を使う

ここ2年程アクティブなプロジェクトに見え、2019年3月には[Hacker News](https://news.ycombinator.com/item?id=19486801)に登場していました。最近も様々な所で、対応が進んでいます。

- [AsciiDoc対応](https://qiita.com/Anubis_369/items/04d26befab6e92cc55bb)
- 静的サイトジェネレータのプラグイン
    - [Hexo](https://www.npmjs.com/package/hexo-filter-kroki)
    - [Sphinx](https://pypi.org/project/sphinxcontrib-kroki/)
    - [Hugo(WIP)](https://github.com/gohugoio/hugo/pull/7919)
- Wiki、ドキュメンテーションサイトのプラグイン
    - [Wiki.js](https://github.com/Requarks/wiki/pull/1900)
    - [Docsify](https://www.npmjs.com/package/docsify-kroki)
    - [Antora](https://antora.org/)
- Juliaへの対応
    - Documenter.jl, Jupyter上で描画できる[Kroki.jl](https://bauglir.github.io/Kroki.jl/stable/)
- アドベントカレンダーの前日! 12/24 :tada: [GitLabインテグレーション対応](https://docs.gitlab.com/ee/administration/integration/kroki.html)   
- [Marpなど、各種Markdownエディタへの埋込も可能](https://qiita.com/tomo_makes/items/aafae4021986553ae1d8#%E5%A4%96%E9%83%A8%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AE%E5%9B%B3%E8%A1%A8%E3%82%92%E5%8F%96%E3%82%8A%E8%BE%BC%E3%82%80)

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">🤯 <a href="https://t.co/WKnRXpfvrO">https://t.co/WKnRXpfvrO</a> is rapidly gaining popularity.<br>In march, the public instance has generated 40K diagrams, last month it was 250K diagrams! 📈 <a href="https://t.co/M4xfqxnt4N">pic.twitter.com/M4xfqxnt4N</a></p>&mdash; Guillaume Grossetie (@Mogztter) <a href="https://twitter.com/Mogztter/status/1319226084760735745?ref_src=twsrc%5Etfw">October 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Last month, <a href="https://t.co/KZ0F0IOd8s">https://t.co/KZ0F0IOd8s</a> has generated 600K diagrams with a spike at 60K on a single day! 📈 <a href="https://t.co/cpd8gMMFdn">pic.twitter.com/cpd8gMMFdn</a></p>&mdash; Guillaume Grossetie (@Mogztter) <a href="https://twitter.com/Mogztter/status/1336373732865138689?ref_src=twsrc%5Etfw">December 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

中の人(Guillaume Grossetie氏)によると、kroki.ioでの図表生成数も、3月には4万だったが、9月には25万まで伸びたとのこと。その後、11月には60万に達したとされています。まさに倍々ゲーム。内数も、各描画エンジンの人気度を示していて、面白いです。

上記に加え、様々なプロジェクトのIssueやPRに、Kroki対応を論じるスレッドがあり、まだ広がりを見せそうです。

### 何が嬉しいか

活用すると、インラインテキスト記述で図表混じりの文書を簡単に作り、gitで管理できます。また、Krokiの対応エンジンを眺めると、「こんなものもあったのか！」と楽しい発見があります。構造を規定するだけで図表が出来るので、思考がそのまま投影される心地よさもあります。

まだ日本語での紹介は多くないため、知るきっかけになりましたら！

## リモートワークと「図表」のありがたみ

2020年といえば、コロナ禍における働き方の変化がありました。弊社も、先日[リモートワークハンドブック](https://nttcom.github.io/remote-work-handbook/)をリリースし、反響をいただきました。

リモートワークが進むと、「同じ時間・同じ場所」で、「相手の表情を見ながら」話す以上に、卓上、ホワイトボード上で、描かれた「形」「位置」「図表」を共有しながら話すありがたみを感じます。

「同じ時間・違う場所」「違う時間・違う場所」へのコミュニケーションの軸足が移ると共に、「形」「位置」「図表」をどう効率的に扱えば良いかと考えます。従来の手描きメモの代わりに、JamboardとiPad Pro、またはペンタブレット。スティッキーノートワークの代わりに、Miroを使うことが増えました。

ただ、継続的に、「違う時間・違う場所」の人に物事を伝えるには、文書と共に、図表も推敲と更新を続ける必要があります。文書と図表を、一緒にリポジトリ管理しておきたくなるものです。一定表現が決まっているもので、テキストからの生成が簡便なら、ドラフト時からも使えます。

そこで選択肢に上がるのが、テキストからの図表生成です。

## テキストからの図表生成とKroki

テキストからの図表生成といえば、下図のように、古くはGraphviz、それを描画に活用するPlantUML、mermaid.jsなど、D3.jsを描画に使うJavaScriptライブラリなどがあります。他にWebSequenceDiagramのように、オンラインのWYSIWYGエディタが提供されているものもあります。

- Graphviz https://graphviz.org/
- PlantUML https://plantuml.com/ja/
- mermaid.js https://mermaid-js.github.io/mermaid/#/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/483ac058-e3f8-1264-7c59-32e142189be9.png)

> 図表は上記公式サイトから引用

ただ、以前から環境のセットアップの問題がありました。Sublime TextやAtom等から始まり、VSCodeのプラグイン、TyporaというMarkdownエディタなど、PlantUMLやmermaid.jsを扱えるものは出てきたものの、対象の図表は限られます。
オンラインのエディタは便利に使えるものの、社内に閉じて使いたい情報はアップロードできないこともあります。

そんな課題を解決しつつ、様々な図表を全部入りで使えるのがKrokiです。

> - **すぐ使える**
>   図表ライブラリは様々な言語で書かれています。Haskell, Python, JavaScript, Go, PHP, Javaなどです。ただ信じてください、全部インストールして準備するくらいなら、他のことに時間を使いましょう。krokiなら、すぐに始められます。
>
> - **シンプル**
>   すべてのダイアグラムライブラリに統一のAPIを提供します。一度学んだら、色々な場所の応用できます。
>
> - **フリー＆オープンソース**
>   コードはすべてGitHub上で公開され、Krokiを無料提供することが目標です。
>
> - **速い**
>   モダンなアーキテクチャを使い、パフォーマンスに優れています。
>
> https://docs.kroki.io/kroki/features/ より翻訳・要約

## krokiが扱える図表

UML、C4、その他図表、データ可視化などが扱えます。

### UML

UMLについて、各図表の説明は不要でしょう。主にPlantUMLでカバーしています。

- ブロック図
- シーケンス図
- アクティビティ図
- ネットワーク図
- ユースケース
- クラス図
- 状態遷移図
- オブジェクト図
- デプロイメント図
- タイミング図
- ER図

### C4

C4は、アジャイル時代に最適なソフトウェアアーキテクチャの記述方法です。C4は、それぞれコンテキスト、コンテナ、コンポーネント、コードの4つを指し、UMLほど細かかったり、複雑にならずに描けます。[ソフトウェアアーキテクチャのためのC4モデル](https://www.infoq.com/jp/articles/C4-architecture-model/)に、詳しい解説があります。

- C4 コンテキスト図
- C4 コンテナ図
- C4 コンポーネント図

### その他のダイアグラム

発想を助けるマインドマップ、WBS, ガントチャートといったプロジェクト管理のための図表、ビジネスプロセス記法であるBPMNから、ハードウェアの世界で使うデジタルタイミング図、ネットワークのパケットを定義するパケット図、ラック搭載図まで、ここにはドメインごとに、多種多様の図表があります。

- マインドマップ
- WBS
- ガントチャート
- BPMN図
- オブジェクト指向グラフ
- パケット図
- ラック搭載図
- デジタルタイミング図（波形）
- バイトフィールド図
- Excalidraw

### データ可視化

簡単なデータ可視化を挿入したいなら、Vega, Vega-liteをKroki経由で使うことができます。棒グラフ、折れ線グラフなど一般的なものから、ヒートマップ、ワードクラウドまで対応しています。

- 棒グラフ
- 折れ線グラフ
- 円グラフ
- 散布図
- 地図
- ツリー
- ネットワーク
- ヒートマップ
- ワードクラウド
- ビースウォーム

## Krokiが対応する描画エンジン

krokiの実態は、様々なテキストからのダイアグラム生成エンジンへのゲートウェイです。以下のエンジンに対応しています。「いくつか見たことがある！使ったことある！」という方も多いのではないでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/a858b804-6b31-c458-f091-05e1b2cb8d3f.png)
> 出典: https://kroki.io/#support



## 使ってみる
### まずWebから触る

https://kroki.io/#try のプルダウンから、様々な図表の種類をブラウズしてみましょう。左にテキスト記述、右にAPIで動的に生成された図表が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/e1b9853e-92ab-5cdd-e672-2c16fedcfc45.png)


### 色々な実例と記法を見る

次に、[Kroki Examples](https://kroki.io/examples.html)から、実例を確認し、生成を試してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/ad84135a-0235-5793-c45a-4811b1068079.png)


### GitLabで使う

GitLabは[公式にインテグレーション](https://docs.gitlab.com/ee/administration/integration/kroki.html)されています。AdminがKrokiとの連携設定を行えば、すぐに使えます。設定で、セルフホスト、開発元提供の無償APIサービス kroki.ioのいずれも選べます。ただし、GitLab.comでは、まだ現状は使えません。

### 静的サイトジェネレータで使う

静的サイトジェネレータでは、以下のプラグインがあるようです。セルフホスト、kroki.ioのいずれも選べます。

- [Hexo](https://www.npmjs.com/package/hexo-filter-kroki)
- [Sphinx](https://pypi.org/project/sphinxcontrib-kroki/)
- [Hugo(WIP)](https://github.com/gohugoio/hugo/pull/7919)

### Wiki、ドキュメンテーションサイトで使う

以下、それぞれプラグインが提供されています。Antoraは、Kroki自体のドキュメントサイトに採用されています。同じく、セルフホスト、kroki.ioのいずれも選べます。

- [Wiki.js](https://github.com/Requarks/wiki/pull/1900)
- [Docsify](https://www.npmjs.com/package/docsify-kroki)
- [Antora](https://antora.org/)

### Juliaで使う

[Kroki.jl](https://bauglir.github.io/Kroki.jl/stable/)を使うと、Documenter.jlやJupyterで使えます。セルフホスト、kroki.ioのいずれも選べます。
開発のモチベーションを示した[JuliaCon 2020 Joris Kraak氏のLT資料](https://live.juliacon.org/uploads/posters/M8KTBL.pdf)も上がっていました。以下に抜粋します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/c661b777-988b-4b32-2237-ea08ae35157a.png)


### VSCodeプラグインで使う

プラグインを使い、インラインに記述することで、図表混じりの文書を容易に作れます。以下それぞれ、デフォルトではkroki.ioを使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/bd68ae22-7cbb-545d-fda0-0e9d64d5dc04.png)

- AsciiDoc
    - 参考: [VSCode で Asciidoc を使ってテキストデータでダイアグラムを組む - Qiita](https://qiita.com/Anubis_369/items/04d26befab6e92cc55bb)
- Marp
    - 参考: [【VS Code + Marp】Markdownから爆速・自由自在なデザインで、プレゼンスライドを作る - 外部ツールの図表を取り込む](https://qiita.com/tomo_makes/items/aafae4021986553ae1d8#%E5%A4%96%E9%83%A8%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AE%E5%9B%B3%E8%A1%A8%E3%82%92%E5%8F%96%E3%82%8A%E8%BE%BC%E3%82%80)

### 記法について

図表生成のAPIは統一されていますが、元々は図表生成エンジンの寄せ集めであるため、生成したい図表ごとの、簡単な文法には習熟する必要があります。それらは各エンジンの公式ドキュメント等を参照します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/4a7a7ded-48b3-3764-7061-b4cd8060bc69.png)


大きくわけて、上図にあるように、3カテゴリの記法があります。

- アスキーアート系
- 要素記述系
- データ可視化系

基本は、要素記述系であり、

- グラフ構造であればノードとリーフをどのようなネスト構造で規定する
- それぞれの要素に見た目のアレンジを加えていく

という構造をしています。

どの図表も数回書けば頭に入る、またはテンプレートを元に容易に書き始められるものです。



## Kroki以外のDiagram as Codeやその先とのつながり

図表は、UML、C4、プロジェクト管理といった領域に止まりません。私はビジュアルプログラミングまで含め、可視化全般が好きなので、Kroki「以外」の領域を、勢い余って紹介します。

### クラウドコンピュータアーキテクチャ 

[diagrams](https://github.com/mingrammer/diagrams)を使うと、様々なクラウドアーキテクチャダイアグラムを、Python/ Graphvizレンダリングで記述できます。


### 数学関連の図表

SIGGRAPH2020で、[Penrose: from mathematical notation to beautiful diagrams](https://penrose.ink/siggraph20.html)というプロジェクトが発表されました。論文の中身も、Haskellベースという実装も面白いです。
参考: [数式からいい感じに図表が生成できてしまう! Penroseを試す (SIGGRAPH 2020) - Qiita](https://qiita.com/tomo_makes/items/5f88c32b4c2f2f33da92)

### データ可視化

Vega-liteの豊富な事例が[ここ](https://qiita.com/tomo_makes/items/4d69f347a5e49346df37#observable%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF-javascript)に、Observableで紹介されています。
参考: [【JS/ Python両方OK!】「データ可視化」が歴史から実装まで体系的に学べるStanford講座の独習ノート - Qiita](https://qiita.com/tomo_makes/items/4d69f347a5e49346df37)

### ネットワーク可視化

前述のネットワーク「構成」図ではなく、ノードとエッジから成る、抽象化されたネットワークの表現方法です。[Cytoscape.js](https://js.cytoscape.org/)がおすすめです。

### 地図などGIS可視化

[Mapbox GL](https://www.mapbox.com/mapbox-gljs)のように、WebGLを生かし、地図表示フレームワークが進化しています。Uber発の[deck.gl](https://deck.gl/)は、そこに大規模データを簡単に重畳表示、可視化できます。

### 手描き図表とDiagram as Codeを繋ぐアプローチ

[Structurizr](https://structurizr.com/)は、テキストからの図表生成と共に、手描き図表へのアノテーション、レビュー機能を有しています。どこまでを手描きで済ませる、どこまでをちゃんとした図表とするか、といった境界の難しさへの一つの解決方法です。

### コードの構造、フロー可視化

[Sourcetrail](https://www.sourcetrail.com/)のオープンソース化は話題となりました。ソースコードから、ブラウズしやすく、ライブラリの依存関係などの可視化を生成します。図表とコードを行き来できます。また、言語特化では、Rに[flow](https://github.com/moodymudskipper/flow)というライブラリがあり、処理フローを可視化し把握しやすくしてくれます。これに類するものとしては、[深層学習系でのモデル構造可視化](https://www.tensorflow.org/tensorboard/graphs?hl=ja)も挙げられます。


### それ以外のリスト

[Online Text to Diagram Tools_Github - MdEditor](https://www.mdeditor.tw/pl/pIVn)に、こちらでの紹介と重なるものもありますが、網羅的なリストがあります。

### ビジュアルプログラミング

ここまでは、テキストやコードからの図表生成でした。逆に「図表」「ダイアグラム」からコードを生成する、というアプローチがあります。ビジュアルプログラミングです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64608/01d11bb1-06d2-af8d-dfc4-2c8cdb77e92b.png)

> 出典: [ビジュアルプログラミング言語を俯瞰する(ScratchからNode-RED、TouchDesignerやIFTTTまで) - Qiita](https://qiita.com/tomo_makes/items/c193d4fc89e6eb4a245d)

## 余談

開発元は、アイコンも可愛らしい「ゆずテック」 https://github.com/yuzutech というフランスの会社です。つられてKrokiも「黒木？」とぼんやり読んでたら、「クロッキー（速描）」のことみたいです。

数多くのエンジンのゲートウェイ的な機能を提供しているため、困難な点が出てくるかもしれません。ただ、今のところ各エンジンのバージョン追随等、こまめにメンテナンスされている様子が[GitHubのPR](https://github.com/yuzutech/kroki/pulls)からも伺えます。

永く続くプロジェクトになるよう、利用者の立場でも支援をしていきたい所です。