当前位置:   article > 正文

VUE+bpmn.js+iview 页面绘制流程图_bpmn-vue-iview

bpmn-vue-iview

前言:业务需求需要在页面绘制流程图,之前后台的同事都是在eclipse画的流程图,为了方便点希望能在页面上画。

我用的是iview的ui框架,用原生的话记得把按钮等标签改改。

如果用的是element-ui的话,可以到这里看看,有中文文档和特别完善的bpmn+element-ui的项目:https://blog.csdn.net/weixin_43359503/article/details/113915655

在百度取经的过程中,发现右侧的工具栏有的内容很少,有的比较全。研究之后发现是安装版本的问题,为了满足需求,工具栏当然是越多越好!

注意:并不是最新版本的就是最好的,最新版本的反而功能更少

这是较新版本的:

这是特定版本的:

 1、 先安装bpmn相关依赖

 npm install bpmn-js@7.3.1
 npm install bpmn-js-properties-panel@0.37.2
 npm install camunda-bpmn-moddle@4.4.0

注意:版本不对会出现 报错 unhandled error in event listener TypeError: bo.get is not a function

2、准备相关js文件,汉化等,文件存放的位置和在vue文件中引入时需要根据你自己的实际情况来写。这三个文件我是放在同一目录下的

(1)translations.js

  1. export default {
  2. // Labels
  3. 'Activate the global connect tool': '激活全局连接工具',
  4. 'Append {type}': '添加 {type}',
  5. 'Add Lane above': '在上面添加道',
  6. 'Divide into two Lanes': '分割成两个道',
  7. 'Divide into three Lanes': '分割成三个道',
  8. 'Add Lane below': '在下面添加道',
  9. 'Append compensation activity': '追加补偿活动',
  10. 'Change type': '修改类型',
  11. 'Connect using Association': '使用关联连接',
  12. 'Connect using Sequence/MessageFlow or Association': '使用顺序/消息流或者关联连接',
  13. 'Connect using DataInputAssociation': '使用数据输入关联连接',
  14. Remove: '移除',
  15. 'Activate the hand tool': '激活抓手工具',
  16. 'Activate the lasso tool': '激活套索工具',
  17. 'Activate the create/remove space tool': '激活创建/删除空间工具',
  18. 'Create expanded SubProcess': '创建扩展子过程',
  19. 'Create IntermediateThrowEvent/BoundaryEvent': '创建中间抛出事件/边界事件',
  20. 'Create Pool/Participant': '创建池/参与者',
  21. 'Parallel Multi Instance': '并行多重事件',
  22. 'Sequential Multi Instance': '时序多重事件',
  23. DataObjectReference: '数据对象参考',
  24. DataStoreReference: '数据存储参考',
  25. Loop: '循环',
  26. 'Ad-hoc': '即席',
  27. 'Create {type}': '创建 {type}',
  28. Task: '任务',
  29. 'Send Task': '发送任务',
  30. 'Receive Task': '接收任务',
  31. 'User Task': '用户任务',
  32. 'Manual Task': '手工任务',
  33. 'Business Rule Task': '业务规则任务',
  34. 'Service Task': '服务任务',
  35. 'Script Task': '脚本任务',
  36. 'Call Activity': '调用活动',
  37. 'Sub Process (collapsed)': '子流程(折叠的)',
  38. 'Sub Process (expanded)': '子流程(展开的)',
  39. 'Start Event': '开始事件',
  40. StartEvent: '开始事件',
  41. 'Intermediate Throw Event': '中间事件',
  42. 'End Event': '结束事件',
  43. EndEvent: '结束事件',
  44. 'Create Gateway': '创建网关',
  45. 'Create Intermediate/Boundary Event': '创建中间/边界事件',
  46. 'Message Start Event': '消息开始事件',
  47. 'Timer Start Event': '定时开始事件',
  48. 'Conditional Start Event': '条件开始事件',
  49. 'Signal Start Event': '信号开始事件',
  50. 'Error Start Event': '错误开始事件',
  51. 'Escalation Start Event': '升级开始事件',
  52. 'Compensation Start Event': '补偿开始事件',
  53. 'Message Start Event (non-interrupting)': '消息开始事件(非中断)',
  54. 'Timer Start Event (non-interrupting)': '定时开始事件(非中断)',
  55. 'Conditional Start Event (non-interrupting)': '条件开始事件(非中断)',
  56. 'Signal Start Event (non-interrupting)': '信号开始事件(非中断)',
  57. 'Escalation Start Event (non-interrupting)': '升级开始事件(非中断)',
  58. 'Message Intermediate Catch Event': '消息中间捕获事件',
  59. 'Message Intermediate Throw Event': '消息中间抛出事件',
  60. 'Timer Intermediate Catch Event': '定时中间捕获事件',
  61. 'Escalation Intermediate Throw Event': '升级中间抛出事件',
  62. 'Conditional Intermediate Catch Event': '条件中间捕获事件',
  63. 'Link Intermediate Catch Event': '链接中间捕获事件',
  64. 'Link Intermediate Throw Event': '链接中间抛出事件',
  65. 'Compensation Intermediate Throw Event': '补偿中间抛出事件',
  66. 'Signal Intermediate Catch Event': '信号中间捕获事件',
  67. 'Signal Intermediate Throw Event': '信号中间抛出事件',
  68. 'Message End Event': '消息结束事件',
  69. 'Escalation End Event': '定时结束事件',
  70. 'Error End Event': '错误结束事件',
  71. 'Cancel End Event': '取消结束事件',
  72. 'Compensation End Event': '补偿结束事件',
  73. 'Signal End Event': '信号结束事件',
  74. 'Terminate End Event': '终止结束事件',
  75. 'Message Boundary Event': '消息边界事件',
  76. 'Message Boundary Event (non-interrupting)': '消息边界事件(非中断)',
  77. 'Timer Boundary Event': '定时边界事件',
  78. 'Timer Boundary Event (non-interrupting)': '定时边界事件(非中断)',
  79. 'Escalation Boundary Event': '升级边界事件',
  80. 'Escalation Boundary Event (non-interrupting)': '升级边界事件(非中断)',
  81. 'Conditional Boundary Event': '条件边界事件',
  82. 'Conditional Boundary Event (non-interrupting)': '条件边界事件(非中断)',
  83. 'Error Boundary Event': '错误边界事件',
  84. 'Cancel Boundary Event': '取消边界事件',
  85. 'Signal Boundary Event': '信号边界事件',
  86. 'Signal Boundary Event (non-interrupting)': '信号边界事件(非中断)',
  87. 'Compensation Boundary Event': '补偿边界事件',
  88. 'Exclusive Gateway': '互斥网关',
  89. 'Parallel Gateway': '并行网关',
  90. 'Inclusive Gateway': '相容网关',
  91. 'Complex Gateway': '复杂网关',
  92. 'Event based Gateway': '事件网关',
  93. Transaction: '转运',
  94. 'Sub Process': '子流程',
  95. 'Event Sub Process': '事件子流程',
  96. 'Collapsed Pool': '折叠池',
  97. 'Expanded Pool': '展开池',
  98. // Errors
  99. 'no parent for {element} in {parent}': '{parent}里,{element}没有父类',
  100. 'no shape type specified': '没有指定的形状类型',
  101. 'flow elements must be children of pools/participants': '流元素必须是池/参与者的子类',
  102. 'out of bounds release': 'out of bounds release',
  103. 'more than {count} child lanes': '子道大于{count} ',
  104. 'element required': '元素不能为空',
  105. 'diagram not part of bpmn:Definitions': '流程图不符合bpmn规范',
  106. 'no diagram to display': '没有可展示的流程图',
  107. 'no process or collaboration to display': '没有可展示的流程/协作',
  108. 'element {element} referenced by {referenced}#{property} not yet drawn':
  109. '{referenced}#{property}引用的{element}元素仍未绘制',
  110. 'already rendered {element}': '{element} 已被渲染',
  111. 'failed to import {element}': '导入{element}失败',
  112. // 属性面板的参数
  113. Id: '编号',
  114. Name: '名称',
  115. General: '常规',
  116. Details: '详情',
  117. 'Message Name': '消息名称',
  118. Message: '消息',
  119. Initiator: '创建者',
  120. 'Asynchronous Continuations': '持续异步',
  121. 'Asynchronous Before': '异步前',
  122. 'Asynchronous After': '异步后',
  123. 'Job Configuration': '工作配置',
  124. Exclusive: '排除',
  125. 'Job Priority': '工作优先级',
  126. 'Retry Time Cycle': '重试时间周期',
  127. Documentation: '文档',
  128. 'Element Documentation': '元素文档',
  129. 'History Configuration': '历史配置',
  130. 'History Time To Live': '历史的生存时间',
  131. Forms: '表单',
  132. 'Form Key': '表单key',
  133. 'Form Fields': '表单字段',
  134. 'Business Key': '业务key',
  135. 'Form Field': '表单字段',
  136. ID: '编号',
  137. Type: '类型',
  138. Label: '名称',
  139. 'Default Value': '默认值',
  140. Validation: '校验',
  141. 'Add Constraint': '添加约束',
  142. Config: '配置',
  143. Properties: '属性',
  144. 'Add Property': '添加属性',
  145. Value: '',
  146. Listeners: '监听器',
  147. 'Execution Listener': '执行监听',
  148. 'Event Type': '事件类型',
  149. 'Listener Type': '监听器类型',
  150. 'Java Class': 'Java类',
  151. Expression: '表达式',
  152. 'Must provide a value': '必须提供一个值',
  153. 'Delegate Expression': '代理表达式',
  154. Script: '脚本',
  155. 'Script Format': '脚本格式',
  156. 'Script Type': '脚本类型',
  157. 'Inline Script': '内联脚本',
  158. 'External Script': '外部脚本',
  159. Resource: '资源',
  160. 'Field Injection': '字段注入',
  161. Extensions: '扩展',
  162. 'Input/Output': '输入/输出',
  163. 'Input Parameters': '输入参数',
  164. 'Output Parameters': '输出参数',
  165. Parameters: '参数',
  166. 'Output Parameter': '输出参数',
  167. 'Timer Definition Type': '定时器定义类型',
  168. 'Timer Definition': '定时器定义',
  169. Date: '日期',
  170. Duration: '持续',
  171. Cycle: '循环',
  172. Signal: '信号',
  173. 'Signal Name': '信号名称',
  174. Escalation: '升级',
  175. Error: '错误',
  176. 'Link Name': '链接名称',
  177. Condition: '条件名称',
  178. 'Variable Name': '变量名称',
  179. 'Variable Event': '变量事件',
  180. 'Specify more than one variable change event as a comma separated list.':
  181. '多个变量事件以逗号隔开',
  182. 'Wait for Completion': '等待完成',
  183. 'Activity Ref': '活动参考',
  184. 'Version Tag': '版本标签',
  185. Executable: '可执行文件',
  186. 'External Task Configuration': '扩展任务配置',
  187. 'Task Priority': '任务优先级',
  188. External: '外部',
  189. Connector: '连接器',
  190. 'Must configure Connector': '必须配置连接器',
  191. 'Connector Id': '连接器编号',
  192. Implementation: '实现方式',
  193. 'Field Injections': '字段注入',
  194. Fields: '字段',
  195. 'Result Variable': '结果变量',
  196. Topic: '主题',
  197. 'Configure Connector': '配置连接器',
  198. 'Input Parameter': '输入参数',
  199. Assignee: '代理人',
  200. 'Candidate Users': '候选用户',
  201. 'Candidate Groups': '候选组',
  202. 'Due Date': '到期时间',
  203. 'Follow Up Date': '跟踪日期',
  204. 'Specify more than one group as a comma separated list.': '多个用户使用逗号隔开',
  205. Priority: '优先级',
  206. // eslint-disable-next-line no-template-curly-in-string
  207. 'The follow up date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)':
  208. '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00',
  209. // eslint-disable-next-line no-template-curly-in-string
  210. 'The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)':
  211. '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00',
  212. Variables: '变量',
  213. 'Candidate Starter Users': '选择启动候选人',
  214. 'Candidate Starter Configuration': '候选人启动器配置',
  215. 'Candidate Starter Groups': '候选人启动组',
  216. 'This maps to the process definition key.': '编号将映射到流程主键.',
  217. save: '保存',
  218. Tools: '工具',
  219. FlowGateway: '流程网关',
  220. ProcessControl: '流程节点',
  221. 'Create StartEvent': '开始节点',
  222. 'Create EndEvent': '结束节点',
  223. 'Create ExclusiveGateway': '互斥网关',
  224. 'Create ParallelGateway': '并行网关',
  225. 'Create Task': '任务节点',
  226. 'Create UserTask': '用户任务节点',
  227. 'Condition Type': '条件类型',
  228. // 左侧工具箱补充汉化项 热水2020.1.12
  229. 'Create Group': '创建组',
  230. 'Create DataObjectReference': '创建数据对象引用',
  231. 'Create DataStoreReference': '创建数据存储引用',
  232. // 节点添加Pad 补充汉化 热水2020.1.12
  233. 'Append EndEvent': '追加结束事件节点',
  234. 'Append Gateway': '追加网关节点',
  235. 'Append UserTask': '追加用户任务节点',
  236. 'Append Intermediate/Boundary Event': '追加中间或边界事件',
  237. 'Append TextAnnotation': '追加文本批注' // 此句要有效,必须在CustomContexPadProvide给此节点增加一个translate('Append TextAnnotation')
  238. }

