D2入門:Text-To-Diagram言語で図を作成する方法 まとめ
D2とは何か
D2はDeclarative Diagramming(宣言的ダイアグラミング)の略称で、テキストからダイアグラム(図)を生成できる新しいドメイン固有言語(DSL)です。
2022年11月22日にオープンソース化され、MPL-2.0ライセンスで公開されました。開発元はTerrastruct社で、実装言語はGoです。公開から日が浅いながらも2024年時点でGitHubスター数が16kを超えるなど注目を集めており、Windows・macOS・LinuxはもちろんWebブラウザ上(WASM経由)でも動作するクロスプラットフォーム対応のツールです。
従来のPlantUMLやMermaidと同様、D2を使うとシステム構成図やクラス図、ER図、シーケンス図など様々な図をテキストベースで記述できます。
エンジニア向けに設計されており、手作業で図形を配置したり線を引いたりする代わりに、関係性や構造をコードで宣言するだけで自動的にレイアウトされた図が得られるのが特徴です。
記法(シンタックス)は比較的シンプルで難解さはなく、少し学習すれば直感的に扱えるでしょう
他の言語と比べたメリット
テキストから図を描くツールは既にPlantUMLやMermaidなどがありますが、D2にはそれらと比べて次のようなメリットがあります。
-
記法がシンプルで直感的: D2のDSLは複雑すぎず理解しやすい構文になっています 。例えばオブジェクト同士の関係は矢印(
->
など)で表現するだけなので、読み書きが容易です。 - エラーメッセージが親切: 記述に誤りがあった場合、D2は単に"syntax error"という表示だけではなく、何行目のどの位置にエラーがあるかまで具体的に指摘してくれます。デバッグが容易なため初心者でも安心です。
- 画像やアイコンの埋め込み: ノード(要素)として任意のURLから画像やアイコンを直接挿入できます。PlantUMLではアイコンフォント(FontAwesome)のみ、Mermaidでは画像埋め込みが限定的ですが、D2ではウェブ上の好きな画像を図中に取り込めます。
- Markdown記法のサポート: ノードのラベルなどにMarkdown形式の装飾を利用でき、テキストを太字やコードブロック表示することが可能です。これにより図中の表現力が向上します。
- コードスニペットと自動整形: D2は図中にコードブロック(コードスニペット)を組み込む機能や、記述したソースを自動フォーマット(整形)する機能も備えています。ソースコードを見やすい形に保ちつつ図を管理できます。
- 単一バイナリで動作: D2は単体のコマンドラインツール(バイナリ)として提供されるため動作が軽量です。Java実行環境が必要なPlantUMLや、ブラウザ環境に依存するMermaidに比べ、導入やCIへの組み込みが容易です。
以上の特徴から、D2はモダンで拡張性が高く、実用的なText-to-Diagramツールと言えます。特にエラー表示の親切さやリッチなノード表現(画像・Markdown対応)は、既存ツールにない利点です。
インストール方法 (macOS + Homebrew)
macOS環境でD2を使ってみるには、Homebrew経由でのインストールが手軽です。Homebrewが既にインストール済みであることを前提に、以下の手順でセットアップできます。
-
ターミナルを開き、D2をHomebrewでインストールします(macOSではbrewコマンドで導入可能です)。
brew install d2
上記コマンドにより、必要なバイナリがダウンロード・配置されます。
-
インストール完了後、バージョン確認を行います。
d2 --version
実行結果としてv0.x.y
のようにバージョン番号が表示されれば成功です。例えばv0.6.9
と表示されれば、D2バージョン0.6.9が正しくインストールされています。
Homebrew以外にも公式のインストールスクリプト(curl -fsSL https://d2lang.com/install.sh | sh
)や、Go言語によるインストール(go install oss.terrastruct.com/d2@latest
)など様々な方法が提供されています)。
しかしHomebrewを利用できる環境では上記のようにワンコマンドで導入できるため、初心者にはHomebrew経由が推奨です。
D2の主要機能
ここからはD2の主要な機能について、コンポーネント図を作成する上で知っておきたいポイントを解説します。D2では基本的に「ノード(要素)」「エッジ(接続線)」をテキストで定義し、必要に応じてクラスタ(グループ化)やカスタマイズを行います。
クラスタ(コンテナ)によるグループ化
複数のノードを**クラスタ(cluster)**としてひとまとまりにできます。クラスタはD2では「コンテナ」とも呼ばれ、ノードを入れ子構造で記述するか、ドット区切りのキー名で階層を表現します。
-
波括弧
{ }
を使った記法: 波括弧の中にインデントしてノードを書くことで、コンテナを定義します。例えば以下のコードはapp
というコンテナ内にfrontend
とbackend
というノードをグループ化しています。app: { frontend: フロントエンド backend: バックエンド frontend -> backend }
上記のように記述すると、**コンテナ「app」**の中に「フロントエンド」と「バックエンド」の2つのノードが含まれ、
frontend -> backend
という矢印がコンテナ内部で引かれます。この構文により入れ子のマップ(階層構造)を簡潔に表現できます。]
コンテナ自体にラベルを付けたい場合は、キー名の後ろにコロンとラベルを書くか、コンテナ内でlabel:
フィールドを指定します。
例えばapp: システム { ... }
のように記述すればコンテナ名として「システム」と表示できます。
-
ドット区切りの記法: 1行で「コンテナ名.ノード名」のように書くことでも、ノードをグループ化できます。
server # コンテナserverを定義 server.process # serverコンテナ内にprocessノードを定義
このようにピリオドで繋ぐと、server
の中にprocess
という子ノードができたとみなされます。
複数階層もparent.child.grandchild
のように記述可能です。
いずれの方法でもコンテナを作成できますが、入れ子が深くなる場合は波括弧記法の方が見通しが良いでしょう。コンテナ内の要素を外部から参照する際は、コンテナ名.ノード名
のようにドットで繋いで指定します(例:users -> app.frontend
)。このクラスタ機能によって、システムのサブシステムやモジュールを一段抽象化して表現することができます。
ノードのカスタマイズ
D2ではノードごとに形状や見た目を柔軟に変更できます。ノードはデフォルトでは長方形ですが、shape
プロパティを指定することで様々なアイコンや図形に変更可能です。使える Shape
の一覧
-
形状(シェイプ)の変更: 用意されている形状には長方形の他、円(円形)、楕円、雲(クラウド)、円柱(データベースのアイコン)、人のアイコンなど多数あります。例えばデータベースを表すノードには円柱シェイプを設定できます。
db: データベース db.shape: cylinder # ノード「データベース」を円柱アイコンに user: ユーザー user.shape: person # ノード 「ユーザー」を人型アイコンに
上記のようにノード名.shape: 形状名
と記述するだけで、そのノードの描画が指定のアイコンに変わります。cylinder
は典型的なデータベースの円柱アイコンで表示されます。
同様にperson
を指定すれば人型のシンボルで描画され、ユーザーや人物を表現するのに便利です 。
-
画像アイコンの挿入:
shape: image
を指定し、icon
プロパティに画像URLを与えることで、任意の画像をノードのアイコンとして使用できます。web: Web Server web.shape: image web.icon: https://icons.terrastruct.com/infra/019-network.svg
上記ではネットワークのアイコン画像(Terrastruct社提供のフリーアイコン)URLを指定し、ノード
web
にその画像を表示させています 。このようにインターネット上の画像も直接利用できる点がD2の強力な機能です。 -
スタイルの変更: ノードや接続線には色や線の種類などスタイルを設定することも可能です。例えば
ノード名.style.fill
で塗りつぶし色、ノード名.style.stroke
で枠線の色を指定できます 。db: データベース db.shape: cylinder # ノード「データベース」を円柱アイコンに db.style.fill: red # ノード「データベース」の色を赤に db.style.stroke: black # ノード「データベース」の枠線を黒に
デフォルトのテーマから企業ブランドに合わせた配色に変えることも容易です。
(詳細は公式ドキュメントのCustomization参照)。
接続の記述方法
ノード同士の**関係(エッジ、矢印)**は、記号を使って直感的に記述できます。D2ではハイフンと不等号を組み合わせて4種類の線を表現します。
A -> B: リクエスト # AからBへの矢印(片方向)+「リクエスト」というラベル
C <- D # DからCへの矢印(片方向、向きが逆)
E <-> F # EとFを両方向矢印で接続(双方向)
G -- H # GとHを単なる線で接続(矢印なし、無方向)
上記のように、--
は矢印なしの単純な線、->
は右向き矢印、<-
は左向き矢印、<->
は両端に矢印を持つ線を表します。
ノード名の後にコロンとテキストを続けることで、接続線にラベル(説明文)を付与できます。
例えばA -> B: リクエスト
と書けば、AからBに伸びる矢印の上に「リクエスト」と文字が表示されます。
接続の宣言順序は自由で、ノードを先に宣言してから矢印を書くことも、矢印の記述によってノードを暗黙的に定義することもできます。D2では接続定義中に新しいキーが登場した場合、自動的にそれをノードとして扱います。
そのためシンプルな図であれば、あらかじめ全ノードを羅列しなくても矢印の関係だけを書いてしまって構いません。
また、矢印の向きはレイアウトエンジンによって自動調整されますが、->
と書いた場合は概念的に「AからBへ」の関係性を示します。双方向の関連がある場合は<->
を使うなど、関係性に応じて適切な矢印を選択してください。
簡単なダイアグラムの例
それでは、D2を使って実際にコンポーネント図を作る手順を簡単な例で見てみましょう。
シンプルな図の例
まずは最もシンプルなダイアグラムです。例えば以下のD2スクリプトを用意します。
A: 第一コンポーネント
B: 第二コンポーネント
A -> B: 初めての図
このコードでは、「第一コンポーネント」と「第二コンポーネント」という2つのノードAとBを定義し、AからBへ「初めての図」というラベル付きの矢印を引いています。D2を実行してこのファイルをレンダリングすると、AからBへ矢印が伸びたシンプルな図が生成されます。ノードには日本語のラベル(第一コンポーネント/第二コンポーネント)が付いており、テキストはそのまま図中に表示されます。D2はマルチバイト文字(日本語など)もサポートしているため、母国語でわかりやすく要素名を記述できます。
出力された図は、長方形のノード2つと、その間に「初めての図」と書かれた矢印という構成になります。
非常に簡単ですが、テキストからこのような図を自動で描画してくれるのがD2の基本的な動作です。
少し複雑なコンポーネント図の例
次に、もう少し複雑なコンポーネント図の例に挑戦してみましょう。ここでは「ユーザーがウェブシステムを利用し、バックエンドでデータベースにアクセスする」というシナリオを図にします。D2コードとその解説は以下の通りです。
direction: right # レイアウトを横方向にする
# ノードの定義とクラスタ
user: ユーザー
user.shape: person # ユーザーは人型アイコンで表現
db: データベース
db.shape: cylinder # データベースは円柱アイコンで表現
system: システム { # システム全体を表すクラスタ(コンテナ)
web: Webサーバー
web.shape: rectangle # Webサーバーは長方形ノード
api: APIサーバー
api.shape: rectangle # APIサーバーも長方形ノード
}
# 接続の定義
user -> system.web: リクエスト # ユーザーからWebサーバーへの矢印(ブラウザリクエスト)
system.web -> system.api: API呼び出し # WebサーバーからAPIサーバーへの矢印
system.api -> db: クエリ # APIサーバーからデータベースへの矢印(クエリ)
このスクリプトでは以下の構成要素を定義しています。
-
ユーザー (
user
): 人物を表すノードで、shape: person
を指定して人型のアイコンで描画しています。これにより、ユーザー役のノードが視覚的に人のシンボルになります -
データベース (
db
): データの保管庫を表すノードで、shape: cylinder
により円柱(データベース)アイコンになります。 -
システム (
system
): コンテナ(クラスタ)として定義され、ラベル「システム」が付けられています。中に**Webサーバー (web
)とAPIサーバー (api
)**の2つのノードを含みます。両ノードともshape: rectangle
(長方形)で一般的なサーバーの箱を表現しています。 -
接続関係: ユーザーからWebサーバーへの「リクエスト」、WebサーバーからAPIサーバーへの「API呼び出し」、APIサーバーからデータベースへの「クエリ」という3つの矢印を定義しています。クラスタ内の
web
やapi
ノードを参照する際にはsystem.web
のようにクラスタ名を付けて指しています。
このコードをD2で描画すると、左側にユーザー(人型アイコン)、中央に「システム」という枠で囲まれたクラスタ(中に「Webサーバー」と「APIサーバー」のノードが配置)、右側にデータベース(円柱アイコン)が配置された図が生成されます。それぞれの間は矢印で結ばれ、ユーザーからシステム(Webサーバー)への矢印には「リクエスト」、システム内のWeb→API矢印には「API呼び出し」、APIサーバーからデータベースへの矢印には「クエリ」とラベルが表示されます。
このようにD2を用いると、**システム構成(コンポーネント間の関係)**をテキストで表現し、わかりやすい図として出力できます。クラスタ機能でグループ化することで、システム内外の関係性も明確に表現できました。
まとめ
本記事では、新しいText-To-Diagram言語であるD2の概要から、他ツールとの比較、基本的な使い方や機能、そしてコンポーネント図の具体例までを解説しました。テキストを書く感覚で図を描けるD2は、設計書やドキュメントにおける図作成のハードルを下げてくれる存在です。
実際に使ってみた印象として、記法の習得は比較的容易で短時間で思い通りの図が描けました。PlantUMLやMermaidに慣れた方でも、D2のシンプルさと拡張性は十分魅力的に感じられるでしょう。特に感じたメリットは、図やアイコンをURL経由で簡単に挿入できる柔軟さで、これにより図の表現力が飛躍的に高まります。また、エラー箇所が詳細に示されるため試行錯誤がしやすく、ライブプレビュー(d2 --watch
コマンド)を使えばリアルタイムに描画を確認しながら編集できるのも便利でした。
D2は登場したばかりのツールですが積極的にメンテナンスが続けられており、新機能の追加も活発です。そのため将来的な拡張にも期待が持てます。現時点でもアーキテクチャ図やネットワーク構成図などを手軽に描け、Terraformなどのインフラコードや設計資料と組み合わせて利用するといった活用シーンが考えられます。
手作業の描画が苦手な場合でもテキストさえ書ければ図を書けるので、「描画ツールは苦手だけど構成を図にしたい」という場面でD2は強い味方になりそうです。
ぜひ皆さんもD2をインストールして、簡単な図から試してみてください。コードで管理できる図表はバージョン管理や再利用も容易で、プロジェクトドキュメンテーションの効率化に役立つはずです。シンプルながら強力なD2の機能を活用し、テキストから美しいコンポーネント図を生成してみましょう。
Discussion