前の記事でブログに利益ファネル図を SVG で埋め込みました。「なぜ XML の記述だけでグラフが描けるのか」「HTML から変換できないのか」という疑問を出発点に、SVG の仕組みを掘り下げます。

SVG の基本構造

SVG(Scalable Vector Graphics)は、図形を XML タグで記述するフォーマットです。ブラウザが直接レンダリングするため、別途ランタイムは不要です。

最小の例:

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <rect x="10" y="10" width="80" height="40" fill="#5b9cff" rx="4"/>
  <text x="18" y="36" fill="white" font-size="14">利益</text>
</svg>

座標系は左上が原点 (0, 0)、右下に向かって x・y が増えます。viewBox 属性で「論理座標」と「表示サイズ」を分離でき、解像度に依存しないスケーリングが可能です。

グラフに使う主要な要素は 4 つです。

要素 用途
<rect> 棒グラフのバー、背景、ボックス
<text> ラベル・数値の表示
<line> / <path> 軸、矢印、折れ線
<defs> + <linearGradient> グラデーション定義の再利用

利益ファネル図は <rect>width を利益の大きさに比例させ、<text> でラベルを重ねただけの構造です。JavaScript も画像変換も必要ありません。

HTML から SVG に変換できるか

結論から言うと「限定的には可能、ただし制約が多い」です。

foreignObject を使う方法

SVG には <foreignObject> という要素があり、内部に HTML を埋め込めます。

<svg width="400" height="200">
  <foreignObject x="0" y="0" width="400" height="200">
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p style="color: white;">普通の HTML</p>
    </div>
  </foreignObject>
</svg>

ただしスタイルの適用範囲や外部フォントの読み込みは制限されます。<canvas> に描画してから toDataURL() で画像化する用途には使えますが、ブラウザ間の互換性が低いです。

ライブラリを使う方法

html2canvasdom-to-image は DOM のスナップショットを Canvas/PNG に変換します。SVG として出力することもできますが、内部は「ビットマップを SVG に貼り付けた」形になり、ベクター描画の恩恵はありません。

Claude Code が SVG を生成する方法

今回の利益グラフのように、LLM が「データ → 座標値 → SVG テキスト」を直接生成するのが最もクリーンです。HTML の DOM を経由せず、仕様から SVG を書き下ろすため、構造が明快で修正しやすい成果物になります。

SVG グラフ作成をスキル化する

同じパターンのグラフを何度も作る場面では、スキルとして仕様化しておくと再現性が上がります。スキルに書くべき内容は 3 層に分かれます。

1. デザイントークン

キャンバスサイズ・配色・フォント・余白などの定数をスキルに固定します。

canvas: 900 × 530px
background: #1a1a2e / #16213e グラデーション
font: -apple-system, 'Segoe UI', sans-serif
bar_radius: 5px
label_color: #b0b8d0

2. データ → 座標変換のルール

「最大値を何 px にマッピングするか」を明示します。

max_width = 700px (= 100%)
bar_x_start = 192px
row_height = 46px, gap = 26px
value[i] の幅 = max_width × (value[i] / max_value)

3. 出力テンプレートの制約

  • <defs> にグラデーションを定義して各バーから参照する
  • <text>text-anchorfont-size を統一する
  • 注釈は fill="#4a5070" で薄く下部に配置する

この 3 層をスキルの SKILL.md に書いておくと、新しいグラフを頼むたびにデザインが揃います。複数の系列(例: 前期比較)が必要になったらグラデーション定義を追加するだけで拡張できます。

まとめ

  • SVG は XML の座標指定で図形を描くフォーマット。ブラウザが直接解釈するためランタイム不要。
  • HTML から SVG への変換は foreignObject やライブラリで可能だが、ビットマップ化が多く「ベクターとして扱える SVG」にはなりにくい。
  • LLM が「仕様 → 座標 → SVG テキスト」を直接生成するアプローチが最も扱いやすい。
  • 繰り返し使うグラフはデザイントークン・座標変換ルール・テンプレート制約の 3 層をスキルに書いておくと一貫性が保てる。