mcpField
E
excalidraw-diagrams

excalidraw-diagrams

github.com/robtaylorデザイン・UI2997 回インストール42 週間前に更新
リポジトリ

excalidraw-diagrams について

excalidraw-diagramsは、Pythonで編集可能なExcalidraw図をJSONファイルとして生成するスキルです。汎用図、フローチャート、アーキテクチャ図のAPIを備え、スタイル設定やPNG出力の手順も示します。

主な機能

  1. 01編集可能な.excalidrawファイルの生成
  2. 02自動配置対応のフローチャート作成
  3. 03システムアーキテクチャ図の作成
  4. 04色・線・テキストサイズの調整
  5. 05Playwrightを使ったPNG出力

活用シーン

  1. 01ドキュメント用の業務フローチャート作成
  2. 02システムの構成要素と接続関係の図示
  3. 03プレゼンテーション用の編集可能な図の作成
  4. 04文書に使う図画像のエクスポート

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/robtaylor/excalidraw-diagrams --skill excalidraw-diagrams

インストール後、Claude Code で/excalidraw-diagramsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
.gitignore
CLAUDE.md
LICENSE
.github/workflows/
release.yml
test-reusable-ci.yml
prompt-gallery.yml
ci.yml
scripts/
drive_helper.py
create_capability_zip.py
excalidraw_generator.py
package-lock.json
package.json
export_playwright.js
layout_engine.py
line_routing_validator.py
tests/
prompts.json
test_diagram_types.py
test_api_skill.py
test_generator.py
test_line_routing_validator.py
test_prompt_generation.py

詳細

Excalidraw ダイアグラムジェネレーター

このスキルは、Python を使用して Excalidraw ダイアグラムをプログラムで生成します。ASCII ダイアグラムを作成する代わりに、これを使ってプロフェッショナルな見た目の編集可能なダイアグラムを作成できます。

出力形式: .excalidraw JSON ファイル。以下が可能です:

  • https://excalidraw.com で開く(ファイルをドラッグ&ドロップ)
  • VS Code で Excalidraw 拡張機能を使って編集する
  • ドキュメントに埋め込む
  • SVG/PNG にエクスポートして Google Docs やプレゼンテーションなどに埋め込む

クイックスタート

方法 1: Python スクリプトを直接実行する(推奨)

ジェネレーターライブラリを使用して Python スクリプトを書き、実行します:

#!/usr/bin/env python3
import sys
import os
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import Diagram, Flowchart, ArchitectureDiagram

# Create your diagram
d = Diagram()
box1 = d.box(100, 100, "Step 1", color="blue")
box2 = d.box(300, 100, "Step 2", color="green")
d.arrow_between(box1, box2, "next")
d.save("my_diagram.excalidraw")

次のコマンドで実行します:

python3 /path/to/your_script.py
方法 2: Python をインラインで実行する
python3 -c "
import sys, os
sys.path.insert(0, os.path.expanduser('~/.claude/skills/excalidraw-diagrams/scripts'))
from excalidraw_generator import Diagram

d = Diagram()
a = d.box(100, 100, 'Hello', color='blue')
b = d.box(300, 100, 'World', color='green')
d.arrow_between(a, b)
d.save('hello.excalidraw')
print('Created: hello.excalidraw')
"

API リファレンス

Diagram クラス

すべてのダイアグラムの基底クラスです。

from excalidraw_generator import Diagram

d = Diagram(background="#ffffff")  # white background
メソッド

box(x, y, label, width=150, height=60, color="blue", shape="rectangle", font_size=18)

ラベル付きの図形を作成します。接続用の Element を返します。

  • x, y: 位置(左上隅)
  • label: 表示するテキスト
  • color: "blue"、"green"、"red"、"yellow"、"orange"、"violet"、"cyan"、"teal"、"gray"、"black"
  • shape: "rectangle"、"ellipse"、"diamond"
