news 2026/8/7 17:12:47

Excalidraw与Mermaid结合:代码化绘图新体验

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Excalidraw与Mermaid结合:代码化绘图新体验

Excalidraw 与 Mermaid 结合:当代码遇上手绘

在一次远程架构评审会上,团队花了整整十分钟才把一张 Visio 绘制的系统图调整到所有人都能看清的状态——字体太小、连线交叉、颜色混乱。更糟的是,会后有人提出修改建议时,没人愿意再去打开那个复杂的图形文件重画一遍。

这并非个例。在技术文档、产品设计和团队协作中,图表的“写、改、看、存”始终是个痛点。我们想要清晰的逻辑表达,又希望视觉上不那么冰冷;需要版本可控,还得让非技术人员也能参与编辑。传统的图形工具和纯代码绘图方案各执一端,却都难以兼顾。

直到 Excalidraw 和 Mermaid 的出现,以及它们之间意想不到的化学反应。


Excalidraw 最初吸引人的,是它那仿佛用铅笔随手勾勒出来的线条。这种“不完美”的手绘风格意外地降低了沟通的心理门槛——没有人会觉得这张图已经“定稿”,反而更愿意拿起虚拟笔加入批注或调整。它的底层其实非常工程化:每个图形都是一个带有x,y,width,height的 JSON 对象,连那条歪歪扭扭的直线,也是通过算法对路径点添加轻微扰动生成的。

