项目文件夹

0
wehub-resource-sync 7226d357e0
CI / test (push) Has been cancelled
docs: make Chinese README the default
2026-07-13 10:14:12 +00:00

Note

本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
English · 原始项目 · 上游 README
原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。

beautiful-mermaid

将 Mermaid 图表渲染为精美的 SVG 或 ASCII 艺术

超快、完全可主题化、零 DOM 依赖。为 AI 时代而生。

beautiful-mermaid sequence diagram example

npm version License

在线演示与示例

→ 在 Craft Agents 中即时使用


我们为何构建它

图表对于 AI 辅助编程至关重要。当你与 AI 编程助手协作时,能够在终端或聊天界面中直接可视化数据流、状态机和系统架构,能让复杂概念一目了然。

Mermaid 是基于文本的图表事实标准(de facto standard)。它非常出色。但默认渲染器存在一些问题:

  • 美观度 — 或许只是个人偏好,但希望它们看起来更专业
  • 复杂的主题定制 — 自定义颜色需要与 CSS 类较劲
  • 无终端输出 — 无法为 CLI 工具渲染为 ASCII
  • 沉重依赖 — 为简单图表引入大量代码

我们在 Craft 构建了 beautiful-mermaid,为 Craft Agents. 中的图表提供动力。它快速、美观,随处可用——从富 UI 到纯终端。

ASCII 渲染引擎基于 Alexander Grooff 的 mermaid-ascii。我们从 Go 移植到 TypeScript 并进行了扩展。感谢 Alexander 提供的优秀基础!(以及证明了这是可行的灵感。)

功能特性

  • 6 种图表类型 — 流程图、状态图、时序图、类图、ER 图和 XY 图(柱状、折线、组合)
  • 双输出 — SVG 用于富 UI,ASCII/Unicode 用于终端
  • 同步渲染 — 无异步、无闪烁。可与 React useMemo() 配合使用
  • 15 个内置主题 — 添加自定义主题也极其简单
  • 完整 Shiki 兼容 — 直接使用任意 VS Code 主题
  • 实时主题切换 — CSS 自定义属性,无需重新渲染
  • 单色模式(Mono mode — 仅用 2 种颜色也能生成精美图表
  • 零 DOM 依赖 — 纯 TypeScript,随处可用
  • 超快速度 — 500ms 内渲染 100+ 张图表

安装

npm install beautiful-mermaid
# or
bun add beautiful-mermaid
# or
pnpm add beautiful-mermaid

快速开始

SVG 输出

import { renderMermaidSVG } from 'beautiful-mermaid'

const svg = renderMermaidSVG(`
  graph TD
    A[Start] --> B{Decision}
    B -->|Yes| C[Action]
    B -->|No| D[End]
`)

渲染完全同步——没有 await,没有 promise。ELK.js 布局引擎通过 FakeWorker 绕过机制同步运行,因此你能立即获得 SVG 字符串。

需要异步?使用 renderMermaidSVGAsync() —— 输出相同,返回 Promise<string>

ASCII 输出

import { renderMermaidASCII } from 'beautiful-mermaid'

const ascii = renderMermaidASCII(`graph LR; A --> B --> C`)
┌───┐     ┌───┐     ┌───┐
│   │     │   │     │   │
│ A │────►│ B │────►│ C │
│   │     │   │     │   │
└───┘     └───┘     └───┘

React 集成

由于渲染是同步的,你可以使用 useMemo() 实现零闪烁的图表渲染:

import { renderMermaidSVG } from 'beautiful-mermaid'

function MermaidDiagram({ code }: { code: string }) {
  const { svg, error } = React.useMemo(() => {
    try {
      return {
        svg: renderMermaidSVG(code, {
          bg: 'var(--background)',
          fg: 'var(--foreground)',
          transparent: true,
        }),
        error: null,
      }
    } catch (err) {
      return { svg: null, error: err instanceof Error ? err : new Error(String(err)) }
    }
  }, [code])

  if (error) return <pre>{error.message}</pre>
  return <div dangerouslySetInnerHTML={{ __html: svg! }} />
}

为何效果好:

  • 无闪烁 — SVG 在渲染期间同步计算,而非在 useEffect 中
  • CSS 变量 — 传递 var(--background) 等,而非十六进制颜色。SVG 继承自应用的 CSS,因此主题切换可即时生效而无需重新渲染
  • 记忆化(Memoized — 仅在 code 变化时重新渲染

主题

主题系统是 beautiful-mermaid 的核心。它既强大又极其简单。

双色基础

每张图表只需两种颜色:背景bg)和前景fg)。仅此而已。从这两种颜色出发,整个图表通过 color-mix() 推导得出:

