30分钟用maxGraph从零搭一个能拖拽的流程图编辑器

📅 2026/8/14 14:13:58
30分钟用maxGraph从零搭一个能拖拽的流程图编辑器
30分钟用maxGraph从零搭一个能拖拽的流程图编辑器【免费下载链接】maxGraphmaxGraph is a fully client side JavaScript diagramming library项目地址: https://gitcode.com/gh_mirrors/ma/maxGraph先别急着找流程图生成网站。想象一下这个场景你刚给产品经理画完一版业务流程图第二天需求变了三个节点、两条线你只能重新画一遍——如果是静态图片意味着推倒重来如果手写 SVG 坐标光是对齐就够喝一壶。而用 maxGraph这个纯客户端的 TypeScript 图表库你画出来的不是一张图而是一套能被代码驱动、能响应用户操作、能自动排版的图表应用。今天我就带你从零把它跑起来。画图不难难的是能改、能存、能交互市面上画图方案其实不少但大多数都卡在同一个地方图是静态的。用图片或 SVG 硬编码每次改需求都要重新出图节点位置全靠手算坐标图一多直接心态爆炸用在线画图工具导出的图无法被程序读取更别说让用户拖拽、缩放、连线用商业图表库功能是够了但价格贵、闭源想定制一个泳道样式都得看厂商脸色。maxGraph 正好补上这个缺口。它管理着图表世界的三块基石顶点矩形、圆形乃至你自定义的形状、边连接顶点的线、箭头、分组类似文件夹把相关元素装在一起。在这之上它还能做布局算法、图论运算和深度的 API 控制。它的身世也值得一提2020 年老牌库 mxGraph 归档停更后社区 fork 出 maxGraph 接棒维护原生用 TypeScript 重写同时保留了 mxGraph 的 XML 兼容性——这意味着老项目的数据文件还能接着用。对于开发者的钱包和硬盘它也很友好零第三方依赖JS 代码符合 ES2020 规范同时提供 CommonJS 和 ES Module 两种格式支持 tree-shaking按需打包想在 React、Vue 还是原生 JS 里用都行。第一个可运行的 demo一个矩形、一个圆、一条线先装包这一步没什么悬念npm install maxgraph/core注意一个前提maxGraph 需要配合构建工具webpack、Vite 等使用不支持直接script标签引入这也是后面避坑指南要细说的点。在 HTML 里准备一个容器元素div idgraph-container stylewidth: 100%; height: 500px/div然后写入口代码。下面这段就是官方入门示例的完整版我把每行的意图都标了出来import {type CellStyle, Graph, InternalEvent} from maxgraph/core; // 1. 拿到页面上的容器图表会渲染进这个 div const container document.getElementById(graph-container) as HTMLElement; // 2. 屏蔽浏览器自带的右键菜单否则后面拖拽平移会和它打架 InternalEvent.disableContextMenu(container); // 3. 创建图表实例一切从这里开始 const graph new Graph(container); // 4. 开启平移按住鼠标右键拖动即可移动画布 graph.setPanning(true); // 5. batchUpdate 把多次增删改打包成一次事务 // 好处有两个撤销历史更干净、批量渲染更高效 graph.batchUpdate(() { // 插入第一个顶点一个 100x100 的矩形位置在 (10, 10) const rectangle graph.insertVertex({ position: [10, 10], size: [100, 100], value: 矩形节点, // 显示在节点上的文字 }); // 插入第二个顶点一个橙色的圆形位置 (350, 90) const circle graph.insertVertex({ position: [350, 90], size: [50, 50], style: { fillColor: orange, shape: ellipse, // 形状换成椭圆 }, value: 圆形节点, }); // 用一条线把两个节点连起来 graph.insertEdge({ source: rectangle, target: circle, value: 连接线, style: { edgeStyle: orthogonalEdgeStyle, // 直角拐弯的连接线 rounded: true, // 拐角处加圆角 }, }); });跑起来你会看到类似这样的效果——而且注意这个图是活的你可以拖动节点、移动画布、选中元素到这里一个最小可用图表就诞生了。insertVertex和insertEdge是你日后最常打交道的两个 API前者负责摆东西后者负责连东西。三个每天都会用到的核心能力demo 能跑只是起点真正让 maxGraph 值钱的是下面三件事。样式定制别让你的节点全都长一个样默认节点是朴素的白底黑边。想让所有节点统一风格改默认样式即可一次改动全图生效// 必须在任何 insertVertex 之前执行 const vertexStyle graph.getStylesheet().getDefaultVertexStyle(); vertexStyle.rounded true; // 直角变圆角 vertexStyle.dashed true; // 边框变虚线 vertexStyle.strokeWidth 2; // 边框加粗到 2 像素 vertexStyle.strokeColor green; // 边框变绿效果对比很直观——左边是默认样式右边是加了圆角、虚线、绿色边框之后的节点而如果只想某个节点特殊一点就在它自己的insertVertex配置里写style就像 demo 里橙色圆形那样。maxGraph 单节点可配置的样式属性有 100 多个从填充色、透明度到图标、形状基本覆盖你见过的所有图表风格。事件监听让图表知道用户干了什么图表是给人用的就得能响应用户操作。addListener是通往交互世界的大门// 用户点击某个单元格时触发 graph.addListener(InternalEvent.CLICK, (_sender, evt) { const cell evt.getProperty(cell); if (cell) { console.log(你点击了单元格:, cell); // 在这里可以做任何事弹详情、高亮相关节点、打开编辑面板…… } }); // 用户移动单元格时触发 graph.addListener(InternalEvent.CELLS_MOVED, (_sender, evt) { const cells evt.getProperty(cells); console.log(本次共移动了 ${cells.length} 个单元格); });这种事件机制覆盖了点击、移动、新增、删除、样式变更等几乎所有图的变化是后续做点击节点弹出详情拖拽完成自动保存这类功能的基石。布局算法把位置交给代码去算手摆节点摆到 30 个就烦了。maxGraph 内置了层级、树状、圆形、力导向organic、泳道等多种布局算法你需要做的只是喂数据、喊开始import {HierarchicalLayout} from maxgraph/core; // 1. 先按层级关系把节点和连线加进图里坐标随便给布局会重排 graph.batchUpdate(() { // ...一堆 insertVertex / insertEdge... }); // 2. 创建层级布局实例适合流程图、组织架构图 const layout new HierarchicalLayout(graph); // 3. 一句 execute所有节点自动对齐成层级树 layout.execute(graph.getDefaultParent());配上泳道swimlane之后复杂的业务流程也能排得清清楚楚如果你的图是关系型的可以换用FastOrganicLayout力导向布局模拟物理引力把节点弹开几行代码就能让乱成一团的网络图自动舒展开。踩坑预警新手最容易翻车的 4 个地方先别急着复制代码看看这几个坑能帮你省下至少一晚上的调试时间。坑一直接script引入会报错。maxGraph 要求通过打包器使用。它给你的maxgraph/core包自带 ESM 和 CommonJS 两种格式配合 Vite、Webpack 都顺畅但别指望在纯 HTML 里裸奔。项目里提供了packages/ts-example、packages/js-example等现成工程模板可以直接照着抄配置。坑二忘了禁用右键菜单。在容器上调用InternalEvent.disableContextMenu(container)几乎应该成为固定仪式。否则浏览器的原生右键菜单会跟 maxGraph 自己的交互抢地盘尤其是开启平移、框选之后体验会非常割裂。坑三所有修改要放进batchUpdate。初学者容易一条条调用insertVertex图能出来但性能差、撤销历史乱。把一批操作塞进batchUpdate(() {...})里会被当成一次原子操作——一次渲染、一步撤销这也是官方示例的标准姿势。坑四坐标是相对父节点的。一旦用了分组子节点的position是相对于父容器算的不是全局坐标。这个细节在画复杂嵌套结构时特别容易踩改位置之前先想清楚它属于哪个层级。进阶玩法从能看到能用demo 和样式只是热身。当你的图开始承载真实业务下面两招会让它质变。分组 折叠复杂度管理。图一多人的眼睛就处理不过来了。用groupCells把相关节点装进一个父节点再配合折叠collapse/expand功能可以把几十个节点收成一个图标需要时再展开。maxGraph 还支持 drill-down下钻——双击某个分组直接进入它的子图去编辑就像在文件系统里层层打开文件夹XML 序列化让图能存、能传。图的最终归宿往往是保存下来、下次再打开。maxGraph 沿用 mxGraph 的 XML 格式持久化就是两行代码的事import {ModelXmlSerializer} from maxgraph/core; // 保存把整个图的数据模型导出成 XML 字符串 const xml new ModelXmlSerializer(graph.getDataModel()).export(); // 加载把 XML 字符串还原成一张完整的图 new ModelXmlSerializer(graph.getDataModel()).import(xml);导出后的 XML 可以存到数据库、写进文件或者发给后端做数据流转。这也是它适合做业务数据可视化而不是一次性插图的根本原因——图和数据是绑定的。哪些项目真正适合用 maxGraph不是所有图表需求都值得引入一个库但下面这几种场景maxGraph 几乎是量身定做的流程/工作流编辑器BPM 建模、审批流设计器泳道、分支、事件全支持网络拓扑与架构图设备连设备、服务调用服务配合力导向布局一键排布组织结构图部门层级天然就是树层级布局直接出图数据血缘可视化字段级的上下游依赖靠边和分组就能表达清楚。而且它和框架无关无论你的主工程是 React、Vue、Angular 还是纯原生都能接入。想看各种功能的真实效果仓库里的packages/html/stories存放了整套 Storybook 演示想从工程级案例起步packages/ts-example和packages/js-example分别展示了 TypeScript 和 JavaScript 的完整配置。深入 API 和概念packages/website/docs下的 manual手册与 usage用法目录是现成的参考手册。如果想动手改源码研究内部实现可以把这个仓库克隆到本地跑一遍示例git clone https://gitcode.com/gh_mirrors/ma/maxGraph。动起来给你的下一步建议回到开头的场景——如果你的流程图需求还在重新画一遍的循环里现在有了解法。maxGraph 让你做的不是画图而是构建一个能画图的程序节点数据化、连线可编程、布局自动化用户拖拽修改程序负责兜底。接下来怎么走我的建议是三步把文中的 demo 跑通亲手拖一拖节点感受一下活图和死图的区别挑一个你真实遇到的场景比如审批流、组织架构用insertVertexinsertEdge把它数据化加上事件监听和 XML 保存让图表和你的业务数据真正打通。半小时后回头看你会发现自己已经告别了画图工具迈进了图表应用开发者的行列。【免费下载链接】maxGraphmaxGraph is a fully client side JavaScript diagramming library项目地址: https://gitcode.com/gh_mirrors/ma/maxGraph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考