box1 = d.box(100, 100, "Process A", color="blue")
box2 = d.box(100, 200, "Decision?", color="yellow", shape="diamond")

text_box(x, y, content, font_size=20, color="black")

独立したテキストを作成します。

d.text_box(100, 50, "System Architecture", font_size=28, color="black")

arrow_between(source, target, label=None, color="black", from_side="auto", to_side="auto")

2 つの要素の間に矢印を描画します。

  • from_side、to_side: "auto"、"left"、"right"、"top"、"bottom"
d.arrow_between(box1, box2, "sends data")
d.arrow_between(box1, box3, from_side="bottom", to_side="top")

line_between(source, target, color="black")

要素間に線(矢印なし)を描画します。

save(path)

ダイアグラムを保存します。拡張子 .excalidraw が付いていない場合は追加されます。

d.save("output/my_diagram")  # Creates output/my_diagram.excalidraw

設定とスタイリング

ダイアグラムジェネレーターは、設定クラスを通じて幅広いカスタマイズをサポートしています。

DiagramStyle - 全体的な外観

ダイアグラム内のすべての要素の全体的な見た目を制御します:

from excalidraw_generator import Diagram, DiagramStyle

# Create a clean, professional diagram
d = Diagram(diagram_style=DiagramStyle(
    roughness=0,           # 0=clean, 1=hand-drawn, 2=rough sketch
    stroke_style="solid",  # "solid", "dashed", "dotted"
    stroke_width=2,        # Line thickness (1-4)
    color_scheme="corporate"  # Named color scheme
))

ラフネスレベル:

  • 0 - Architect: クリーンで正確な線
  • 1 - Artist: 通常の手描き風の見た目(デフォルト)
  • 2 - Cartoonist: ラフでスケッチ風の外観
カラースキーム

定義済みのスキームからセマンティックカラーを使用します:

# Available schemes: "default", "monochrome", "corporate", "vibrant", "earth"
d = Diagram(diagram_style=DiagramStyle(color_scheme="vibrant"))

# Get colors by role
primary = d.scheme_color("primary")     # Main components
secondary = d.scheme_color("secondary") # Supporting elements
accent = d.scheme_color("accent")       # Highlights
warning = d.scheme_color("warning")     # Caution states
danger = d.scheme_color("danger")       # Error states
neutral = d.scheme_color("neutral")     # Backgrounds, users

スキームのカラーマッピング:

スキームPrimarySecondaryAccentWarningDanger
defaultbluegreenvioletyellowred
monochromeblackgraygraygrayblack
corporatebluetealvioletorangered
vibrantvioletcyanorangeyellowred
earthtealgreenorangeyellowred
FlowchartStyle - フローチャートのカスタマイズ

フローチャートのノードの色とルーティングの動作をカスタマイズします:

from excalidraw_generator import Flowchart, FlowchartStyle

fc = Flowchart(flowchart_style=FlowchartStyle(
    start_color="cyan",      # Start node color
    end_color="red",         # End node color
    process_color="blue",    # Process node color
    decision_color="orange", # Decision diamond color
))
ArchitectureStyle - アーキテクチャ図のカスタマイズ
from excalidraw_generator import ArchitectureDiagram, ArchitectureStyle

arch = ArchitectureDiagram(architecture_style=ArchitectureStyle(
    component_color="blue",
    database_color="green",
    service_color="violet",
    user_color="gray",
))
BoxStyle - テキストボックスのサイズ設定

テキストボックスの自動サイズ設定を制御します:

from excalidraw_generator import Diagram, BoxStyle

d = Diagram(box_style=BoxStyle(
    h_padding=40,      # Horizontal padding (total)
    v_padding=24,      # Vertical padding (total)
    min_width=80,      # Minimum box width
    min_height=40,     # Minimum box height
    font_size=18,      # Default font size
    font_family="hand" # "hand", "normal", "code"
))

