当前位置: 首页 > news >正文

React+bpmn.js实现基本流程图(一)

效果如图:

项目背景

最近的项目使用的React,需要用到bpmn-js来设计流程图。项目中使用的各插件版本

//package.json { "react": ">=18.0.0", "react-dom": ">=18.0.0", "bpmn-js": "^18.8.0", "antd": "^5.0.0", "less": "^4.5.1", "less-loader": "^7.0.0" }

我用的React v18版本,低于18版本的自行修改React语法

bpmn-js基础使用示例

1. 安装依赖

npm install bpmn-js

2. 创建BPMN组件

2.1 基本组件 /BpmnModelerWidget/index.tsx

import React, { useEffect, useRef, useState } from 'react'; import BpmnModeler from 'bpmn-js/lib/Modeler'; import 'bpmn-js/dist/assets/diagram-js.css'; import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'; import 'bpmn-js/dist/assets/bpmn-js.css'; import { defXmlStr } from "./xmlStr"; import './styles.less' const BpmnModelerWidget = ({ initialXml, onSave }) => { const containerRef = useRef(null); const modelerRef = useRef(null); const [xml, setXml] = useState(''); const [error, setError] = useState(null); useEffect(() => { // 初始化建模器 modelerRef.current = new BpmnModeler({ container: containerRef.current }); // 加载初始XML if (initialXml) { loadDiagram(initialXml); } else { createNewDiagram(); } // 监听变化 modelerRef.current.on('commandStack.changed', async () => { try { const { xml: newXml } = await modelerRef.current.saveXML({ format: true }); setXml(newXml); } catch (err) { console.error('Failed to save XML', err); } }); return () => { modelerRef.current?.destroy(); }; }, []); const loadDiagram = async (xml) => { try { await modelerRef.current.importXML(xml); const canvas = modelerRef.current.get('canvas'); canvas.zoom('fit-viewport'); setError(null); } catch (err) { setError('Failed to load diagram'); console.error(err); } }; const createNewDiagram = async () => { const newDiagram = defXmlStr('New_Process', 'New Process') await loadDiagram(newDiagram); }; const handleImport = async (event) => { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = async (e) => { const xml = e.target.result; try { await modelerRef.current.importXML(xml); } catch (err) { console.error('Failed to import diagram:', err); } }; reader.readAsText(file); } }; const handleSave = async () => { try { const { xml: savedXml } = await modelerRef.current.saveXML({ format: true }); if (onSave) { onSave(savedXml); } } catch (err) { console.error('Failed to save', err); } }; const handleExportBPMN = async () => { try { const { xml } = await modelerRef.current.saveXML({ format: true }); const blob = new Blob([xml], { type: 'application/xml' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'diagram.bpmn'; a.click(); URL.revokeObjectURL(url); } catch (err) { console.error('Failed to export diagram:', err); } } const handleExportSVG = async () => { try { const { svg } = await modelerRef.current.saveSVG(); const blob = new Blob([svg], { type: 'image/svg+xml' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'diagram.svg'; a.click(); URL.revokeObjectURL(url); } catch (err) { console.error('Failed to export SVG', err); } }; return ( <div className="bpmn-modeler"> {error && <div className="error">{error}</div>} <div className="toolbar"> <button onClick={createNewDiagram}>新建</button> <input type="file" accept=".bpmn" onChange={handleImport} /> <button onClick={handleSave}>保存</button> <button onClick={handleExportBPMN}>导出BPMN</button> <button onClick={handleExportSVG}>导出SVG</button> </div> <div id='canvas' className='modeler-container' ref={containerRef} /> </div> ); }; export default BpmnModelerWidget;

2.2 默认字符串 /BpmnModelerWidget/xmlStr.tsx

/** * bpmn默认字符串 * @param flowKey 流程标识 * @param flowName 流程名称 * @returns 默认的xml:只包含开始节点 */ export const defXmlStr = (flowKey?: string, flowName?: string) => `<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" targetNamespace="http://bpmn.io/schema/bpmn"> <process id="${flowKey}" name="${flowName}" isExecutable="true"> <startEvent id="Event_0m4asyn" /> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="${flowKey}"> <bpmndi:BPMNShape id="Event_0m4asyn_di" bpmnElement="Event_0m4asyn"> <dc:Bounds x="232" y="182" width="36" height="36" /> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>`;

