最新の Azure アイコンを svg2mxlibrary で変換して diagrams.net (draw.io) で使用する

## 概要

先日の [最新の Azure アイコンと Visual Studio Code Draw.io Integration の活用](https://qiita.com/yaegashi/items/e661507765c48db09e2b) という記事で、 pacodelacruz さんが作られた[最新 Azure アイコンの diagrams.net (draw.io) アプリ用のシェイプライブラリ](https://github.com/pacodelacruz/diagrams-net-azure-libraries)を紹介しましたが、最新版の [Azure Icon Collection](https://code.benco.io/icon-collection/) を反映していないのが残念だということを書きました。

そこで SVG のアイコンファイルから diagrams.net アプリが認識する mxlibrary 形式のファイルに変換するツール svg2mxlibrary を自作し、最新版の Azure Icon Collection から変換した mxlibrary と共に次のリポジトリで公開しましたので、この記事で紹介します。

https://github.com/yaegashi/icon-collection-mxlibrary

Visual Studio Code の [Draw.io Integration](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio) 用のカスタムライブラリ設定も用意しています。ぜひ活用してください。

![vscode-drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61759/fc2b97ab-7ddd-62f7-fe6e-6a00149ec459.png)

## 使い方

SVG のアイコンファイルから変換済みの mxlibrary ファイルは、リポジトリの [mxlibrary ブランチ](https://github.com/yaegashi/icon-collection-mxlibrary/tree/mxlibrary)で参照できます。

[オンライン版 app.diagrams.net アプリ](https://app.diagrams.net)で使う場合は、次のリンクを利用してください。 mxlibrary がインポートされます。一度インポートされた mxlibrary はアプリによって永続化されます。

|アイコンギャラリー|app.diagrams.net リンク|
|---|---|
|['Official' Azure Icons Set](https://code.benco.io/icon-collection/azure-icons)|[Open app.diagrams.net with azure-icons.xml](https://app.diagrams.net/?splash=0&clibs=Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fyaegashi%2Ficon-collection-mxlibrary%2Fmxlibrary%2Fazure-icons.xml)|
|[Azure Docs](https://code.benco.io/icon-collection/azure-docs)|[Open app.diagrams.net with azure-docs.xml](https://app.diagrams.net/?splash=0&clibs=Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fyaegashi%2Ficon-collection-mxlibrary%2Fmxlibrary%2Fazure-docs.xml)|
|['CDS' Azure Icons Set](https://code.benco.io/icon-collection/azure-cds)|[Open app.diagrams.net with azure-cds.xml](https://app.diagrams.net/?splash=0&clibs=Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fyaegashi%2Ficon-collection-mxlibrary%2Fmxlibrary%2Fazure-cds.xml)|
|[Azure Patterns Collection](https://code.benco.io/icon-collection/azure-patterns)|[Open app.diagrams.net with azure-patterns.xml](https://app.diagrams.net/?splash=0&clibs=Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fyaegashi%2Ficon-collection-mxlibrary%2Fmxlibrary%2Fazure-patterns.xml)<br/>(アイコンが 1500 以上あるので注意！)|
|[Logos & Brands](https://code.benco.io/icon-collection/logos)|[Open app.diagrams.net with logos.xml](https://app.diagrams.net/?splash=0&clibs=Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fyaegashi%2Ficon-collection-mxlibrary%2Fmxlibrary%2Flogos.xml)|
|[Other Icons](https://code.benco.io/icon-collection/other)|[Open app.diagrams.net with other.xml](https://app.diagrams.net/?splash=0&clibs=Uhttps%3A%2F%2Fraw.githubusercontent.com%2Fyaegashi%2Ficon-collection-mxlibrary%2Fmxlibrary%2Fother.xml)|

[デスクトップ版 diagrams.net アプリ](https://github.com/jgraph/drawio-desktop)で使う場合は、[mxlibrary ファイルをダウンロード](https://github.com/yaegashi/icon-collection-mxlibrary/archive/mxlibrary.zip)して XML ファイルをアプリにドラッグ・アンド・ドロップすればインポートすることができます。

[Visual Studio Code の Draw.io Integration 拡張](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio)で使用する場合は、次の設定を settings.json に追加してください。カスタムライブラリとして呼び出せるようになります。

```json
    "hediet.vscode-drawio.customLibraries": [
        {
            "entryId": "'Official' Azure Icons Set",
            "libName": "Azure Icons",
            "url": "https://raw.githubusercontent.com/yaegashi/icon-collection-mxlibrary/mxlibrary/azure-icons.xml"
        },
        {
            "entryId": "Azure Docs",
            "libName": "Azure Docs",
            "url": "https://raw.githubusercontent.com/yaegashi/icon-collection-mxlibrary/mxlibrary/azure-docs.xml"
        },
        {
            "entryId": "'CDS' Azure Icons Set",
            "libName": "Azure CDS",
            "url": "https://raw.githubusercontent.com/yaegashi/icon-collection-mxlibrary/mxlibrary/azure-cds.xml"
        },
        {
            "entryId": "Azure Patterns Collection",
            "libName": "Azure Pattenrs",
            "url": "https://raw.githubusercontent.com/yaegashi/icon-collection-mxlibrary/mxlibrary/azure-patterns.xml"
        },
        {
            "entryId": "Logos & Brands",
            "libName": "Azure Logos",
            "url": "https://raw.githubusercontent.com/yaegashi/icon-collection-mxlibrary/mxlibrary/logos.xml"
        },
        {
            "entryId": "Other Icons",
            "libName": "Azure Other",
            "url": "https://raw.githubusercontent.com/yaegashi/icon-collection-mxlibrary/mxlibrary/other.xml"
        },
    ],
```

## Azure Icon Collection から mxlibrary への変換

リポジトリには [Azure Icon Collection のリポジトリ](https://github.com/benc-uk/icon-collection)のクローンと mxlibrary ファイルへの変換を自動的に行うスクリプト [convert.sh](https://github.com/yaegashi/icon-collection-mxlibrary/blob/master/convert.sh) が含まれています。

次のように実行してください。変換プログラム [svg2mxlibrary](https://github.com/yaegashi/icon-collection-mxlibrary/tree/master/svg2mxlibrary) を動かすために [Node.js](https://nodejs.org) が必要です。変換結果の mxlibrary ファイルは out フォルダに格納されます。

```console
$ git clone https://github.com/yaegashi/icon-collection-mxlibrary
$ cd icon-collection-mxlibrary
$ npm install --no-save svg2mxlibrary
$ ./convert.sh
Cloning into 'icon-collection'...
remote: Enumerating objects: 2842, done.
remote: Counting objects: 100% (2842/2842), done.
remote: Compressing objects: 100% (2739/2739), done.
remote: Total 2842 (delta 153), reused 1216 (delta 99), pack-reused 0
Receiving objects: 100% (2842/2842), 1.72 MiB | 1.95 MiB/s, done.
Resolving deltas: 100% (153/153), done.
Generating mxlibrary out/azure-icons.xml
Generating mxlibrary out/azure-docs.xml
Generating mxlibrary out/azure-cds.xml
Generating mxlibrary out/azure-patterns.xml
Generating mxlibrary out/logos.xml
Generating mxlibrary out/other.xml
```

## svg2mxlibrary について

変換プログラム [svg2mxlibrary](https://github.com/yaegashi/icon-collection-mxlibrary/tree/master/svg2mxlibrary) は Node.js の CLI で、次のようなコマンドラインオプションが利用できます。

```console
$ node svg2mxlibrary
svg2mxlibrary [options] <SVG files...>

Options:
      --version  Show version number                                   [boolean]
      --help     Show help                                             [boolean]
  -o, --out      output file                 [string] [default: "mxlibrary.xml"]
  -s, --size     icon size                                         [default: 80]
```

`-s` オプションで出力するアイコンのサイズを指定できます。リポジトリで公開している mxlibrary はデフォルトの値 80 で出力しています。

svg2mxlibrary は [mxgraph](https://www.npmjs.com/package/mxgraph) という NPM パッケージを使用しています。 [mxGraph](https://jgraph.github.io/mxgraph/) は diagrams.net (draw.io) アプリ実装のコアとなるライブラリです。

mxGraph を使用するには DOM が必要なのですが、Web ブラウザではなく Node.js の CLI で使うために [jsdom](https://github.com/jsdom/jsdom) を利用するテクニックを利用しました。  [How i can use mxGraph instance in node.js](https://stackoverflow.com/q/55711473/4937930) という Stack Overflow の回答に説明があります。

SVG アイコンを描画した mxGraph オブジェクトを mxlibrary 形式のファイルに変換する手順については、 [GitHub Issue #470 Generate mxlibrary - how to properly encode contents of the xml property?](https://github.com/jgraph/drawio/issues/470) を参考にしました。

SVG アイコン描画時のスタイルについては元ネタとなった [Azure Icon Libraries for Diagrams.net (Draw.io)](https://github.com/pacodelacruz/diagrams-net-azure-libraries) の設定値を参考にしました。アスペクト比を固定し、テキストラベルの位置をアイコン下中央にしているので、使いやすいと思います。

## まとめ

ということで、最新の Azure アイコンを diagrams.net (draw.io) アプリや Visual Studio Code で使える mxlibrary として公開しましたので、ぜひ活用してください。なお[公式の Azure アーキテクチャアイコンの配布](https://docs.microsoft.com/ja-jp/azure/architecture/icons/)では 2020 年 11 月に v3 がリリースされていますが、 [Azure Icon Collection](https://code.benco.io/icon-collection/) にはまだこれが含まれていないようです。こちらが更新されしだいリポジトリの mxlibrary にも反映させます。

また今回開発した svg2mxlibrary は、 Azure アイコンに限らず、任意の SVG ファイルから mxlibrary に変換するための汎用ツールとしても使えると思います。

大して複雑ではない短いプログラムですが、正しく動作させるまでにはいろいろな調査や試行錯誤が必要でした。 Node.js のプログラムを一から作るのも初めてで、いろいろと不備があると思いますので、バグの報告や改善の提案をいただけるうれしいです。