Flowchart クラス

自動配置を備えたフローチャートに特化したクラスです。

from excalidraw_generator import Flowchart

fc = Flowchart(direction="vertical", spacing=80)

fc.start("Begin")
fc.process("p1", "Process Data")
fc.decision("d1", "Valid?")
fc.process("p2", "Save")
fc.end("Done")

fc.connect("__start__", "p1")
fc.connect("p1", "d1")
fc.connect("d1", "p2", label="Yes")
fc.connect("d1", "__end__", label="No")

fc.save("flowchart.excalidraw")
メソッド
  • start(label="Start") - 緑の楕円
  • end(label="End") - 赤の楕円
  • process(node_id, label, color="blue") - 青の長方形
  • decision(node_id, label, color="yellow") - 黄のひし形
  • node(node_id, label, shape, color, width, height) - 汎用ノード
  • connect(from_id, to_id, label=None) - ノード間の矢印
  • position_at(x, y) - 次のノードの位置を設定します

AutoLayoutFlowchart クラス

自動階層レイアウトを備えた複雑なフローチャート向けです。grandalf パッケージが必要です。

from excalidraw_generator import AutoLayoutFlowchart, DiagramStyle, FlowchartStyle, LayoutConfig

fc = AutoLayoutFlowchart(
    diagram_style=DiagramStyle(roughness=0),  # Clean lines
    flowchart_style=FlowchartStyle(decision_color="orange"),
    layout_config=LayoutConfig(
        vertical_spacing=100,
        horizontal_spacing=80,
    )
)

# Add nodes with semantic types
fc.add_node("start", "Start", shape="ellipse", color="green", node_type="terminal")
fc.add_node("process1", "Validate Input", node_type="process")
fc.add_node("check", "Is Valid?", shape="diamond", color="yellow", node_type="decision")
fc.add_node("success", "Process Data", node_type="process")
fc.add_node("error", "Show Error", color="red", node_type="process")
fc.add_node("end", "End", shape="ellipse", color="red", node_type="terminal")

# Add edges (arrows)
fc.add_edge("start", "process1")
fc.add_edge("process1", "check")
fc.add_edge("check", "success", label="Yes")
fc.add_edge("check", "error", label="No")
fc.add_edge("success", "end")
fc.add_edge("error", "process1", label="Retry")  # Back-edge auto-routes through whitespace

# Compute layout and render
result = fc.compute_layout(
    two_column=True,           # Split tall diagrams into columns
    target_aspect_ratio=0.8,   # Target width/height ratio
)

fc.save("auto_flowchart.excalidraw")

ルーティング用のノードタイプ:

  • terminal - 開始/終了ノード
  • process - 標準的な処理ステップ
  • decision - 判断のひし形(矢印は側面から出ます)
メソッド
  • add_node(node_id, label, shape, color, width, height, node_type) - ノードを追加します
  • add_edge(from_id, to_id, label, color) - エッジを追加します
  • compute_layout(start_x, start_y, max_width, max_height, routing, two_column, target_aspect_ratio, column_gap) - ノードを自動配置します

ArchitectureDiagram クラス

システムアーキテクチャ図向けです。

from excalidraw_generator import ArchitectureDiagram

arch = ArchitectureDiagram()

# Add components at specific positions
arch.user("user", "User", x=100, y=200)
arch.component("frontend", "React App", x=250, y=200, color="blue")
arch.service("api", "API Gateway", x=450, y=200, color="violet")
arch.database("db", "PostgreSQL", x=650, y=200, color="green")

# Connect them
arch.connect("user", "frontend", "HTTPS")
arch.connect("frontend", "api", "REST")
arch.connect("api", "db", "SQL")

arch.save("architecture.excalidraw")
メソッド
  • component(id, label, x, y, width=150, height=80, color="blue")
  • database(id, label, x, y, color="green") - 楕円形
  • service(id, label, x, y, color="violet")
  • user(id, label="User", x=100, y=100) - 灰色の楕円
  • connect(from_id, to_id, label=None, bidirectional=False)

