Mermaid 图表和流程图越来越受欢迎,尤其是在 GitHub 宣布 在 Markdown 中原生支持它们之后。让我们看看它们是什么,如何使用它们,以及同样重要的是:为什么。
就像您可能想要 将您的 CodePen 演示直接嵌入 到您的文档源中一样,将您的图表和图表置于您的文本旁边可以防止它们腐烂——也就是说,与您的文档状态不同步。同样无用、过时或误导性的代码注释可能比没有注释更糟糕,图表也是如此。
Mermaid 图表与 Jamstack 和 静态站点生成器 配合良好,这些生成器越来越受欢迎。这种搭配很自然。虽然 Mermaid 图表不限于 Markdown,但它们是受 Markdown 启发的。使用 Markdown 提供的相同标记抽象来注释代码,Mermaid 可以以相同的方式表示以输出图表和流程图。而 Markdown 之于 Jamstack 和静态网站,就像花生酱之于果冻。
如果您的网站是在 Markdown 中创作,处理成 HTML,并且您有足够的控制权来添加一些自定义 JavaScript,那么您可以使用我们在本文中介绍的想法来满足您自己的需求,并使用 Mermaid 方便地在 Markdown 的其余部分旁边实现图表。 “图表即代码”这个词已经出现了吗?它应该出现。
例如,假设您正在开发一款新产品,您想以 甘特图(或 其他类型——比如流程图、序列和类图)的形式提供路线图。使用 Mermaid,您可以在几行代码中完成此操作
gantt
title My Product Roadmap
dateFormat YYYY-MM-DD
section Cool Feature
A task :a1, 2022-02-25, 30d
Another task :after a1, 20d
section Rad Feature
Task in sequence :2022-03-04, 12d
Task, No. 2 :24d
这将呈现一个漂亮的 SVG 图表,如下所示

专业提示:Mermaid 有一个实时编辑器,可以让您在 mermaid.live 上进行尝试,而无需任何承诺。
Markdown 中的 Mermaid 图表
Mermaid 与 Markdown 配合良好,因为它表现为另一个 围栏代码块,只是使用 mermaid
语言语法集。例如,这块代码
```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
```
……生成一个 HTML <pre>
元素,其中包含代码块内容
<pre class="mermaid"><code>graph TD;
A-->B;
A-->C;
B-->D;
C-->D;</code></pre>
如果您使用的是 与 CommonMark 规范对齐的 Markdown 处理器,它将更类似于这样
<pre><code class="language-mermaid">graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
</code></pre>
Mermaid API 的默认行为期望一个 <div class="mermaid">
标签,该标签直接包含内容——因此,没有 <code>
或 <span>
(如来自语法高亮器)您可能在 Markdown 到 HTML 的转换中看到。
使用 JavaScript 进行微调
使用一些 JavaScript,可以合理地将 Markdown 生成的 HTML 微调成 Mermaid 目标的 <div class="mermaid">
标签。值得注意的是 $element.textContent
在这里是有目的的:Markdown 会对特定字符进行 HTML 编码(例如,将 >
编码成 >
),而 Mermaid 使用这些字符。它还会过滤掉 <pre>
元素的任何错误 HTML 元素。
// select <pre class="mermaid"> _and_ <pre><code class="language-mermaid">
document.querySelectorAll("pre.mermaid, pre>code.language-mermaid").forEach($el => {
// if the second selector got a hit, reference the parent <pre>
if ($el.tagName === "CODE")
$el = $el.parentElement
// put the Mermaid contents in the expected <div class="mermaid">
// plus keep the original contents in a nice <details>
$el.outerHTML = `
<div class="mermaid">${$el.textContent}</div>
<details>
<summary>Diagram source</summary>
<pre>${$el.textContent}</pre>
</details>
`
})
现在我们的 HTML 格式正确了,让我们实现 Mermaid 来进行渲染。
使用 Mermaid
Mermaid 发布为一个 npm 包,因此您可以使用支持包的 CDN(如 unpkg)获取副本。您需要使用最小化的代码(例如,mermaid.min.js
)而不是 mermaid.core.js
的默认导出。例如
<script src="https://unpkg.com/[email protected]/dist/mermaid.min.js"></script>
Mermaid 也是 ESM 就绪的,因此您也可以使用 Skypack 来加载它
<script type="module">
import mermaid from "https://cdn.skypack.dev/[email protected]";
</script>
如果您想保持简单,可以在这里停止。默认情况下,Mermaid 会 在文档准备就绪时自动初始化自身。只要您在加载 Mermaid 之前 使用 JavaScript 完成前面提到的 Markdown 到 HTML 的微调——您就可以开始使用它。
但是,Mermaid 有几个值得配置的设置
// initialize Mermaid to [1] log errors, [2] have loose security for first-party
// authored diagrams, and [3] respect a preferred dark color scheme
mermaid.initialize({
logLevel: "error", // [1]
securityLevel: "loose", // [2]
theme: (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) ?
"dark" :
"default" // [3]
})
logLevel
将为您提供有关可能出现的任何错误的更多可见性。如果您想查看更多信息,可以 选择更详细的级别(反之亦然)。securityLevel
与 图表源的信任级别 有关。如果它是你自己创作的内容,那么"loose"
就可以了。如果它是用户生成的内容,最好保留"strict"
的默认值。theme
更改 渲染图表的样式。通过 查询首选颜色方案 并利用三元运算符,我们可以根据需要指定"dark"
。
现在就一起做!
以下是在 Markdown 中的一些 Mermaid 图表示例
更深的水域
这种策略特别有效,因为它具有渐进性:如果禁用了 JavaScript,则会按原样显示原始 Mermaid 源代码。没有问题。
还有一个完整的 Mermaid 命令行界面,如果您有兴趣探索,它可以用来显示完全在服务器端渲染的图表。在 Mermaid CLI 和在线生成器之间,甚至可以将您使用的任何构建过程挂钩,以生成图表的快照,并将其作为 <img>
回退而不是源代码来显示。
希望随着 Mermaid 越来越受欢迎,我们将看到更多像这样的原生 Mermaid 集成。在文档旁边拥有可视化图表和图表的实用性是毋庸置疑的——从产品路线图到决策树,以及介于两者之间的所有内容。这些都是仅凭文字很难记录的信息。
Mermaid 图表解决了这个问题,而且它确保了这些信息可以与文档的其余部分一起管理和维护。
为什么不直接使用图像,而要费尽心思保留原始 Mermaid 源代码,直到它在浏览器中被替换?源代码不是人类可读的等效代码。
好文章,非常全面的概述!
我觉得也应该提到,GitHub 实现的 Mermaid 对辅助技术的支持不是很好。因此,目前
这意味着每个人都能理解您提供的图表。
Eric 的流程可能是最好的选择。
Mermaid 的图表一直以来都存在无障碍问题,至少从 2019 年开始就存在。虽然自 GitHub 公告以来已经做了一些努力,但它们似乎还没有在所有地方推出(实时编辑器不识别新的属性,并且没有更改来考虑流程图的阅读顺序或连接)。至少,可能不要在 GitHub 或自己的项目中使用它们,除非你自己手动创建图像替代方案。
关于 Mermaid 的概述,这是一篇很棒的文章。我最近在 VS Code 编辑器中使用了类似的工具来构建思维导图。这种工具对于需要向经理汇报未来两个月目标/工作分解结构的开发者来说非常有用。
顺便说一句,看起来 Mermaid 已经添加了无障碍信息,根据 Adrian 的评论:https://github.com/microsoft/FluidFramework/pull/3850