テキストベースの図、もっと表現力が欲しい
ども!PlantUML × VS Codeの記事を書いた龍ちゃんです。
Claude Codeを使って爆速でPlantUMLを書けるようになりました。でも!実際に設計書やブログに貼るとなると「もうちょっと見た目をなんとかしたい」ってなるんですよね。図の横に設計ポイントを添えたり、色を揃えて見やすくしたり。
そこで今回は、PlantUMLの図にTailwind CSSの装飾を組み合わせます。1つのHTMLファイルにPlantUML図 + 注釈パネルをまとめて、PNGに変換する仕組みです。
「なんでPlantUML?」理由はシンプルで、Mermaidではカバーできない図があるからです。
- コンポーネント図 —
database "PostgreSQL"と書くだけであのドラム型DBアイコンが出る - アクティビティ図 — ワークフローの分岐・マージを
if/else/endifで描ける - ユースケース図 —
actor "ユーザー"で棒人間アイコンが出る
Mermaidはフロー図やシーケンス図が得意ですけど、この3つは守備範囲外なんですよね。PlantUMLならテキストベースのまま作れます。
Mermaid × Tailwind CSSの組み合わせも同時に記事にしてます。フロー図やシーケンス図を作りたい人は「Mermaid × Tailwind CSS — ハイブリッド図解の作り方」をどうぞ。
今回の内容です。
- コピペ用テンプレート2種(右サイド注釈型 / 左右均等型)
- PNG変換の手段3つ
関連記事: 仕様書の図にソースコードと設計意図を添える方法については「仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン」で詳しく書いてます。AIに図の構造を正確に伝えたい人はこちらもどうぞ。
テンプレートA: 右サイド注釈型
コピペして使えるHTMLテンプレートを2種類用意しました。
仕組みはシンプルで、plantuml-encoderというライブラリでPlantUML構文をエンコードしてplantuml.comに投げるだけです。Tailwind CDNとの共存も問題なし。テンプレートをコピペすればそのまま動きます。plantuml.comへの通信が発生するのでネット接続は必要ですが、大抵の開発環境では問題にならないです。
まずはテンプレートA。左にPlantUMLで描画したコンポーネント図、右にTailwind CSSで装飾した注釈パネルを並べるレイアウトです。ドラム型のDB記号やキュー記号が見えるのがPlantUMLならではのポイントですね。
向いてる場面: 横に広がる図(コンポーネント図、シーケンス図)に設計ポイントを3-4個添えたいとき
キャンバスサイズ: 1280x720px

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>コンポーネント図: 3層アーキテクチャ</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/plantuml-encoder@1.4.0/dist/plantuml-encoder.min.js"></script>
<style>
body {
width: 1280px;
height: 720px;
margin: 0;
padding: 0;
background: white;
overflow: hidden;
}
</style>
</head>
<body class="p-8">
<div class="h-full flex flex-col">
<!-- タイトル -->
<h1 class="text-2xl font-bold mb-6 text-gray-800">コンポーネント図: 3層アーキテクチャ</h1>
<!-- メインコンテンツ: 2カラム -->
<div class="flex gap-6 flex-1">
<!-- 左: PlantUML図 -->
<div class="flex-1 flex flex-col">
<div class="bg-blue-50 border-2 border-blue-300 rounded-lg p-4 flex-1 flex items-center justify-center">
<div id="diagram-container" class="flex items-center justify-center">
<p class="text-gray-500">Loading diagram...</p>
</div>
</div>
</div>
<!-- 右: 注釈パネル -->
<div class="w-72 flex flex-col gap-4">
<div class="bg-yellow-50 border border-yellow-300 rounded-lg p-4">
<h3 class="font-bold text-yellow-800 mb-2">フロントエンド層</h3>
<p class="text-sm text-yellow-900">Web・モバイルの2系統。APIゲートウェイを経由して統一的にアクセス</p>
</div>
<div class="bg-blue-50 border border-blue-300 rounded-lg p-4">
<h3 class="font-bold text-blue-800 mb-2">バックエンド層</h3>
<p class="text-sm text-blue-900">認証・記事・通知をマイクロサービスに分離。ゲートウェイでルーティング</p>
</div>
<div class="bg-green-50 border border-green-300 rounded-lg p-4">
<h3 class="font-bold text-green-800 mb-2">データ層</h3>
<p class="text-sm text-green-900">PostgreSQL + Redis + メッセージキューの3点セット。非同期処理はキュー経由</p>
</div>
</div>
</div>
</div>
<script>
window.addEventListener('DOMContentLoaded', function() {
const umlSource = `@startuml
skinparam style strictuml
skinparam backgroundColor transparent
package "フロントエンド" {
[Webアプリ] as Web
[モバイルアプリ] as Mobile
}
package "バックエンド" {
[APIゲートウェイ] as GW
[認証サービス] as Auth
[記事サービス] as Article
[通知サービス] as Notify
}
package "データ層" {
database "PostgreSQL" as DB
database "Redis" as Cache
queue "メッセージキュー" as MQ
}
Web --> GW
Mobile --> GW
GW --> Auth
GW --> Article
Article --> DB
Article --> Cache
Article --> MQ
MQ --> Notify
Auth --> DB
@enduml`;
try {
const encoded = plantumlEncoder.encode(umlSource);
const imgUrl = `https://www.plantuml.com/plantuml/svg/${encoded}`;
const container = document.getElementById('diagram-container');
container.innerHTML = `<img src="${imgUrl}" alt="コンポーネント図" class="max-w-full max-h-full" />`;
} catch (error) {
console.error('Error encoding PlantUML:', error);
document.getElementById('diagram-container').innerHTML =
`<p class="text-red-500">Failed to load diagram: ${error.message}</p>`;
}
});
</script>
</body>
</html>差し替えは3箇所だけです。
- PlantUML構文(
const umlSourceの中身)を自分の図に差し替える - 注釈パネルの内容(右側の3つのパネル)を自分の設計ポイントに差し替える
- タイトルを差し替える
注釈パネルは増減しても大丈夫です。3個が収まりいいですけど、2個でも4個でもレイアウトは崩れません。
skinparamについて
Mermaid編では themeVariables で図の配色をTailwindのカラーパレットに合わせましたね。PlantUMLでは skinparam が同じ役割です。
skinparam style strictuml
skinparam backgroundColor transparentbackgroundColor transparent で背景を透明にするだけで、Tailwind側の bg-blue-50 と自然に馴染みます。追加で色をカスタマイズしたい場合はこんな設定もあります。
skinparam packageBackgroundColor #f0f9ff
skinparam ArrowColor #3b82f6
skinparam ParticipantBackgroundColor #dbeafeMermaidの themeVariables ほど細かい制御はできないですけど、背景透明にするだけで大抵は十分です。もっと細かく調整したい人はPlantUML公式のskinparamリファレンスを参照してください。
PlantUML固有の記法
テンプレートのコードで使ってる記法と、他の図で使える記法をまとめておきます。
テンプレートAで使用:
| 記法 | 表示 |
|---|---|
database "名前" | ドラム型DB記号 |
queue "名前" | キュー型記号 |
package "名前" { ... } | パッケージでグループ化 |
他の図で使える記法:
| 記法 | 用途 |
|---|---|
== フェーズ名 == | シーケンス図のフェーズ分割 |
alt / else / end | 条件分岐ブロック |
ref over A, B | 外部参照 |
left to right direction | ユースケース図の横向きレイアウト |
テンプレートB: 左右均等型
テンプレートAだと、縦長の図のときに左側のスペースが余ります。アクティビティ図やユースケース図は縦に伸びるんで、横幅を半々にして右側に説明を置くほうが収まりがいいです。
向いてる場面: 縦長の図(アクティビティ図、ユースケース図)に説明を横に並べたいとき
キャンバスサイズ: 1280x720px

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>アクティビティ図: ユーザー登録フロー</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/plantuml-encoder@1.4.0/dist/plantuml-encoder.min.js"></script>
<style>
body {
width: 1280px;
height: 720px;
margin: 0;
padding: 0;
background-color: white;
overflow: hidden;
}
</style>
</head>
<body class="flex">
<!-- 左: PlantUML図 -->
<div class="w-1/2 flex items-center justify-center p-8">
<div id="diagram-container"></div>
</div>
<!-- 右: 注釈パネル -->
<div class="w-1/2 flex flex-col justify-center p-8 space-y-6">
<h1 class="text-3xl font-bold text-gray-800 mb-4">ユーザー登録フロー</h1>
<div class="bg-yellow-100 border-l-4 border-yellow-500 p-4">
<p class="text-gray-800 font-semibold">バリデーション</p>
<p class="text-sm text-gray-600 mt-1">フォーム入力後、サーバー側でバリデーション。失敗時はエラーメッセージを表示してフォームに戻す</p>
</div>
<div class="bg-blue-100 border-l-4 border-blue-500 p-4">
<p class="text-gray-800 font-semibold">DB保存とリトライ</p>
<p class="text-sm text-gray-600 mt-1">保存失敗時はエラーログを記録してリトライ画面を表示。ユーザーに再試行の機会を与える</p>
</div>
<div class="bg-green-100 border-l-4 border-green-500 p-4">
<p class="text-gray-800 font-semibold">完了通知</p>
<p class="text-sm text-gray-600 mt-1">保存成功時は完了メールを送信してから完了画面を表示。メール送信は非同期でもOK</p>
</div>
</div>
<script>
window.addEventListener('DOMContentLoaded', () => {
const plantUmlSource = `@startuml
start
:ユーザーがフォームを入力;
if (バリデーション?) then (成功)
:データベースに保存;
if (保存成功?) then (はい)
:完了メールを送信;
:完了画面を表示;
else (いいえ)
:エラーログを記録;
:リトライ画面を表示;
endif
else (失敗)
:エラーメッセージを表示;
:フォームに戻る;
endif
stop
@enduml`;
const encoded = plantumlEncoder.encode(plantUmlSource);
const img = document.createElement('img');
img.src = `https://www.plantuml.com/plantuml/svg/${encoded}`;
img.alt = 'アクティビティ図: ユーザー登録フロー';
img.className = 'max-w-full max-h-full';
document.getElementById('diagram-container').appendChild(img);
});
</script>
</body>
</html>差し替えポイントはテンプレートAと同じ3箇所です。PlantUML構文、注釈パネル、タイトル。実例はアクティビティ図ですけど、ユースケース図を作りたい場合も const plantUmlSource の中身を差し替えるだけです。
テンプレートAとの違いは2つです。
- レイアウトが左右均等(
w-1/2+w-1/2)。図と注釈が50:50で並ぶんで、縦長の図に余裕ができます - 注釈のスタイルが
border-l-4(左ボーダーアクセント)。テンプレートAのカード型とは雰囲気が変わります
Mermaid編のテンプレートBは縦拡張(1280x1080px)でしたけど、PlantUML編は標準の1280x720pxです。PlantUMLはサーバー側で描画するんで、Mermaidの自動縮小問題がない。CSS transformも不要です。
テンプレート使い分け
| 条件 | テンプレート |
|---|---|
| 横に広がる図(コンポーネント図、シーケンス図) | A: 右サイド注釈型 |
| 縦長の図(アクティビティ図、ユースケース図) | B: 左右均等型 |
| 注釈が少ない(2-3個) | A |
| 注釈にテキストが多い | B |
迷ったらテンプレートAで試して、図が窮屈ならBに切り替えてください。
PNG変換 — 3つの手段
手段は3つあります。好みと環境に合わせて選んでください。
| 手段 | 自動化 | セットアップ | 向いてる用途 |
|---|---|---|---|
| CLIツール(html-screenshot) | できる | Python + Playwright | 量産やCI/CD |
| Playwright MCP | できる | MCP設定 | Claude Code連携 |
| ブラウザで直接開く | 手動 | なし | 手軽に確認 |
CLIツール
uv run html-screenshot --file template-a.html --output template-a.png
以前の記事で紹介したhtml-screenshotツールがそのまま使えます。Playwrightの wait_until="networkidle" がplantuml.comからのSVG取得完了を待ってくれるんで、PlantUML図の描画が終わってからスクリーンショットを撮ってくれます。
Playwright MCP
Claude CodeからPlaywrightのブラウザ操作を直接呼び出す方法もあります。HTMLファイルを開いてスクリーンショットを撮る操作がMCPのツールで完結します。Playwright MCPの記事で詳しく書いてるんで、Claude Code使ってる人はこっちが楽です。
ブラウザで直接開く
一番手軽なのはHTMLファイルをブラウザで直接開くことですね。Tailwind CDNとplantuml-encoder CDNが読み込まれて、PlantUML図がそのまま描画されます。PNG変換は手動(DevToolsやOS標準のスクリーンショット)になりますけど、「ちょっと確認したい」くらいならこれで十分です。
まとめ
Mermaid編のテンプレート2種 + 今回のPlantUML編テンプレート2種で、計4種類が揃いました。
| テンプレート | 図の描画 | 向いてる図 |
|---|---|---|
| Mermaid A: 右サイド注釈型 | Mermaid | フロー、シーケンス、状態遷移 |
| Mermaid B: 下部グリッド注釈型 | Mermaid | 複雑なシーケンス |
| PlantUML A: 右サイド注釈型 | PlantUML | コンポーネント、シーケンス |
| PlantUML B: 左右均等型 | PlantUML | アクティビティ、ユースケース |
フロー図、シーケンス図、状態遷移図に加えて、アクティビティ図、ユースケース図、コンポーネント図もカバーできるようになりました。特にコンポーネント図の database でドラム型DBアイコンが出せるのは、アーキテクチャ図を書く人にはかなり便利です。
おまけとして、Mermaid編でも触れましたがこのテンプレートで作った図はAI連携にも使えます。PlantUMLもMermaidと同じく宣言的記法なんで、AIが構造を正確に読み取れます。注釈パネルに設計意図を書いておけば、人間が見ても、AIが読んでもどっちにも伝わる。この辺の話は仕様書の図にソースコードを添える設計パターンで詳しく書いてます。
もう1つ。このテンプレートを毎回コピペするのも手ですけど、Claude CodeのSKILL機能にreference(参考例)として登録しておくと、「シーケンス図作って」と言うだけでテンプレートに沿った図が出てきます。テンプレートのクオリティがそのままSKILLのクオリティになるんで、良いテンプレートを貯める = 図解の品質を底上げする、という流れができます。コピペ用テンプレートとSKILL化、好きなほうで使ってください。
ほなまた〜
関連ブログ
今回の記事はシリーズの一部です。
- Mermaid × Tailwind CSS — ハイブリッド図解の作り方
— 今回の前編。Mermaid + Tailwind CSSのテンプレート2種を紹介してます。まだ読んでない人はこちらから。 - ClaudeでMermaid図作成を自動化!プロンプトテンプレート集も公開
— シリーズの出発点。Mermaid記法をAIで生成するところから始めたい人はここから。 - 図解作成、AIに丸投げしたら「たまに自分より上手い」件
— HTML+Tailwind CSSで図解を丸ごとAIに作らせる方法。フロー図以外の図解(比較図、アーキテクチャ図とか)はこっちが向いてます。 - 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン
— 仕様書をAIと共有してるチーム向け。図にソースコードと設計意図を添えて、AIの「推測」をなくす方法です。 - Claude CodeでPlantUML × VS Code Preview
— PlantUMLの基礎とVS Codeでのプレビュー設定。PlantUML自体が初めての人はこちらが入門になります。 - Playwright MCPで始めるブラウザ自動化
— PNG変換の手段の1つとして紹介したPlaywright MCP。Claude Codeからブラウザ操作を直接呼び出せます。