2.3 样式文件 /BpmnModelerWidget/styles.less

.bpmn-modeler { height: 100%; position: relative; .toolbar { position: absolute; bottom: 10px; left: 10px; z-index: 2; button { cursor: pointer; margin: 0 5px; } input { width: 76px; } } .modeler-container { width: 100%; height: 100%; background: #fdf5eb; .bjs-container { /* 圆点背景 */ background: radial-gradient(circle at 0.5px 0.5px, #999 0.5px, transparent 0); background-size: 10px 10px; //圆点间隔(自定义值) 第一值是左右间隔 第二个值是上下间隔 } } }

这样就完成了一个基本的流程设计器,后续使用过程中会记录更多的使用功能。

代码仓库

完整代码已上传至 https://gitee.com/z-beast/bpmn-logic-flowchart

http://www.jsqmd.com/news/1399049/

相关文章:

  • 免费PDF工具实测:PDF补丁丁三步上手,书签合并提取一次搞定
  • 探索韩国美食之旅:精选进口食品批发商全揭秘 - 官方资讯
  • 揭秘邯郸领创中专:如何联系招生办获取最新入学资讯 - 官方资讯
  • 电脑上的时间都去哪儿了?免费的 Windows 时间追踪工具 Tai 帮你把每一分钟算明白
  • GLM-5.3发布:基座不变、编程提升50%,后训练红利下的开发者新机会
  • 国内工作服定制厂家哪家强?广东牧马人领衔三大**企业解析 - 变量人生001
  • 景德镇珠山区房屋漏水维修靠谱商家推荐(2026 新):精准测漏维修 - 超人防水
  • Windows 看图神器 voidImageViewer 用起来有多爽?GIF/WEBP 动画流畅播放的秘密全公开
  • League Akari 英雄联盟玩家终极效率工具箱完整指南:自动选人、战绩分析与游戏流程一键搞定
  • 为什么需要react-merge-refs?解决React组件开发中的refs冲突难题
  • 小学生学C++编程语法知识(C++申请内存与释放内存)
  • 探索异国风味:韩国进口美食批发首选指南 - 官方资讯
  • Navicat无限试用实操:mac版14天试用期一键重置完整指南
  • 数据结构-Data Structure (顺序表专题)
  • 从零构建AI智能体:一份适合新手速通的实战通关地图
  • Snipe-IT Docker部署实战:5步搭建免费IT资产管理系统,附持久化与备份方案
  • 探索未来,领创中等专业学校招生热线全面开放 - 官方资讯
  • 2026年国内工作服定制生产厂家推荐:广东牧马人领衔三大实力派企业 - 变量人生001
  • 中国象棋AI连线工具终极上手指南:3步让Vin象棋替你盯盘、算棋、落子
  • 避开中介引流店铺,认准线下实景门店,武汉黄金回收参考 - 资讯早知道
  • 《ArrayList的初始化和扩容源代码解读》
  • ExPose:革命性单目3D人体姿态估计技术,一键实现精准的身体形状与表情捕捉
  • 告别 30 天倒计时:KMS_VL_ALL_AIO 让 Windows 与 Office 激活一步到位
  • 免费开源的Windows时间统计工具Tai:三步装好,一周后你就再也不会问“时间去哪了“
  • 找不到PS3游戏更新补丁?这份开源下载器上手手册帮你一次搞定
  • 2026年韩国进口食品批发商推荐:行业**引领新趋势 - 官方资讯
  • scrcpy 连接总翻车?新手绕开这 6 类坑,安卓投屏一次就成
  • 揭秘邯郸市领创中等专业学校招生热线,家长学生必看! - 官方资讯
  • 2026马年新春创意线上投票活动方案推荐[最新合集]
  • 掌握OCaml异步编程:Jane Street Workshop中的Async库应用教程