カラーリファレンス

利用可能な色(ストローク色、および対応する淡い背景色):

色ストロークの Hex用途
blue#1971c2主要なコンポーネント
green#2f9e44成功、データベース
red#e03131エラー、終了状態
yellow#f08c00警告、判断
orange#e8590cハイライト
violet#6741d9サービス
cyan#0c8599ネットワーク
teal#099268補助的な要素
gray#868e96ユーザー、アクター
black#1e1e1eテキスト、矢印

完全な例

例 1:シンプルなフロー
import sys, os
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import Diagram

d = Diagram()

# Title
d.text_box(200, 30, "Data Processing Pipeline", font_size=24)

# Boxes
input_box = d.box(100, 100, "Input", color="gray")
process = d.box(300, 100, "Process", color="blue")
output = d.box(500, 100, "Output", color="green")

# Arrows
d.arrow_between(input_box, process, "raw data")
d.arrow_between(process, output, "results")

d.save("pipeline.excalidraw")
例 2:判断フローチャート
import sys, os
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import Flowchart

fc = Flowchart(direction="vertical", spacing=100)

fc.start("User Request")
fc.process("auth", "Authenticate")
fc.decision("valid", "Valid Token?")

# Branch for Yes
fc.position_at(300, 340)
fc.process("proc", "Process Request")
fc.process("resp", "Return Response")

# Branch for No
fc.position_at(100, 340)
fc.process("err", "Return 401")

fc.connect("__start__", "auth")
fc.connect("auth", "valid")
fc.connect("valid", "proc", "Yes")
fc.connect("valid", "err", "No")
fc.connect("proc", "resp")

fc.save("auth_flow.excalidraw")
例 3:マイクロサービスアーキテクチャ
import sys, os
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import ArchitectureDiagram

arch = ArchitectureDiagram()

# Client layer
arch.user("client", "Client", x=400, y=50)

# Gateway
arch.service("gateway", "API Gateway", x=350, y=180, color="violet")

# Services row
arch.service("auth", "Auth Service", x=100, y=350, color="blue")
arch.service("users", "User Service", x=300, y=350, color="blue")
arch.service("orders", "Order Service", x=500, y=350, color="blue")
arch.service("notify", "Notification", x=700, y=350, color="cyan")

# Databases
arch.database("authdb", "Auth DB", x=100, y=500, color="green")
arch.database("userdb", "User DB", x=300, y=500, color="green")
arch.database("orderdb", "Order DB", x=500, y=500, color="green")

# Message queue
arch.component("queue", "Message Queue", x=600, y=450, color="orange")

# Connections
arch.connect("client", "gateway", "HTTPS")
arch.connect("gateway", "auth", "gRPC")
arch.connect("gateway", "users", "gRPC")
arch.connect("gateway", "orders", "gRPC")
arch.connect("auth", "authdb", "SQL")
arch.connect("users", "userdb", "SQL")
arch.connect("orders", "orderdb", "SQL")
arch.connect("orders", "queue", "publish")
arch.connect("queue", "notify", "subscribe")

arch.save("microservices.excalidraw")

出力の表示

.excalidraw ファイルを生成した後:

  1. Excalidraw.com:https://excalidraw.com にアクセスし、ファイルをキャンバスにドラッグします
  2. VS Code:「Excalidraw」拡張機能をインストールし、ファイルを開きます
  3. CLI:macOS では open filename.excalidraw を使用してデフォルトアプリで開きます

PNG へのエクスポート

Google ドキュメント、プレゼンテーション、その他のドキュメントに図を埋め込むには、Playwright を使用して PNG にエクスポートします。

エクスポートスクリプトの使用
# First time setup: install dependencies
cd ~/.claude/skills/excalidraw-diagrams/scripts
npm install
npx playwright install chromium

