
在 react-pdf 文档中渲染 Mermaid 图表react-pdf/mermaid 完全指南【免费下载链接】react-pdf Create PDF files using React项目地址: https://gitcode.com/gh_mirrors/re/react-pdf导读本文基于 react-pdf 仓库中的 packages/mermaid/README.md 及其配套源码系统讲解如何使用react-pdf/mermaid在 react-pdf 文档中渲染 Mermaid 图表为 SVG。你将掌握从安装、基础用法、支持的六类图型到颜色/主题定制、尺寸控制、debug 排障的完整实操并通过源码级解析理解「Mermaid 定义 → SVG → react-pdf 原生 SVG 组件」的渲染管线及其在 Web Worker 环境下的适配原理。一、包定位与安装react-pdf/mermaid是 react-pdf 生态中专门用于在 PDF 文档内渲染 Mermaid 图表流程图、时序图、状态图、类图、ER 图、XY 图表的扩展包底层由 beautiful-mermaid 驱动。安装方式见 package.jsonyarn add react-pdf/mermaid环境要求来自 peerDependencies 声明react-pdf/renderer 4.8.1react^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0运行时依赖beautiful-mermaid、react-pdf/svgSVG 解析与react-pdf/primitivesSVG 元素类型定义。导出入口见 src/index.ts仅暴露Mermaid一个组件。二、快速开始在 PDF 中插入一张流程图Mermaid的使用方式与普通 react-pdf 组件一致将 Mermaid 图定义作为children字符串传入即可import { Document, Page, View } from react-pdf/renderer; import { Mermaid } from react-pdf/mermaid; const MyDocument () ( Document Page sizeA4 View style{{ padding: 30 }} Mermaid width{400} height{300} {graph TD A[Start] -- B{Decision} B --|Yes| C[OK] B --|No| D[End]} /Mermaid /View /Page /Document );图表定义使用模板字符串包裹其中保留换行与缩进即可无需额外转义。该组件可以直接嵌入View、Page等任意布局容器配合width/height参与 PDF 排版。三、支持的图类型README 明确列出以下六类 Mermaid 图型测试用例 tests/mermaid.test.jsx 逐类做了渲染快照验证类型语法关键字测试用例中的示例流程图graph TD/graph LR起止节点 菱形判断节点 条件分支时序图sequenceDiagramAlice-Bob: Hello Bob消息交互状态图stateDiagram-v2[*] -- Idle -- Processing -- Done -- [*]类图classDiagram类成员与方法、Animal |-- Dog继承关系ER 图erDiagramCUSTOMER \|\|--o{ ORDER : places关系标注XY 图表xychart-beta条形图含x-axis/y-axis/bar声明其中 XY 图表xychart-beta是渲染管线中较为特殊的一类它的柱形、网格线完全通过 CSS 类选择器着色因此需要额外的样式内联处理详见第五节。四、Props 全量参考组件属性定义见 src/Mermaid.tsxProp类型默认值说明childrenstring必填Mermaid 图定义文本widthnumber \| stringauto渲染 SVG 的宽度heightnumber \| stringauto渲染 SVG 的高度colorstringblack前景/文字颜色bgstring—背景颜色accentstring—强调色箭头、高亮linestring—连线/连接线描边颜色mutedstring—次要文字与标签颜色surfacestring—节点填充色borderstring—节点描边颜色transparentbooleanfalse使用透明背景themestring—内置主题名见第六节debugbooleanfalse为 SVG 元素添加可见边框便于排查布局4.1 尺寸控制与宽高比推导当只指定width或height其中之一时另一个维度会根据 SVGviewBox的宽高比自动推导实现等比例缩放两者都省略时则采用viewBox解析出的原始尺寸。从源码结构看这一逻辑由 src/mapSvg.tsx 中的resolveDimensions实现优先使用传入的宽高其次用height × aspectRatio或width / aspectRatio补齐缺失维度最后兜底为默认高度 22 并按宽高比推导宽度。因此传入width{400}即可保持图表比例不会拉伸变形。4.2 debug 模式debug用于给生成的 SVG 根元素添加可见边框帮助在 PDF 页面中快速定位图表的实际占位区域排查「图表渲染了但位置/大小不对」的布局问题渲染成品中请关闭该属性。五、颜色体系与主题定制5.1 从主题到调色板的展开theme属性接受内置主题名组件内部调用themeColors()将主题名展开为一组颜色见 src/render.ts。测试 tests/render.test.ts 验证了两个关键行为未知主题名返回空对象行为等同未传theme回退到 beautiful-mermaid 默认调色板不会抛错返回的是副本对展开结果做任何覆盖都不会污染THEMES常量本身。5.2 颜色 Props 的优先级与覆盖在 src/Mermaid.tsx 中theme展开后的调色板作为基础随后通过一系列if判断用显式传入的color/bg/accent/line/muted/surface/border/transparent逐项覆盖。因此显式颜色 prop 的优先级高于主题你可以先选一个主题再微调其中一两个颜色。5.3 派生色的自动计算未显式提供的派生色由 src/colorMix.ts 中的colorMix()在 sRGB 空间按百分比混合前景色与背景色得出等价于 CSS 的color-mix(in srgb, ...)。以 src/preprocessSvg.ts 的变量映射为例次要文字--_text-secmuted或前景 60% 背景连线--_lineline或前景 50% 背景箭头--_arrowaccent或前景 85% 背景节点填充--_node-fillsurface或前景 3% 背景接近背景色的淡色节点描边--_node-strokeborder或前景 20% 背景。这意味着即使只设置color与bg两个值整张图表也会自动生成一套和谐完整的配色。colorMix支持#RGB与#RRGGBB两种十六进制格式。六、内置主题一览通过theme属性可直接使用以下 15 个内置主题均来自 beautiful-mermaid 的THEMES常量风格主题名Tokyo Nighttokyo-night、tokyo-night-storm、tokyo-night-lightCatppuccincatppuccin-mocha、catppuccin-latteNordnord、nord-lightDraculadraculaGitHubgithub-dark、github-lightSolarizedsolarized-dark、solarized-lightOne Darkone-darkZinczinc-dark、zinc-light用法示例README 原例Mermaid themenord width{400} {graph LR A -- B -- C} /Mermaid值得注意的是主题本质上是「调色板」而非独立的渲染选项themeColors()会把主题展开成一组十六进制颜色后交给底层渲染因此主题色会真实作用于生成的 SVG测试中mermaidToSvg(graph, themeColors(nord))产出的 SVG 包含nord主题的背景色。七、渲染管线从 Mermaid 定义到 PDF 内 SVGMermaid组件在 src/Mermaid.tsx 中完成一次四步流水线这也是理解整包工作原理的核心Mermaid 文本 → mermaidToSvg() → preprocessSvg() → parseSvg() → mapSvgNode() → react-pdf SVG 组件树7.1 mermaidToSvgWeb Worker 环境适配src/render.ts 中的mermaidToSvg()调用 beautiful-mermaid 生成 SVG 字符串并包裹在inWorkerScope()中。这一步是踩坑后的关键修复底层的 elkjs 布局引擎在检测到「存在self但不存在document」即 Web Worker 形态时会误认为自己是独立 Worker 脚本转而接管onmessage而不是执行布局。inWorkerScope通过临时注入一个假的document让 elkjs 保持库模式并把只读的self重新定义为可写beautiful-mermaid 退出时会对其赋值渲染结束后再原样恢复全局作用域。这一行为有专门的测试 tests/workerScope.test.ts 覆盖在self是 getter 且无document的模拟 Worker 作用域中渲染成功且不污染onmessage、不残留document/self修改。因此该包可以安全运行于浏览器主线程与 Web Worker 两种环境下。7.2 preprocessSvgCSS 变量解析与样式内联beautiful-mermaid 产出的 SVG 大量依赖 CSS 自定义属性如var(--_line)与style块而 react-pdf 的 SVG 渲染器不支持这些机制。src/preprocessSvg.ts 的preprocessSvg()负责把它们翻译成 react-pdf 能理解的形式提取颜色从根节点style属性中解析--fg/--bg缺省回退#27272A/#FFFFFF并合并显式传入的颜色覆盖构建变量映射生成全套--bg、--fg、--_text、--_line、--_arrow等 CSS 变量并额外从 SVG 中抽取--xychart-color-N与--xychart-bar-fill-N系列见buildVariableMapsrc/preprocessSvg.ts递归解析 var()resolveVarReferences()迭代解析嵌套的var(--x, fallback)引用直至结果稳定并对剩余的color-mix()调用直接换算为混合后的十六进制色src/preprocessSvg.tsCSS 类样式内联解析style块中的类选择器支持.foo、path.foo、逗号分隔选择器把匹配到的fill、stroke、stroke-width、opacity、stroke-dasharray等 react-pdf 支持的展示属性以属性形式内联到元素上且不覆盖元素已存在的同名属性inlineCssStylessrc/preprocessSvg.ts清理移除全部style块、class属性、根节点style属性并解析属性值中的var()引用。步骤 4 正是xychart-beta图表柱形、网格线纯 CSS 类着色能正确着色的关键。7.3 parseSvg 与 mapSvgNode映射为原生组件预处理后的 SVG 字符串交给react-pdf/svg的parseSvg()解析为节点树再由 src/mapSvg.tsx 的mapSvgNode()递归映射为 react-pdf 的Svg、G、Path、Rect、Line、Circle、Ellipse、Polygon、Polyline、Text、Tspan、Defs、Marker等原生组件来自react-pdf/primitives的类型常量。映射过程中跳过xmlns、class、style、role、focusable、aria-hidden及data-*等 react-pdf 无关属性SKIP_ATTRSsrc/mapSvg.tsxcurrentColor值被解析为实际前景色color默认black数值型字符串属性如坐标、半径自动转为数字遇到不支持的 SVG 标签时若有子元素则降级用G包裹避免整图丢失。尺寸方面根svg的宽高在映射阶段由resolveDimensions()统一计算结合用户传入的width/height与viewBox宽高比并透传debug给Svg组件。八、验证与测试体系该包的质量由四组测试保障均可作为使用参考与回归基准tests/mermaid.test.jsx六类图型 自定义尺寸共 7 个用例渲染成图片后做快照比对覆盖 flowchart、sequence、state、class、er、xychart 及width300, height100的尺寸定制场景tests/render.test.ts验证themeColors()的主题展开、未知主题容错、返回值隔离以及主题色真实写入 SVGtests/preprocessSvg.test.ts验证 CSS 变量解析与样式内联的正确性tests/workerScope.test.ts验证 Web Worker 作用域下的渲染与全局环境恢复tests/colorMix.test.ts验证colorMix的十六进制混合结果。运行测试cd packages/mermaid yarn test # vitest九、使用建议与已知边界优先指定width或widthheight只给一个维度可等比缩放两者都不给时按源码兜底逻辑尺寸可能偏小默认高度 22 推导建议显式传宽以保证 PDF 中排版稳定。主题 单色微调先选theme获得成套配色再用color/line/accent等覆盖个别颜色如需浅色背景配合bg或transparent。children必须是字符串图定义应作为模板字符串传入而不是 JSX 子节点。Worker 环境可放心使用渲染层已针对 elkjs 的 Worker 探测做了兼容处理并有测试锁定不会干扰宿主环境的onmessage。图表内容越复杂PDF 体积与渲染耗时越高这与 SVG 路径数量的增加直接相关建议对大型图型做必要精简。十、总结react-pdf/mermaid以极简的组件化 API 补齐了 react-pdf 生态中「文档内嵌图表」的能力一个children字符串 若干样式属性即可把六类 Mermaid 图表以矢量 SVG 形式嵌入 PDF。其背后是一条精心设计的渲染管线——Worker 环境适配、CSS 变量解析、类样式内联、SVG 节点树映射——每一项都有对应源码与测试支撑。若你正在用 react-pdf 生成技术报告、架构文档或数据分析 PDF这个包可以直接开箱即用。【免费下载链接】react-pdf Create PDF files using React项目地址: https://gitcode.com/gh_mirrors/re/react-pdf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考