GitHub に Mermaid がサポートされるようになったので、マークダウン中にいい感じのグラフを描画できるようになりましたね。
しかし、 Mermaid で作成される画像は SVG 形式なので、ブラウザからだと「名前をつけて画像を保存」ができません。
この記事は、いい感じの図ができたから Slack で共有しようと思ったのに、保存できなくて焦った人など向けに作ったものです。
最後の方でブラウザの開発者ツールの話が出ますが、そこから HTML 文書をコピペするだけでいいのでは? と思いつく方は対象にしておりません。
TL;DR
サンプルが以下です。
See the Pen Download SVG by Kitagawa (@aster-mnch) on CodePen.
保存処理だけを抜き出したのが以下です。
function downloadSvg(svgNode, filename) {
const svgText = new XMLSerializer().serializeToString(svgNode);
const svgBlob = new Blob([svgText], { type: 'image/svg+xml' });
const svgUrl = URL.createObjectURL(svgBlob);
const a = document.createElement('a');
a.href = svgUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(svgUrl);
}
説明
対象の SVG テキストを取得
const svgText = new XMLSerializer().serializeToString(svgNode);
ファイル保存するために SVG テキストデータを取得する必要がありますが、単純に .toString()
としても '[object SVGSVGElement]'
しか返ってきません。
そのため XMLSerializer.serializeToString() を使って文字列として取得します。
保存用の Blob オブジェクトを作成
const svgBlob = new Blob([svgText], { type: 'image/svg+xml' });
const svgUrl = URL.createObjectURL(svgBlob);
// ...
URL.revokeObjectURL(svgUrl);
先で取得した SVG テキストをファイル形式で保存するために Blob オブジェクトを作成します。
作成した Blob から URL.createObjectURL() でダウンロード用の URL を作成することができます。
この URL はスコープを抜けても解放されないので、不要になったら URL.revokeObjectURL() で解放しましょう。
a 要素を使ったダウンロード処理
const a = document.createElement('a');
a.href = svgUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
最後に、作成した Blob URL からファイルをダウンロードできるように a
要素を使います。
download
属性を使うことで、 href
に指定した URL からファイルをダウンロードすることができます。
また、 Blob URL と同様に、 document.body.appendChild
で追加したノードはドキュメントに紐づいているため、スコープを抜ける前に document.body.removeChild
で削除しましょう。
おまけ
保存したい対象の SVG 要素を選択する場合は、一から作るか document.getElementById() や document.querySelector() を使う必要がありますが、ブラウザのコンソールから $0
を使うと要素で直前に選択したノードを使用することができます。