(2)customTranslate.js

  1. import translations from './translations';
  2. export default function customTranslate(template, replacements) {undefined
  3. replacements = replacements || {};
  4. // Translate
  5. template = translations[template] || template;
  6. // Replace
  7. return template.replace(/{([^}]+)}/g, function(_, key) {undefined
  8. return replacements[key] || '{' + key + '}';
  9. });
  10. }

(3)生成流程图的默认模板  defaultXmlStr.js

  1. export var xmlStr = `
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
  5. xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  6. xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
  7. id="sample-diagram"
  8. targetNamespace="http://bpmn.io/schema/bpmn"
  9. xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
  10. <bpmn2:process id="Process_1" isExecutable="false">
  11. <bpmn2:startEvent id="StartEvent_1" />
  12. </bpmn2:process>
  13. <bpmndi:BPMNDiagram id="BPMNDiagram_1">
  14. <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
  15. <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
  16. <dc:Bounds x="192" y="82" width="36" height="36" />
  17. </bpmndi:BPMNShape>
  18. </bpmndi:BPMNPlane>
  19. </bpmndi:BPMNDiagram>
  20. </bpmn2:definitions>`

(4)vue文件

  1. <template>
  2. <div class="containers" ref="content">
  3. <div class="button-row">
  4. <Upload :file-list="uploadBpmnFileList" :before-upload="beforeUpload" action="">
  5. <Button class="button" type="warning">
  6. 导入BPMN
  7. </Button>
  8. </Upload>
  9. <Button @click="downloadBpmn" class="button" type="success">
  10. 保存BPMN
  11. </Button>
  12. <!-- <Button @click="downloadXml" class="button" icon="md-download" type="success">
  13. 保存XML
  14. </Button> -->
  15. <Button @click="downloadSvg" class="button" type="success">
  16. 保存SVG
  17. </Button>
  18. <Button @click="showXml" class="button" type="primary">
  19. 预览xml
  20. </Button>
  21. <ButtonGroup class="button">
  22. <Button @click="handlerUndo">撤销</Button>
  23. <Button @click="handlerRedo">恢复</Button>
  24. </ButtonGroup>
  25. <ButtonGroup>
  26. <Button @click="handlerZoom(0.1)">放大</Button>
  27. <Button @click="handlerZoom(-0.1)">缩小</Button>
  28. <Button @click="handlerZoom(0)">还原</Button>
  29. </ButtonGroup>
  30. <a hidden ref="downloadLink"></a>
  31. </div>
  32. <div class="canvas" ref="canvas"></div>
  33. <div id="js-properties-panel" class="panel"></div>
  34. <Modal title="预览" v-model="showXmlModal" fullscreen :mask-closable="false">
  35. <!-- <xmp><div v-text="xmlData"></div></xmp> -->
  36. <pre><div v-text="xmlData"></div></pre>
  37. <div slot="footer"></div>
  38. </Modal>
  39. </div>
  40. </template>
  41. <script>
  42. import BpmnModeler from 'bpmn-js/lib/Modeler'
  43. import propertiesPanelModule from 'bpmn-js-properties-panel'
  44. import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
  45. import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
  46. // BPMN国际化
  47. import customTranslate from '@/lib/customTranslate';
  48. // 自定义汉化模块
  49. var customTranslateModule = {
  50. translate: ['value', customTranslate]
  51. };
  52. import {
  53. xmlStr
  54. } from '@/lib/defaultXmlStr';
  55. export default {
  56. components: {},
  57. data() {
  58. return {
  59. bpmnModeler: null,
  60. container: null,
  61. canvas: null,
  62. uploadBpmnFileList: [],
  63. scale: 1,
  64. showXmlModal: false,
  65. xmlData: "",
  66. }
  67. },
  68. created() {
  69. },
  70. mounted() {
  71. this.init();
  72. // 删除 bpmn logo bpmn.io官方要求不给删或者隐藏,否则侵权 内部使用
  73. // const bjsIoLogo = document.querySelector('.bjs-powered-by')
  74. // while (bjsIoLogo.firstChild) {
  75. // bjsIoLogo.removeChild(bjsIoLogo.firstChild)}
  76. },
  77. methods: {
  78. /**
  79. * 初始化流程设计器对象
  80. * @returns {Promise<void>}
  81. */
  82. async init() {
  83. // 获取到属性ref为“content”的dom节点
  84. this.container = this.$refs.content
  85. // 获取到属性ref为“canvas”的dom节点
  86. const canvas = this.$refs.canvas
  87. // 创建BpmnModeler
  88. this.bpmnModeler = new BpmnModeler({
  89. container: canvas,
  90. // 加入工具栏支持
  91. propertiesPanel: {
  92. parent: '#js-properties-panel'
  93. },
  94. additionalModules: [
  95. // 左边工具栏以及节点
  96. propertiesProviderModule,
  97. // 右边的工具栏
  98. propertiesPanelModule,
  99. // 国际化
  100. customTranslateModule,
  101. // camundaModdleDescriptor
  102. ],
  103. moddleExtensions: {
  104. // bpmn: bpmnModdleDescriptor
  105. camunda: camundaModdleDescriptor
  106. }
  107. });
  108. // 创建新流程
  109. await this.createNewDiagram(xmlStr);
  110. },
  111. /**
  112. * 创建新流程
  113. * @param bpmn BPMN流程XML报文
  114. * @returns {Promise<void>}
  115. */
  116. async createNewDiagram(bpmn) {
  117. // 将字符串转换成图显示出来;
  118. this.bpmnModeler.importXML(bpmn, err => {
  119. if (err) {
  120. console.log('err', err);
  121. this.$Message.error('打开模型出错,请确认该模型符合Bpmn2.0规范');
  122. } else {
  123. console.log("成功导入模型");
  124. }
  125. });
  126. },
  127. handlerRedo() {
  128. this.bpmnModeler.get("commandStack").redo();
  129. },
  130. handlerUndo() {
  131. this.bpmnModeler.get("commandStack").undo();
  132. },
  133. handlerZoom(radio) {
  134. const newScale = !radio ? 1.0 : this.scale + radio;
  135. this.bpmnModeler.get("canvas").zoom(newScale);
  136. this.scale = newScale;
  137. },
  138. beforeUpload(file) {
  139. // this.uploadBpmnFileList = [];
  140. this.openBpmn(file);
  141. return false;
  142. },
  143. openBpmn(file) {
  144. const reader = new FileReader();
  145. // 读取File对象中的文本信息,编码格式为UTF-8
  146. reader.readAsText(file, "utf-8");
  147. reader.onload = () => {
  148. // 读取完毕后将文本信息导入到Bpmn建模器
  149. this.createNewDiagram(reader.result);
  150. };
  151. return false;
  152. },
  153. downloadBpmn() {
  154. this.bpmnModeler.saveXML({
  155. format: true
  156. }, (err, xml) => {
  157. if (!err) {
  158. // 获取文件名
  159. const name = `${this.getFilename(xml)}.bpmn`;
  160. // 将文件名以及数据交给下载方法
  161. this.download({
  162. name: name,
  163. data: xml
  164. });
  165. }
  166. });
  167. },
  168. downloadXml() {
  169. this.bpmnModeler.saveXML({
  170. format: true
  171. }, (err, xml) => {
  172. if (!err) {
  173. // 获取文件名
  174. const name = `${this.getFilename(xml)}.xml`;
  175. // 将文件名以及数据交给下载方法
  176. this.download({
  177. name: name,
  178. data: xml
  179. });
  180. }
  181. });
  182. },
  183. downloadSvg() {
  184. this.bpmnModeler.saveXML({
  185. format: true
  186. }, (err, xml) => {
  187. if (!err) {
  188. // 获取文件名
  189. const name = `${this.getFilename(xml)}.svg`;
  190. // 从建模器画布中提取svg图形标签
  191. let context = "";
  192. const djsGroupAll = this.$refs.canvas.querySelectorAll(".djs-group");
  193. for (let item of djsGroupAll) {
  194. context += item.innerHTML;
  195. }
  196. // 获取svg的基本数据,长宽高
  197. const viewport = this.$refs.canvas
  198. .querySelector(".viewport")
  199. .getBBox();
  200. // 将标签和数据拼接成一个完整正常的svg图形
  201. const svg = `
  202. <svg
  203. xmlns="http://www.w3.org/2000/svg"
  204. xmlns:xlink="http://www.w3.org/1999/xlink"
  205. width="${viewport.width}"
  206. height="${viewport.height}"
  207. viewBox="${viewport.x} ${viewport.y} ${viewport.width} ${viewport.height}"
  208. version="1.1"
  209. >
  210. ${context}
  211. </svg>
  212. `;
  213. // 将文件名以及数据交给下载方法
  214. this.download({
  215. name: name,
  216. data: svg
  217. });
  218. }
  219. });
  220. },
  221. download({
  222. name = "diagram.bpmn",
  223. data
  224. }) {
  225. // 这里就获取到了之前设置的隐藏链接
  226. const downloadLink = this.$refs.downloadLink;
  227. // 把输就转换为URI,下载要用到的
  228. const encodedData = encodeURIComponent(data);
  229. if (data) {
  230. // 将数据给到链接
  231. downloadLink.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
  232. // 设置文件名
  233. downloadLink.download = name;
  234. // 触发点击事件开始下载
  235. downloadLink.click();
  236. }
  237. },
  238. getFilename(xml) {
  239. let start = xml.indexOf("process");
  240. let filename = xml.substr(start, xml.indexOf(">"));
  241. filename = filename.substr(filename.indexOf("id") + 4);
  242. filename = filename.substr(0, filename.indexOf('"'));
  243. return filename;
  244. },
  245. showXml() {
  246. this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
  247. this.xmlData = xml;
  248. this.showXmlModal = true;
  249. });
  250. },
  251. },
  252. computed: {}
  253. }
  254. </script>
  255. <style lang="less" scoped>
  256. // 左边工具栏以及编辑节点的样式
  257. @import '~bpmn-js/dist/assets/diagram-js.css';
  258. @import '~bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
  259. @import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
  260. @import '~bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
  261. // 右边工具栏样式
  262. @import '~bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css';
  263. .containers {
  264. position: absolute;
  265. background-color: #ffffff;
  266. width: 100%;
  267. height: 100vh;
  268. padding: 5px;
  269. }
  270. .canvas {
  271. width: 100%;
  272. height: 100%;
  273. }
  274. .panel {
  275. position: absolute;
  276. right: 0;
  277. top: 0;
  278. width: 300px;
  279. }
  280. .button-row {
  281. margin-top: 10px;
  282. display: flex;
  283. flex-direction: row;
  284. justify-content: center;
  285. .button {
  286. margin-right: 10px;
  287. font-weight: bolder;
  288. }
  289. }
  290. </style>

到此就可以看到流程图制作的页面了,在样式上还存在一些问题,比如用滚轮上下滚动的话可以无限滑动,得滑动滚动条才行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/446664
推荐阅读
相关标签
  

闽ICP备14008679号