# Export to PNG
node ~/.claude/skills/excalidraw-diagrams/scripts/export_playwright.js diagram.excalidraw output.png
仕組み

Playwright エクスポートスクリプトは以下を実行します:

  1. ヘッドレス Chromium ブラウザで excalidraw.com を開きます
  2. ドラッグアンドドロップをシミュレートして図を読み込みます
  3. ビューをコンテンツに合わせます(Shift+1)
  4. 1920x1200 の解像度でキャンバスをスクリーンショットします
要件
  • Node.js:バージョン 18 以降
  • Playwright:scripts ディレクトリで npm install によりインストール
  • Chromium:npx playwright install chromium によりインストール

ヒント

  1. 配置:グリッドシステムを使用します。図形は整列しやすいよう 50 または 100 の倍数の位置から始めます。

  2. 間隔:矢印をきれいに引くために、要素間に 50〜100px のスペースを空けます。

  3. ラベル:ラベルは短く保ちます(2〜3 語)。より長い説明にはテキストボックスを使用します。

  4. 色:類似したコンポーネントには一貫した色を使用します(すべてのデータベースは緑、すべてのサービスは青)。

  5. レイアウトパターン:

    • 水平フロー:x が増加し、y は一定
    • 垂直フロー:y が増加し、x は一定
    • グリッド:複雑な図では両方を組み合わせます
  6. 生成後:Excalidraw で開いて位置を微調整し、手書き風の要素を追加します。


Google Drive 連携

クラウドストレージおよび Excalidraw Web での人手による編集のために、図を Google Drive に直接保存します。

クイックアップロード
import sys, os
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import Diagram

d = Diagram()
d.box(100, 100, "Cloud Diagram", color="blue")

# Save directly to Google Drive
result = d.save_to_drive("my_diagram.excalidraw", share_public=True)

print(f"View in Drive: {result['file']['web_view_link']}")
print(f"Edit in Excalidraw: {result['edit_url']}")
save_to_drive() メソッド

save_to_drive(name=None, folder_id=None, share_public=False, local_path=None)

図を Google Drive に直接保存します。

  • name:Drive 内のファイル名(デフォルト:"diagram.excalidraw")
  • folder_id:アップロード先の Drive フォルダ ID(デフォルト:ルート)
  • share_public:True の場合、ファイルを公開アクセス可能にします
  • local_path:このパスにもローカル保存します(任意)

以下を含む dict を返します:

  • file.id:Google Drive のファイル ID
  • file.web_view_link:Drive で表示するためのリンク
  • edit_url:Excalidraw.com で開くためのリンク
  • share:共有情報(share_public=True の場合)
drive_helper を直接使用する

より細かく制御するには、drive_helper モジュールを使用します:

import sys, os
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import Diagram
from drive_helper import upload_to_drive, share_file, search_excalidraw_files

# Create and save locally first
d = Diagram()
d.box(100, 100, "Hello")
d.save("hello.excalidraw")

# Upload to specific folder
result = upload_to_drive("hello.excalidraw", folder_id="YOUR_FOLDER_ID")

# Share with specific user
share_file(result["file"]["id"], email="[email protected]", role="writer")

# Find all excalidraw files in Drive
files = search_excalidraw_files()
DriveUploader クラス

バッチアップロードやフォルダ整理には:

from drive_helper import DriveUploader

uploader = DriveUploader(folder_id="YOUR_FOLDER_ID")

result = uploader.upload(
    "diagram.excalidraw",
    name="My Diagram",
    share_public=True
)
人手による編集ワークフロー

Drive に保存した後、ユーザーは 2 つの方法で図を編集できます:

  1. Excalidraw.com(edit_url 経由):

    • ブラウザで edit_url を開きます
    • Excalidraw が Drive からファイルを読み込みます
    • 編集して変更を保存します
  2. gdrive.excalidraw.com:

