mermaid.js のフローチャートに画像を表示させます。
はじめに
mermaid.js とは、Javascript製のフローチャート作成ライブラリです。複雑なフローチャートやシーケンス図が簡単に書けちゃいます。
で、今回フローチャートに画像を表示させたかったのですが、思いのほか上手くいかず四苦八苦してやっと表示できるようになったので紹介します。
完成系
手っ取り早く完成系から紹介します。
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/mermaid/6.0.0/mermaid.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/6.0.0/mermaid.js"></script>
<script>
window.onload = function () {
var mermaidAPI = mermaid.mermaidAPI;
var config = {
startOnLoad: false,
htmlLabels: true,
callback: function (id) {
console.log(id, ' rendered');
},
flowchart: {
useMaxWidth: false,
}
};
mermaid.initialize(config);
var element = document.getElementById("app");
var insertSvg = function (svgCode, bindFunctions) {
element.innerHTML = svgCode;
};
var graphDefinition = `
graph LR
subgraph \u5e7c\u5e74\u671f
botamon(<img src='https://digimon.net/cimages/digimon/botamon.jpg' width='40' height='40' /><br>\u30dc\u30bf\u30e2\u30f3)
koromon(<img src='https://digimon.net/cimages/digimon/koromon.jpg' width='40' height='40' /><br>\u30b3\u30ed\u30e2\u30f3)
end
subgraph \u6210\u9577\u671f
agumon(<img src='https://digimon.net/cimages/digimon/agumon.jpg' width='40' height='40' /><br>\u30a2\u30b0\u30e2\u30f3)
betamon(<img src='https://digimon.net/cimages/digimon/betamon.jpg' width='40' height='40' /><br>\u30d9\u30bf\u30e2\u30f3)
end
subgraph \u6210\u719f\u671f
greymon-first(<img src='https://digimon.net/cimages/digimon/greymon-first.jpg' width='40' height='40' /><br>\u30b0\u30ec\u30a4\u30e2\u30f3)
tyranomon(<img src='https://digimon.net/cimages/digimon/tyranomon.jpg' width='40' height='40' /><br>\u30c6\u30a3\u30e9\u30ce\u30e2\u30f3)
devimon(<img src='https://digimon.net/cimages/digimon/devimon.jpg' width='40' height='40' /><br>\u30c7\u30d3\u30e2\u30f3)
meramon(<img src='https://digimon.net/cimages/digimon/meramon.jpg' width='40' height='40' /><br>\u30e1\u30e9\u30e2\u30f3)
airdramon(<img src='https://digimon.net/cimages/digimon/airdramon.jpg' width='40' height='40' /><br>\u30a8\u30a2\u30c9\u30e9\u30e2\u30f3)
seadramon(<img src='https://digimon.net/cimages/digimon/seadramon.jpg' width='40' height='40' /><br>\u30a8\u30a2\u30c9\u30e9\u30e2\u30f3)
numemon(<img src='https://digimon.net/cimages/digimon/numemon.jpg' width='40' height='40' /><br>\u30cc\u30e1\u30e2\u30f3)
end
subgraph \u5b8c\u5168\u4f53
metalgreymon-v(<img src='https://digimon.net/cimages/digimon/metalgreymon-v.jpg' width='40' height='40' /><br>\u30e1\u30bf\u30eb\u30b0\u30ec\u30a4\u30e2\u30f3)
mamemon(<img src='https://digimon.net/cimages/digimon/mamemon.jpg' width='40' height='40' /><br>\u30de\u30e1\u30e2\u30f3)
monzaemon(<img src='https://digimon.net/cimages/digimon/monzaemon.jpg' width='40' height='40' /><br>\u3082\u3093\u3056\u3048\u30e2\u30f3)
end
botamon-->koromon
koromon-->agumon
koromon-->betamon
agumon-->greymon-first
agumon-->tyranomon
agumon-->devimon
betamon-->devimon
agumon-->meramon
betamon-->meramon
betamon-->airdramon
betamon-->seadramon
agumon-->numemon
betamon-->numemon
greymon-first-->metalgreymon-v
devimon-->metalgreymon-v
airdramon-->metalgreymon-v
tyranomon-->mamemon
meramon-->mamemon
seadramon-->mamemon
numemon-->monzaemon
`;
var graph = mermaidAPI.render("mermaid", graphDefinition, insertSvg);
};
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
これを HTML に張り付けてブラウザで表示させると、こんなフローチャートが表示されます。

なんでデジモンなのかは置いておいて、こんな感じにフローチャート内に画像を表示することができます。
つまづいた点
render関数 を通さないと画像が表示できない
mermaid.js は HTML内に直接書けるように出来ているのですが、画像を表示させるために、Javascript の mermaidAPI.render関数 を通さないと画像が表示できませんでした。
例えば、このように書くだけでフローチャートができちゃうんですよ、普通は。
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/mermaid/6.0.0/mermaid.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/6.0.0/mermaid.js"></script>
<script>mermaid.initialize({ startOnLoad: true });</script>
</head>
<body>
<div class="mermaid">
graph LR
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
</div>
</body>
</html>

この書き方が出来なかったのが辛かった。
参考

How to embed an image in a node with "mermaid.js"
Is there any way to embed a picture with mermaid.js in a flow diagram graph node? I tried: <div class="mermaid"> graph LR A(<img src="pic.svg">...
日本語表示が出来なかった
え?いや、出来てるじゃん。って思ったと思いますが、日本語を1文字ずつわざわざ Unicodeエスケープシーケンス に変換して表示しています。
日本語の変換にはこちらを使わせてもらいました。
わざわざ変換するのがクソめんどくさい。
おわりに
そんなこんなで、Javascript製のフローチャート作成ライブラリの紹介でした。