PerfectVector
著者: Irene Kim2 分で読める

MermaidのカスタムSVGアイコン:自分の図形を登録する

SVG図形をIconifyアイコンセットにまとめ、Mermaidに登録します。動作する図の例で、アイコンの欠落、形状の切れ、ラベルをテストします。

目次

Mermaidで自分のSVGアイコンを使うには、描画内容と座標寸法をIconifyアイコンセットに入れ、mermaid.registerIconPacks() を呼び、図内で登録した名前を参照します。SVGのファイル名だけではアイコンは登録されません。

この方法はMermaidのJavaScriptを制御できるページやアプリに適します。ホスト型のMarkdownエディターでは図のテキストだけしか編集できない場合があるため、アイコン群を準備する前に統合設定を確認してください。単純な記号1つとコネクター1本から始めます。ラベルは図形と分かれたままにするため、Mermaidに保持します。

セットを登録できる場所を確認する

Mermaidの登録APIは、アイコンセットを直接受け取るか、セットを返すローダー経由で読み込みます。登録した name が図で使う接頭辞になります。この例はセットが garden、アイコンが leaf で、参照は garden:leaf です。

登録はレンダラーを準備するJavaScriptに置きます。そのJavaScriptをMermaidコードブロックに貼るのは同じ操作ではありません。公開プラットフォームでレンダラーを設定できないなら、対応するアイコンセットを使うか、自分で制御できる手順で図を描画し、書き出した結果を挿入します。後の編集用にMermaidの元データも一緒に保管してください。

この手順では、ローカルHTTPで配信する通常のHTMLページを使います。固定したMermaid 12.0.0のモジュールをCDNから読み込むため、ネットワーク接続が必要です。本番アプリは、選んだMermaidの版をバンドルすることもできます。採用前にその版とホストのコンテンツセキュリティポリシーをテストします。

SVGの描画座標を保持する

次がテストで使ったオリジナルの葉です。図形を別途確認したければ leaf.svg として保存します。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 24">
  <path fill="#167c72"
    d="M3 19C1 5 14 2 29 3C29 17 17 25 3 19Z"/>
  <path fill="none" stroke="#d7f1ca" stroke-width="1.8"
    d="M5 18L23 7"/>
</svg>

Iconifyのbodyフィールドは、外側の <svg> 要素を除いたSVGルート内部の内容を保持します。座標長方形は別途 left、top、width、height で持ち運びます。このファイルは原点0、寸法32 × 24です。

描画されたCSSサイズをコピーしないでください。64ピクセルで表示されたファイルでも viewBox は 0 0 32 24 の場合があります。パスは後者の座標系で描かれています。原点が0以外なら対応する left と top も保持するか、パッケージ化の前に意図的に原点0のキャンバスへ図形を移します。

Iconifyセットは prefix と icons オブジェクトを含みます。各アイコンのキーが図形の名前です。寸法の明示は重要です。アイコンにもセットにも指定がなければ、幅と高さの既定値は16です。大きなキャンバス用の図形が切れる場合があります。

記号群を準備するなら、先に輪郭、余白、視覚的な太さを整えます。SVGのUIキット準備ガイドは、それらの元図形の判断を扱っています。パッケージ化はシルエットを改善しません。

完全な2ノードの例を実行する

新しいフォルダーに次を index.html として保存します。Pythonが使えるならそのフォルダーで python3 -m http.server 8000 を実行し、ブラウザーで http://localhost:8000 を開きます。

<!doctype html>
<meta charset="utf-8">
<title>Custom Mermaid leaf icon</title>
<div id="diagram"></div>
 
<script type="module">
import mermaid from
  'https://cdn.jsdelivr.net/npm/mermaid@12.0.0/dist/mermaid.esm.min.mjs';
 
const icons = {
  prefix: 'garden',
  icons: {
    leaf: {
      width: 32,
      height: 24,
      body: '<path fill="#167c72" d="M3 19C1 5 14 2 29 3C29 17 17 25 3 19Z"/>' +
        '<path fill="none" stroke="#d7f1ca" stroke-width="1.8" d="M5 18L23 7"/>'
    }
  }
};
 
mermaid.registerIconPacks([{ name: 'garden', icons }]);
mermaid.initialize({ startOnLoad: false, theme: 'neutral' });
 
const definition = `architecture-beta
  service source(garden:leaf)[Source]
  service library(database)[Library]
  source:R --> L:library`;
 
const { svg } = await mermaid.render('garden-diagram', definition);
document.querySelector('#diagram').innerHTML = svg;
</script>

葉とデータベースの記号が並び、SourceからLibraryへ接続して見えるはずです。葉は登録セット由来で、database はMermaidの組み込みarchitectureアイコンの1つです。architecture構文のリファレンスは、丸括弧のアイコン名、角括弧のラベル、エッジに使うサービスの側面を説明しています。

この例は自動描画を無効にし、登録後に明示的な render() を1回呼びます。テスト時の順序が明確になります。既存サイトに統合するなら、登録とrenderが同じMermaidインスタンスを使うようにしてください。

