今回はブラウザで Mermaid 形式でテキストを記入して、図を描画する方法を解説していきます。特につながりはないのですが、前回のソースを使いまわしています。
完成しているコードは下記にあります。
環境
- node: 18.20.0
- Angular CLI:17.0.0
- Mermaid:11.3.0
パッケージのインストール
$ npm install mermaid
ライブラリは Mermaid を使用します。
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"esModuleInterop": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"skipLibCheck": true,
"lib": [
"ES2022",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
このまま Mermaid を使用すると TypeScript の型チェックでエラーが出るので、 tsconfig.json で "skipLibCheck": true
を設定して *.d.ts
ファイルに対する型チェックをスキップするようにします。
コンポーネントの生成
$ ng generate component mermaid
import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { InputComponent } from '../../share/input/input.component';
import { OutputComponent } from '../../share/output/output.component';
import mermaid from 'mermaid';
@Component({
selector: 'app-mermaid',
standalone: true,
imports: [InputComponent, OutputComponent],
templateUrl: './mermaid.component.html',
styleUrl: './mermaid.component.css'
})
export class MermaidComponent {
public safeHTML!: SafeHtml;
constructor(
private sanitizer: DomSanitizer
) {
mermaid.initialize({ startOnLoad: false });
}
public async onParse(message: any) {
const content = '<div class="mermaid">' + message + '</div>';
this.safeHTML = this.sanitizer.bypassSecurityTrustHtml(content);
setTimeout(async () => {
await mermaid.run({
querySelector: '.mermaid',
});
}, 0);
}
}
基本的には HTMLで <div class="mermaid"> {{ content }}</div>
を準備しておいて、TypeScriptから content
に Mermaid 形式でテキストを代入してやればいいのですが、 MathJax のときと同じく出力の方法を変えたくなかったので別の方法を採っています。
22行目
startOnLoad: true
の場合は、HTMLが読み込み終わった時点で自動で変換処理が実行されます。 今回は startOnLoad: false
とすることで、任意のタイミングで変換処理を実行するようにします。
26行目
startOnLoad: true
の場合はMermaid形式のテキストを <div class="mermaid"></div>
の要素を記載すれば class="mermaid"
の要素を対象に自動で変換してくれます。
29~30行目
DOMの更新を待ってから、 mermaid.run()
で手動で変換処理を実行します。引数に対象となるDOMを指定できます。
確認
graph LR
A["$$x^2$$"] -->|"$$\sqrt{x+3}$$"| B("$$\frac{1}{2}$$")
A -->|"$$\overbrace{a+b+c}^{\text{note}}$$"| C("$$\pi r^2$$")
B --> D("$$x = \begin{cases} a &\text{if } b \\ c &\text{if } d \end{cases}$$")
C --> E("$$x(t)=c_1\begin{bmatrix}-\cos{t}+\sin{t}\\ 2\cos{t} \end{bmatrix}e^{2t}$$")

注意点
<div class=”mermaid”></div> の要素に余計なものを書くとシンタックスエラーになります。例えば下記のような入力をするとエラーになります。
# Mermaid
graph LR
A["$$x^2$$"] -->|"$$\sqrt{x+3}$$"| B("$$\frac{1}{2}$$")
A -->|"$$\overbrace{a+b+c}^{\text{note}}$$"| C("$$\pi r^2$$")
B --> D("$$x = \begin{cases} a &\text{if } b \\ c &\text{if } d \end{cases}$$")
C --> E("$$x(t)=c_1\begin{bmatrix}-\cos{t}+\sin{t}\\ 2\cos{t} \end{bmatrix}e^{2t}$$")

コメント