const svg = renderMermaidSVG(diagram, {
  bg: '#1a1b26',  // Background
  fg: '#a9b1d6',  // Foreground
})

这就是单色模式(Mono Mode——仅用两种颜色就能生成连贯、精美的图表。系统会自动推导:

元素 推导方式
文本 --fg at 100%
次要文本 --fg at 60% into --bg
边标签 --fg at 40% into --bg
淡色文本 --fg at 25% into --bg
连接线 --fg at 50% into --bg
箭头 --fg at 85% into --bg
节点填充 --fg at 3% into --bg
组标题 --fg at 5% into --bg
内部描边 --fg at 12% into --bg
节点描边 --fg at 20% into --bg

增强模式(Enriched Mode

对于更丰富的主题,你可以提供可选的「增强」颜色来覆盖特定推导结果:

const svg = renderMermaidSVG(diagram, {
  bg: '#1a1b26',
  fg: '#a9b1d6',
  // Optional enrichment:
  line: '#3d59a1',    // Edge/connector color
  accent: '#7aa2f7',  // Arrow heads, highlights
  muted: '#565f89',   // Secondary text, labels
  surface: '#292e42', // Node fill tint
  border: '#3d59a1',  // Node stroke
})

若未提供增强颜色,则回退到 color-mix() 推导。这意味着你只需提供你关心的颜色。

CSS 自定义属性 = 实时切换

所有颜色都是 <svg> 元素上的 CSS 自定义属性。这意味着你可以即时切换主题而无需重新渲染:

// Switch theme by updating CSS variables
svg.style.setProperty('--bg', '#282a36')
svg.style.setProperty('--fg', '#f8f8f2')
// The entire diagram updates immediately

对于 React 应用,传递 CSS 变量引用而非十六进制值:

const svg = renderMermaidSVG(diagram, {
  bg: 'var(--background)',
  fg: 'var(--foreground)',
  accent: 'var(--accent)',
  transparent: true,
})
// Theme switches apply automatically via CSS cascade — no re-render needed

内置主题

开箱即用提供 15 个精心策划的主题:

主题 类型 背景 强调色
zinc-light Light #FFFFFF Derived
zinc-dark Dark #18181B Derived
tokyo-night Dark #1a1b26 #7aa2f7
tokyo-night-storm Dark #24283b #7aa2f7
tokyo-night-light Light #d5d6db #34548a
catppuccin-mocha Dark #1e1e2e #cba6f7
catppuccin-latte Light #eff1f5 #8839ef
nord Dark #2e3440 #88c0d0
nord-light Light #eceff4 #5e81ac
dracula Dark #282a36 #bd93f9
github-light Light #ffffff #0969da
github-dark Dark #0d1117 #4493f8
solarized-light Light #fdf6e3 #268bd2
solarized-dark Dark #002b36 #268bd2
one-dark Dark #282c34 #c678dd
import { renderMermaidSVG, THEMES } from 'beautiful-mermaid'

const svg = renderMermaidSVG(diagram, THEMES['tokyo-night'])

添加自定义主题

创建主题轻而易举。至少需要提供 bgfg

const myTheme = {
  bg: '#0f0f0f',
  fg: '#e0e0e0',
}

const svg = renderMermaidSVG(diagram, myTheme)

想要更丰富的颜色?添加任意可选增强色:

const myRichTheme = {
  bg: '#0f0f0f',
  fg: '#e0e0e0',
  accent: '#ff6b6b',  // Pop of color for arrows
  muted: '#666666',   // Subdued labels
}

完整 Shiki 兼容性

通过 Shiki 集成,可直接使用任意 VS Code 主题。这样你就能访问数百个社区主题:

import { getSingletonHighlighter } from 'shiki'
import { renderMermaidSVG, fromShikiTheme } from 'beautiful-mermaid'

// Load any theme from Shiki's registry
const highlighter = await getSingletonHighlighter({
  themes: ['vitesse-dark', 'rose-pine', 'material-theme-darker']
})

// Extract diagram colors from the theme
const colors = fromShikiTheme(highlighter.getTheme('vitesse-dark'))

const svg = renderMermaidSVG(diagram, colors)

fromShikiTheme() 函数会智能地将 VS Code 编辑器颜色映射到图表角色:

编辑器颜色 图表角色
editor.background bg
editor.foreground fg
editorLineNumber.foreground line
focusBorder / keyword token accent
comment token muted
editor.selectionBackground surface
editorWidget.border border

支持的图表

流程图

graph TD
  A[Start] --> B{Decision}
  B -->|Yes| C[Process]
  B -->|No| D[End]
  C --> D

支持所有方向:TD(自上而下)、LR(从左到右)、BT(自下而上)、RL(从右到左)。

状态图

stateDiagram-v2
  [*] --> Idle
  Idle --> Processing: start
  Processing --> Complete: done
  Complete --> [*]

时序图

sequenceDiagram
  Alice->>Bob: Hello Bob!
  Bob-->>Alice: Hi Alice!
  Alice->>Bob: How are you?
  Bob-->>Alice: Great, thanks!

类图

classDiagram
  Animal <|-- Duck
  Animal <|-- Fish
  Animal: +int age
  Animal: +String gender
  Animal: +isMammal() bool
  Duck: +String beakColor
  Duck: +swim()
  Duck: +quack()

ER 图

erDiagram
  CUSTOMER ||--o{ ORDER : places
  ORDER ||--|{ LINE_ITEM : contains
  PRODUCT ||--o{ LINE_ITEM : "is in"

内联边样式

使用 linkStyle 覆盖边的颜色和描边宽度——就像 Mermaid 的 linkStyle:

graph TD
  A --> B --> C
  linkStyle 0 stroke:#ff0000,stroke-width:2px
  linkStyle default stroke:#888888
语法 效果
linkStyle 0 stroke:#f00 按索引(从 0 开始)为单条边设置样式
linkStyle 0,2 stroke:#f00 一次为多条边设置样式
linkStyle default stroke:#888 应用于所有边的默认样式

按索引设置的样式会覆盖默认样式。支持的属性:strokestroke-width

适用于流程图和状态图。

XY 图表

柱状图、折线图及其组合——使用 Mermaid 的 xychart-beta 语法。

柱状图:

xychart-beta
    title "Monthly Revenue"
    x-axis [Jan, Feb, Mar, Apr, May, Jun]
    y-axis "Revenue ($K)" 0 --> 500
    bar [180, 250, 310, 280, 350, 420]

折线图:

xychart-beta
    title "User Growth"
    x-axis [Jan, Feb, Mar, Apr, May, Jun]
    line [1200, 1800, 2500, 3100, 3800, 4500]

柱状图 + 折线图组合:

xychart-beta
    title "Sales with Trend"
    x-axis [Jan, Feb, Mar, Apr, May, Jun]
    bar [300, 380, 280, 450, 350, 520]
    line [300, 330, 320, 353, 352, 395]

水平方向:

xychart-beta horizontal
    title "Language Popularity"
    x-axis [Python, JavaScript, Java, Go, Rust]
    bar [30, 25, 20, 12, 8]

坐标轴配置:

  • 分类 x 轴:x-axis [A, B, C]
  • 数值 x 轴范围:x-axis 0 --> 100
  • 坐标轴标题:x-axis "Category" [A, B, C]
  • Y 轴范围:y-axis "Score" 0 --> 100

多系列: 添加多个 bar 和/或 line 声明。每个系列会从基于主题强调色的单色调色板中获得一种独立颜色。

XY 图表样式

图表渲染器遵循受 Apple 和 Craft 启发的简洁、极简设计理念:

  • 点状网格 — 绘图区域以微妙的点状图案填充,而非传统的实线网格
  • 圆角柱条 — 所有柱条边角均做圆角处理,呈现现代、精致的外观
  • 平滑曲线 — 折线系列采用自然三次样条插值,在所有数据点之间生成数学上平滑的曲线(而非直线段或阶梯状折线)
  • 浮动标签 — 无可见坐标轴线或刻度线;标签自由浮动,营造简洁清爽的视觉效果
  • 投影线条 — 每条折线系列下方都有微妙阴影,以增强层次感
  • 单色调色板 — 系列 0 使用主题的强调色;其余系列在同一色相下获得更深/更浅的色调,并带有微妙的色相偏移,可自动适配浅色或深色背景
  • 交互式工具提示 — 使用 interactive: true 渲染时,悬停在柱条或数据点上会显示数值工具提示。当多个系列共享同一 x 位置时,会显示多行工具提示
  • 稀疏折线点 — 数据点不超过 12 个的折线默认显示数据点标记,以提升可读性
  • 完整主题支持 — 全部 15 个内置主题(以及自定义主题)均适用于图表。强调色驱动整个系列调色板
  • 实时主题切换 — 图表系列颜色为 CSS 自定义属性(--xychart-color-N),因此主题变更可即时生效,无需重新渲染

ASCII 输出

适用于终端环境、CLI 工具,或任何需要纯文本的场景,可渲染为 ASCII 或 Unicode 制表符:

import { renderMermaidASCII } from 'beautiful-mermaid'

// Unicode mode (default) — prettier box drawing
const unicode = renderMermaidASCII(`graph LR; A --> B`)

// Pure ASCII mode — maximum compatibility
const ascii = renderMermaidASCII(`graph LR; A --> B`, { useAscii: true })

Unicode 输出:

┌───┐     ┌───┐
│   │     │   │
│ A │────►│ B │
│   │     │   │
└───┘     └───┘

ASCII 输出:

+---+     +---+
|   |     |   |
| A |---->| B |
|   |     |   |
+---+     +---+

ASCII 选项

renderMermaidASCII(diagram, {
  useAscii: false,      // true = ASCII, false = Unicode (default)
  paddingX: 5,          // Horizontal spacing between nodes
  paddingY: 5,          // Vertical spacing between nodes
  boxBorderPadding: 1,  // Padding inside node boxes
  colorMode: 'auto',    // 'none' | 'auto' | 'ansi16' | 'ansi256' | 'truecolor' | 'html'
  theme: { ... },       // Partial<AsciiTheme> — override default colors
})

ASCII XY 图表

XY 图表可使用专用图表绘制字符渲染为 ASCII:

  • 柱状图 块(Unicode)或 #ASCII 模式)
  • 折线图 — 带圆角的阶梯式路由:╭╮╰╯│─Unicode)或 +|-ASCII
  • 多系列 — 每个系列从主题的强调色调色板中获得一种独立的 ANSI 颜色
  • 图例 — 存在多个系列时自动显示
  • 水平图表 — 完全支持,分类位于 y 轴

API 参考

renderMermaidSVG(text, options?): string

将 Mermaid 图表渲染为 SVG。同步执行。自动检测图表类型。

参数:

  • text — Mermaid 源代码
  • options — 可选的 RenderOptions 对象

RenderOptions

选项 类型 默认值 说明
bg string #FFFFFF 背景色(或 CSS 变量)
fg string #27272A 前景色(或 CSS 变量)
line string? 边/连接线颜色
accent string? 箭头、高亮
muted string? 次要文本、标签
surface string? 节点填充色调
border string? 节点描边颜色
font string Inter 字体族
transparent boolean false 以透明背景渲染
padding number 40 画布内边距(px
nodeSpacing number 24 同级节点之间的水平间距
layerSpacing number 40 层与层之间的垂直间距
componentSpacing number 24 不连通组件之间的间距
thoroughness number 3 交叉最小化尝试次数(1-7,数值越高效果越好但速度越慢)
interactive boolean false 在 XY 图表的柱条和数据点上启用悬停工具提示

XY 图表:xychart-beta 开头的图表会自动识别——无需单独函数。accent 颜色选项决定图表系列的颜色调色板。

renderMermaidSVGAsync(text, options?): Promise<string>

renderMermaidSVG() 的异步版本。输出相同,返回 Promise<string>。适用于异步服务器处理器或数据加载器。

renderMermaidASCII(text, options?): string

将 Mermaid 图表渲染为 ASCII/Unicode 文本。同步方法。

AsciiRenderOptions

选项 类型 默认值 说明
useAscii boolean false 使用 ASCII 而非 Unicode
paddingX number 5 水平节点间距
paddingY number 5 垂直节点间距
boxBorderPadding number 1 内部框内边距
colorMode string 'auto' 'none''auto''ansi16''ansi256''truecolor''html'
theme Partial<AsciiTheme> 覆盖 ASCII 输出的默认颜色

parseMermaid(text): MermaidGraph

将 Mermaid 源码解析为结构化图对象(用于自定义处理)。

fromShikiTheme(theme): DiagramColors

从 Shiki 主题对象中提取图表颜色。

THEMES: Record<string, DiagramColors>

包含全部 15 个内置主题的对象。

DEFAULTS: { bg: string, fg: string }

默认颜色(#FFFFFF / #27272A)。


致谢

ASCII 渲染引擎基于 mermaid-ascii by Alexander Grooff。我们将其从 Go 移植到 TypeScript,并扩展了以下功能:

  • 时序图(Sequence diagram)支持
  • 类图(Class diagram)支持
  • ER 图(ER diagram)支持
  • Unicode 框线绘制字符
  • 可配置的间距与内边距

感谢 Alexander 提供的优秀基础!


许可证

MIT — 详见 LICENSE


Craft 团队用心打造