ラウンドトリップワークフロー

Claude で作成 → 人が編集 → Claude が更新:

from drive_helper import download_from_drive, update_in_drive

# Download human-edited version
download_from_drive(file_id, "updated_diagram.excalidraw")

# Make programmatic changes
d = Diagram()
# ... load and modify ...
d.save("updated_diagram.excalidraw")

# Upload changes back
update_in_drive(file_id, "updated_diagram.excalidraw")
完全なワークフロー: 図から Google ドキュメントまで

図を作成し、PNG にエクスポートして、Google ドキュメントに埋め込みます:

import sys, os, subprocess, json
sys.path.insert(0, os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts"))
from excalidraw_generator import ArchitectureDiagram

# 1. Create the diagram
arch = ArchitectureDiagram()
arch.user("user", "User", x=50, y=150)
arch.component("frontend", "Frontend", x=200, y=130, color="blue")
arch.service("api", "API Gateway", x=400, y=130, color="violet")
arch.database("db", "Database", x=600, y=150, color="green")
arch.connect("user", "frontend", "HTTPS")
arch.connect("frontend", "api", "REST")
arch.connect("api", "db", "SQL")

# 2. Save locally and to Drive
arch.save("/tmp/architecture.excalidraw")
drive_result = arch.save_to_drive("architecture.excalidraw", share_public=True)
file_id = drive_result["file"]["id"]
edit_url = drive_result["edit_url"]

# 3. Export to PNG using Playwright
subprocess.run([
    "node", os.path.expanduser("~/.claude/skills/excalidraw-diagrams/scripts/export_playwright.js"),
    "/tmp/architecture.excalidraw", "/tmp/architecture.png"
])

# 4. Upload PNG to Drive and share
drive_script = os.path.expanduser("~/.claude/skills/google-docs/scripts/drive_manager.rb")
png_result = subprocess.run(
    ["ruby", drive_script, "upload", "--file", "/tmp/architecture.png"],
    capture_output=True, text=True
)
png_data = json.loads(png_result.stdout)
png_id = png_data["file"]["id"]

# Share the PNG publicly
subprocess.run(["ruby", drive_script, "share", "--file-id", png_id, "--type", "anyone", "--role", "reader"])
png_url = f"https://drive.google.com/uc?id={png_id}&export=download"

# 5. Create Google Doc with embedded image
docs_script = os.path.expanduser("~/.claude/skills/google-docs/scripts/docs_manager.rb")

# Create document
doc_input = json.dumps({"title": "Architecture Overview", "content": "System Architecture\\n\\n"})
doc_result = subprocess.run(
    ["ruby", docs_script, "create"],
    input=doc_input, capture_output=True, text=True
)
doc_data = json.loads(doc_result.stdout)
doc_id = doc_data["document_id"]

# Insert image (Note: SVG not supported - must use PNG)
# Width 468pt fits standard Google Doc margins; height auto-scales
img_input = json.dumps({
    "document_id": doc_id,
    "image_url": png_url,
    "index": 25,
    "width": 468  # Page width in points (fits default margins)
})
subprocess.run(["ruby", docs_script, "insert-image"], input=img_input, capture_output=True, text=True)

# Append edit link
link_input = json.dumps({"document_id": doc_id, "text": f"\\n\\nEdit diagram: {edit_url}"})
subprocess.run(["ruby", docs_script, "append"], input=link_input, capture_output=True, text=True)

print(f"Document: https://docs.google.com/document/d/{doc_id}/edit")
print(f"Edit diagram: {edit_url}")

重要: Google ドキュメントは SVG 画像をサポートしていません。埋め込む場合は必ず PNG にエクスポートしてください。

前提条件
  • Google ドキュメントスキルがインストールされている必要があります (OAuth と drive_manager.rb を提供します)
  • 初回実行時、まだ認証が済んでいない場合は Google の認証が求められます

コメント