import { Excalidraw } from "excalidraw"; import { exportToSvg } from "@excalidraw/excalidraw"; const App = () => { const excalidrawRef = useRef(null); const saveAsSVG = async () => { if (excalidrawRef.current) { const canvas = excalidrawRef.current.getSceneElements(); const svg = await exportToSvg({ elements: canvas }); const blob = new Blob([svg.outerHTML], { type: "image/svg+xml" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "diagram.svg"; a.click(); } }; return ( <> <Excalidraw ref={excalidrawRef} /> <button onClick={saveAsSVG}>导出为 SVG</button> </> ); };

这段代码看似普通,但它揭示了一个关键能力:整个画布状态可以被完全序列化为数据结构。这意味着你可以把一张图当作对象来操作——保存、传输、比对、甚至用程序生成。这为自动化打开了大门。

而另一边,Mermaid 正在悄悄改变开发者写文档的方式。不再拖拽形状,而是像写代码一样描述图表:

graph LR subgraph "前端" A[React App] --> B[Nginx] end subgraph "后端" B --> C[Node.js API] C --> D[(PostgreSQL)] end style A fill:#f9f,stroke:#333 style D fill:#bbf,stroke:#000

短短几行文本,就能定义出包含分组、连接关系和样式的完整架构图。更重要的是,它天然支持 Git 版本控制。每次改动都是一次 diff,而不是替换整张图片。配合 CI 工具,甚至可以在提交代码时自动更新文档中的拓扑图。

npm install -g @mermaid-js/mermaid-cli mmdc -i diagram.mmd -o output.png -b transparent --scale 2

但问题也来了:Mermaid 生成的图虽然准确,却总显得过于规整,缺乏温度。尤其在面向业务方汇报或组织头脑风暴时,那种标准矢量图带来的距离感很难打破。

于是有人开始想:能不能让 Mermaid 的“脑”和 Excalidraw 的“手”结合起来?


设想这样一个场景:你刚完成一个微服务拆分的设计,用 Mermaid 写好了流程图。现在要拉会评审。过去你需要导出 PNG 插入 PPT,而现在,你运行一个脚本:

# 伪代码示意 mermaid_ast = parse_mermaid("diagram.mmd") elements = [] for node in mermaid_ast.nodes: elements.append({ "type": "rectangle", "x": calculate_x(node), "y": calculate_y(node), "width": 120, "height": 60, "text": node.label, "backgroundColor": "#ffffff", "strokeColor": "#000000", "roughness": 2 # 增加手绘感 }) for edge in mermaid_ast.edges: elements.append({ "type": "arrow", "points": get_bezier_points(edge.start, edge.end), "strokeColor": "#555", "roughness": 3 }) save_as_excalidraw(elements, "output.excalidraw")

几秒钟后,一张带有手绘质感的架构图就出现在 Excalidraw 白板中。你分享链接,团队成员陆续加入。有人觉得某个模块位置不合理,直接拖动;有人用红笔圈出潜在瓶颈;产品经理顺手加上几个用户触点图标……讨论结束时,这张图已经不再是最初的机械复现,而是一个集体智慧的结晶。

这才是真正理想的协作状态:机器负责结构正确性,人类专注创意与表达

不过这条路并不平坦。Mermaid 使用 Dagre 进行自动布局,输出的是紧凑有序的节点排列;而 Excalidraw 完全依赖手动定位。如果直接映射坐标而不做预计算,很可能得到一堆重叠在一起的方框。解决方案通常是先模拟布局引擎,在转换阶段估算出合理的间距和层级。

另一个挑战是样式映射。Mermaid 支持 CSS 类定义,比如.classDef database fill:#00f,stroke:#000;,但在 Excalidraw 中没有“类”的概念,只能逐个元素设置填充色和描边。这就需要建立一个样式映射表,在解析 AST 时动态替换。

还有交互性的保留问题。如果你从 Mermaid 生成了一张图并导入 Excalidraw,后续能否继续编辑?答案是可以,但前提是导出的 JSON 必须包含完整的元信息,比如元素 ID、层级顺序、是否锁定等。否则一旦打乱,就无法再与原始代码对应。

性能也不能忽视。当图表规模超过百个节点时,Excalidraw 的渲染可能会变慢。这时候可以考虑分模块加载,或者启用懒加载策略,只渲染可视区域内的元素。


有意思的是,这个组合正在催生新的工作模式。

有些团队已经开始在 PR 描述中附带 Mermaid 图,并自动生成对应的 Excalidraw 链接。审查者可以直接点击进入白板,在图上标注疑问或建议。这种“可交互的技术评审”极大地提升了反馈质量。

教育领域也在尝试类似做法。老师让学生先用 Mermaid 编写流程图代码,强制理解逻辑结构;然后导入 Excalidraw 手动美化,加深对布局和视觉层次的理解。比起单纯画图,这种方式更能培养系统思维。

甚至有项目尝试接入 AI。输入一句自然语言:“画一个前后端分离的登录流程”,AI 先生成 Mermaid 代码,再自动转为 Excalidraw 格式,最终呈现为一张可供编辑的手绘草图。整个过程无需人工编码,却又保持了可追溯性和可修改性。

当然,目前还没有成熟的通用转换器能完美处理所有 Mermaid 语法。复杂的甘特图、时序图仍然难以还原。但对于最常见的流程图、架构图来说,基础映射已经足够实用。


这种融合背后,其实反映了一种更深层的趋势:我们不再满足于“要么全手动,要么全自动”的二元选择

代码化绘图解决了可维护性问题,但牺牲了灵活性;
传统绘图工具提供了自由度,却难以纳入工程体系。

Excalidraw + Mermaid 的尝试告诉我们,或许真正的未来在于“混合范式”——用机器生成初稿,由人进行创造性润色;用代码定义语义,用界面传递情感。

就像程序员不需要从零开始写每一行汇编,未来的图表创作者也不必纠结于“该用鼠标还是键盘”。他们会说:“我用 Mermaid 描述我想表达的逻辑,然后交给工具变成一张好看的手绘图,大家一起来改。”

这听起来有点理想主义,但技术的进步往往始于这样的跨界想象。

某种意义上,这张带着轻微抖动的手绘线,不只是视觉风格的选择,更像是在告诉所有人:“这里欢迎修改,欢迎涂鸦,欢迎你不完美的想法。”

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 18:36:06

Maven二方库

Maven二方库依赖是指在Maven项目中&#xff0c;依赖由同一组织或团队内部&#xff08;非第三方开源组织&#xff09;开发并发布的库&#xff08;JAR包&#xff09;。 核心概念区分 1. 一方库 指当前项目自身的模块在项目内部直接进行模块拆分通过 <module> 在父pom中声明…

作者头像 李华
网站建设 2026/8/7 1:33:28

21、Windows系统实用工具与控制面板全解析

Windows系统实用工具与控制面板全解析 在使用Windows系统的过程中,我们会遇到各种各样的需求,而系统自带的许多实用工具和控制面板中的功能,能帮助我们更好地管理和使用计算机。下面将为大家详细介绍这些实用功能。 系统还原(System Restore) 系统还原是一项非常实用的…

作者头像 李华
网站建设 2026/8/7 15:17:12

23、Windows系统设置与相关术语详解

Windows系统设置与相关术语详解 1. 安全中心(Security Center) 在控制面板窗口处于分类视图(Category View)时,点击“安全中心”链接,Windows会打开“Windows安全中心”对话框。在此对话框中,你可以对计算机的防火墙、自动更新和病毒防护选项进行开启或关闭操作(不建…

作者头像 李华
网站建设 2026/8/7 18:36:06

Excalidraw如何助力初创团队低成本启动项目?

Excalidraw如何助力初创团队低成本启动项目&#xff1f; 在一次深夜的远程会议中&#xff0c;三位联合创始人围坐在各自的屏幕前&#xff0c;试图梳理新产品的系统架构。白板软件卡顿、工具操作复杂、沟通断层频发——原本计划一小时完成的设计讨论&#xff0c;最终拖成了四个小…

作者头像 李华
网站建设 2026/8/7 0:54:06

【光子AI】MCP 跟 Function Calling 的本质区别全解析

【光子AI】MCP 跟 Function Calling 的本质区别全解析 文章目录 【光子AI】MCP 跟 Function Calling 的本质区别全解析 一、一句话本质区别 二、定位层级对比(非常关键) 三、能力边界对比 1️⃣ Function Calling 能做什么? 2️⃣ MCP 能做什么? 四、工程视角:能力对照表 …

作者头像 李华
网站建设 2026/8/6 15:25:52

测量仪表的特性

万用表的内阻简 介&#xff1a; 本文探讨了测量仪表内阻对测量结果的影响及误差来源。通过实验展示了电压表内阻与被测电源内阻匹配的重要性&#xff0c;当两者均为10kΩ时测量误差高达50%。文章分析了系统误差和随机误差两大类误差来源&#xff0c;重点说明仪表内阻、频带宽度…

作者头像 李华