これは例用に作った、小さな信頼できる図形です。大きなアイコン群には、すべての書き出したSVGを追加作業なしにパス文字列へ減らせると思わず、Iconifyの読み込み・整理ツールを使います。フォント、外部画像、スタイル、参照定義には別の確認が必要です。

登録の欠落と寸法の欠落を比較する

Mermaid 12.0.0を使い、別々のブラウザー文書でこの図を3つ描画しました。最初は登録を省略、2つ目は葉の2パスを登録して寸法を省略、3つ目は同じパスに width: 32 と height: 24 を登録しました。

ブラウザーで描画した3つのMermaid図。登録なしでは疑問符、寸法なしでは切れた葉、32 × 24の座標空間を保持すると完全な葉が表示されます
Mermaid 12.0.0で同じオリジナルの葉を比較。登録が図形を供給し、寸法が座標境界を制御します。ラベルとコネクターは図のネイティブ要素のままです。

最初の描画では、葉があるべき場所に疑問符が表示され、出力に葉のパスはありませんでした。2つ目は viewBox="0 0 16 16" のSVG内にパスがあり、葉が明らかに切れていました。3つ目は viewBox="0 0 32 24" を使い、完全な葉を表示しました。

これは今回の例と版の観察で、すべてのホストが使えないアイコンを同じ方法で報告すると確定するものではありません。また、この例は手書きSVGパスで、PerfectVectorの変換結果ではありません。

見える症状最初の確認有用な次の工程
疑問符かカスタム図形の欠落登録、セット名、アイコンキーgarden、leaf、garden:leaf を合わせ、描画前に登録を実行する
図形の一部だけ見えるアイコンの座標と寸法元のviewBoxをleft、top、width、heightと比較する
図全体が失敗するMermaidの版、構文、モジュール読み込み完全な最小例から始め、報告されたエラーを確認する
ローカル例は動くがホストのMarkdownは失敗するホストでレンダラーを制御できるか対応する登録方法と固定Mermaidバージョンを確認する
図形は見えるが図のサイズで細部が消える元の複雑さと表示サイズ図形を単純化するか、より明瞭な記号を使う

アイコンを増やす前に、最小例の動くコピーを保管します。セットの属性は1つずつ変えてください。そうしないと、名前の修正が別のサイズの問題を隠す場合があります。

必要な場合にラスター図形を取り込む

カスタム記号がPNGやJPGでしか残っていない場合、PerfectVectorのクリップアートからSVGへの手順で編集可能な輪郭を復元できます。コピーを記号に切り抜き、ベクター結果をプレビューして、シルエット、内側の隙間、不要な背景形状を確認します。その後、SVGを編集ソフトで開き、図で使う小さな版を準備します。

編集可能なSVGマスターは保持します。予定アイコンサイズで明瞭になってから描画内容と座標をパッケージ化してください。単純な幾何学記号は描き直す方が速い場合があり、写真は別画像の方が明瞭な場合があります。すでに適したSVGがあるなら、パッケージ化から始めます。

ベクター化はサービス名、関係、コネクターの方向を復元しません。それらはMermaidの元データに保持します。形状の動作が異なるキャンバス編集ソフトにはdraw.ioのカスタムSVG形状を参照してください。通常のWebページの再利用アイコンには、SVGのsymbolスプライトも別の方法です。DOTの図では、GraphvizのSVGノード画像の納品で、カスタム図形が書き出したグラフとともに持ち運べるか確認します。

図を渡す前に、実際の公開手順で開き直します。アイコンが読み込まれ、全シルエットが収まり、両ラベルが読め、コネクターが正しい向きであることを確認します。ローカル描画の成功を最初の確認とし、利用先の確認を続けます。

よくある質問

Mermaidのアイコン参照にSVGのファイル名を入れられますか? 登録アイコンセットの方法では、garden:leafなどのセット名とアイコンキーを使います。SVGの描画をアイコンデータとして準備し、レンダラーのJavaScriptで登録します。

カスタムMermaidアイコンが切れるのはなぜですか? 元のviewBoxとアイコンデータの座標属性を比較してください。アイコンとセットの両方に寸法がないと幅と高さは既定で16となり、図形には小さすぎる場合があります。

すべてのホスト型Markdownエディターで動きますか? いいえ。ホストが図の構文に対応し、必要なセットの登録方法を提供するか、すでに含む必要があります。ローカル構成と同じと思わず、実際の公開先をテストしてください。

参考資料

  1. Mermaid — アイコンセットの登録 — 直接のアイコンデータ、ローダー、登録名を説明しています。
  2. Mermaid — architecture図 — サービスアイコン、ネイティブラベル、組み込みアイコン、エッジ構文を定義しています。
  3. Iconify — IconifyIcon — 外側のSVGを除いた描画内容と座標属性を定義しています。
  4. Iconify — IconifyJSON — セット構造とアイコンが継承する寸法の既定値を定義しています。

図に使う記号がラスターしかないなら、PerfectVectorでSVG候補を作成し、シルエットと隙間を確認してください。その後、アイコンを1つ登録し、最終Mermaidレンダラーで境界とラベルを検証します。

ブログのその他の記事

編集しやすい
よりきれいなSVGから始めましょう