https://blog.csdn.net/u013253924/article/details/85784002

通过本文逐步熟悉bpmn-js。

快速介绍:

bpmn.js是一个BPMN2.0渲染工具包和web建模器。使用JavaScript编写,在不需要后端服务器支持的前提下向现代浏览器内嵌入BPMN2.0流程图。这使得它很容易的嵌入到任何web应用中。

这个库既可以是web查看器也可以是web建模器。使用查看器将BPMN2.0流程图嵌入到你的应用中并可以使用数据丰富你的流程图。使用建模器在你的应用内部创建BPMN2.0流程图。

下文将向您介绍如何使用该库,并深入了解其内部结构。也就是说,这两个组件促成了该库的高度模块化和可扩展的结构。

本文包含以下内容:

● 如何使用库

• 嵌入查看器(预打包)

• 自己制作模型(通过npm)

● 理解bpmn-js内部

• 流程图交互/建模(流程图-js)

• BPMN元模型(bpmn-moddle)

• 将事物整合在一起(bpmn-js)

● 进一步探索

如何使用库

有两种方法在你的应用中使用bpmn.js。库的预打包版本可以让你在任何网站中快速添加BPMN。npm版本的设置更加复杂,但允许您访问单个库组件,并更容易扩展。

本节将概述这两种方法。首先我们来介绍如何向网站中嵌入一个预打包的BPMN查看器。之后,展示如何通过npm创建一个BPMN建模器。

嵌入预打包查看器

通过一个简单的script标签引入就可以将预打包的BPMN查看器嵌入你的网站

  1.  
    <!-- BPMN 流程图容器 -->
  2.  
    <div id="canvas"></div>
  3.  
    <!-- 使用 CDN 路径 或者本地 bpmn-js 路径 -->
  4.  
    <script src="https://unpkg.com/bpmn-js@0.27.0-1/dist/bpmn-viewer.development.js"></script>

通过引入的BPMNjs变量,可以使BPMN查看器可用。我们可以通过下面这段js来引入一个BPMN流程图。

  1.  
    <script>
  2.  
    // 你即将要展示的流程图
  3.  
    var bpmnXML;
  4.  
    // BpmnJS是BPMN查看器实例
  5.  
    var viewer = new BpmnJS({ container: '#canvas' });
  6.  
    // 导入BPMN 2.0流程图
  7.  
    viewer.importXML(bpmnXML, function(err) {
  8.  
    if (err) {
  9.  
    //导入失败 !
  10.  
    } else {
  11.  
    // 导入成功!
  12.  
    var canvas = viewer.get('canvas');
  13.  
    canvas.zoom('fit-viewport');
  14.  
    }
  15.  
    });
  16.  
    </script>

该代码片段使用Viewer#importXML API显示预加载的BPMN 2.0图。导入图是异步的,一旦完成,查看器将通过回调通知我们结果。

导入后,我们可以通过Viewer#get访问各种图表服务。在上面的代码片段中,我们与画布交互以使图适合当前可用的视图大小。

通常,通过AJAX动态加载BPMN 2.0图更实用。这可以使用纯JavaScript(如下所示)或通过实用程序库(如jQuery)实现,后者提供了更方便的api。

  1.  
    <script>
  2.  
    var xhr = new XMLHttpRequest();
  3.  
    xhr.onreadystatechange = function() {
  4.  
    if (xhr.readyState === 4) {
  5.  
    viewer.importXML(xhr.response, function(err) {
  6.  
    // ...
  7.  
    });
  8.  
    }
  9.  
    };
  10.  
    xhr.open('GET', 'path-to-diagram.bpmn', true);
  11.  
    xhr.send(null);
  12.  
    </script>

查看预打包的示例以及我们的初学者示例,了解更多信息。

创建属于自己的建模器

如果你想要围绕库做一些定制化,需要使用npm来使用库。这种方法有很多优点,比如可以访问单个库组件。它还使我们能够更好地控制部分打包查看器/建模器。需要使用Webpack (>=2) or Rollup来打包bpmn-js和我们的应用。

以下大致遵循modeler示例,使用该库创建BPMN建模器。

引入库

首先,通过npm安装bpmn.js

npm install bpmn-js

然后,通过ES import获得BPMN建模器

import Modeler from 'bpmn-js/lib/Modeler';

// 创建一个建模器

var modeler = new Modeler({ container: '#canvas' });

// 导入流程图

  1.  
    modeler.importXML(bpmnXML, function(err) {
  2.  
    // ...
  3.  
    });

同样的,需要在你的html中提供一个id声明的画布元素,以便建模器能够向画布内渲染。

添加样式

当将建模器嵌入网页时,要引入diagram-js样式以及BPMN图标字体。它们都随bpms -js发行版一起在dist/assets文件夹下提供。

  1.  
    <link rel="stylesheet" href="bpmn-js/dist/assets/diagram-js.css" />
  2.  
    <link rel="stylesheet" href="bpmn-js/dist/assets/bpmn-font/css/bpmn-.css" />

添加样式表可以确保图元素获得适当的样式化,背景板以及画板显示BPMN图标

浏览器打包

bpmn.js及其依赖由ES模块分发。使用ES模块打包器Webpack (>=2) 或者 Rollup来打包bpmn.js和你的应用。可以通过打包例子来学习更多相关。

与生命周期事件挂钩

事件允许您钩入建模器的生命周期以及图交互。下面的代码片段展示了一般情况下如何捕获元素的更改和建模操作。

  1.  
    modeler.on('commandStack.changed', function() {
  2.  
    // 建模或执行撤销/重做操作
  3.  
    });
  4.  
    modeler.on('element.changed', function(event) {
  5.  
    var element = event.element;
  6.  
    // 元素改变触发
  7.  
    })

使用Viewer#on注册事件或者扩展模块中的事件总线。使用 Viewer#off 来停止监听事件。请查看交互示例,以查看监听动作中的事件。

建模器的扩展

在实际使用的过程中,你可以用additionalModules选项来扩展查看器和建模器。允许您使用自定义模块来修改或替换现有的功能。

import OriginModule from 'diagram-js-origin';
  1.  
    // 创建一个建模器
  2.  
    var modeler = new Modeler({
  3.  
    container: '#canvas',
  4.  
    additionalModules: [
  5.  
    OriginModule,
  6.  
    require('./custom-rules'),
  7.  
    require('./custom-context-pad')
  8.  
    ]
  9.  
    });
  10.  
     

一个模块(比较:模块系统部分)是一个单元,定义了一个或多个服务。这些服务配置了bpmn.js或者提供了额外的功能。也就是通过接入流程图的生命周期来实现的。

一些模块,例如: diagram-js-origin 或 diagram-js-minimap提供了通用的用户界面添加。内置的bpmn-js模块,例如:such as bpmn rules 或 modeling提供了高定制的BPMN功能。

常用扩展BPMN建模器的方法是添加“自定义建模规则”。这样,您可以限制或扩展用户的建模操作。

扩展的其他例子有:

● 添加自定义元素

● 自定义面板/内容面板

● 自定义形状的渲染

查看bpms -js-example项目,了解更多工具包扩展展示案例。

构建自定义发行版

如果你想要针对你自定义的建模器和查看器创建预打包版本,请参 custom-bundle example这个例子。如果你定制了大量的功能但是希望以简单的方式交付给用户的话,这可能会给到你帮助。

理解bpmn-js内部

本节探讨一些bpmn-js的内部结构。

如下面的架构图所示,bpmn-js构建在两个重要的库之上:diagram-js和bpmn-moddle。

我们使用diagram-js 来绘制形状和连接。它为我们提供了与这些图形元素交互的方法,同时也提供了额外的工具例如overlays来帮助用户构建更为强大的查看器。对于更高级的建模情况,提供了提供了背景板、调色板和重做/撤消等功能。

bpmn-moddle清楚BPMN2.0元模型,元模型定义在BPMN2.0规范之上。它允许我们读写BPMN 2.0模式兼容的XML文档,获得关于图形和连接的相关信息并绘制出来。

在这两个库之上,bpmn.js定义了BPMN的细节,比如外观、建模规则和工具(如调色板)。我们将在下面的段落中详细介绍各个组件。

图交互/建模(diagram-js)

diagram-js是一个工具箱,用于在web上显示和修改图表。它允许我们渲染视觉元素并在它们之上构建交互体验。它为我们提供了一个非常简单的模块系统,用于构建特殊的服务和服务的依赖注入。这个系统还提供了一些核心服务,这些服务实现了图的基本内容。

此外,diagram-js为图形元素及其关系定义了一个数据模型。

模块系统

再下一层,diagram-js使用依赖注入(DI)来连接和发现图组件。这个机制是建立在node-di之上的。

在diagram-js上下文中讨论模块时,我们指的是提供命名服务及其实现的单元。从这个意义上说,服务是一个函数或实例,它可以使用其他服务在图的上下文中执行某些操作。

下面显示了一个与生命周期事件挂钩的服务。它通过eventBus注册一个事件来实现,eventBus是另一个著名的服务:

  1.  
    function MyLoggingPlugin(eventBus) {
  2.  
    eventBus.on('element.changed', function(event) {
  3.  
    console.log('element ', event.element, ' changed');
  4.  
    });
  5.  
    }

// 确保依赖项名称在缩小后仍然可用

MyLoggingPlugin.$inject = [ 'eventBus' ];

我们必须使用模块定义唯一名称发布服务:

import CoreModule from 'diagram-js/lib/core';

  1.  
    // 作为一个模块导入
  2.  
    export default {
  3.  
    __depends__: [ CoreModule ], // {2}
  4.  
    __init__: [ 'myLoggingPlugin' ], // {3}
  5.  
    myLoggingPlugin: [ 'type', MyLoggingPlugin ] // {1}
  6.  
    };

该定义告诉DI基础设施,该服务名为myLoggingPlugin {1},它依赖于diagram-js核心模块{2} 并且服务应该在创建关系图{3}时初始化。要了解更多细节,请查看node-di的文档。

我们现在可以通过我们的自定义模块引导diagram-js

要将模块插入bpmn-js,可以使用additionalModules选项,如扩展Modeler部分所示。

核心服务

bpmn-js核心是围绕一些基本服务构建的:

● Canvas -提供了添加和删除图形元素的api;处理元素生命周期,并提供用于缩放和滚动的api。

● EventBus -该库的全局通信通道具有防火和遗忘策略。可以订阅各种事件,并在事件发出后立即采取行动。事件总线帮助我们解耦关注点并模块化功能,以便新特性能够轻松地与现有行为挂钩。

● ElementFactory -根据bpmn-js的内部数据模型创建形状和连接的工厂。

● ElementRegistry—知道添加到图中的所有元素,并提供api来根据id检索元素及其图形表示。

● GraphicsFactory -负责创建图形和连接的图形表示。实际的外观是由渲染器定义的,即绘制模块中的DefaultRenderer。

数据模型

实际上,diagram-js实现了一个由形状和连接组成的简单数据模型。

数据模型要点:形状和连接

一个形状有父节点、子节点列表以及传入和传出连接列表。

一个连接有父节点、源节点和目标节点,指向一个形状。

ElementRegistry负责根据该模型创建形状和连接。

在建模过程中,建模服务将根据用户操作更新元素关系。

辅助服务(即工具箱)

除了数据模型及其核心服务之外,diagram-js还提供了丰富的辅助工具工具箱。

CommandStack-负责建模过程中的重做和撤销。

● ContextPad-提供一个元素的上下文操作。

● Overlays——提供api来附加额外的信息到图元素。

● Modeling——提供用于更新画布上的元素(移动、删除)的api

● Palette

让我们继续讨论幕后发生的BPMN魔法。

BPMN元模型(bpmn-moddle)

bpmn-moddle封装了BPMN 2.0元模型,为我们提供了读写BPMN 2.0 XML文档的工具。在导入时,它将XML文档解析为JavaScript对象树。在建模过程中对该树进行编辑和验证,然后在用户希望保存图时将其导出回BPMN 2.0 XML。因为bpmn-moddle封装了有关BPMN的知识,我们能够在导入和建模期间进行验证。根据结果,我们可以约束某些建模操作,并向用户输出有用的错误消息和警告。

就像bpmn-js一样,bpmn-moddle的基础也是建立在两个库之上的:

● moddle提供了一种用JavaScript定义元模型的简洁方法

● 基于moddle读写XML文档的model-xml

从本质上讲,bpmn-moddle将BPMN规范作为元模型添加进来,并为BPMN模式验证提供了一个简单的接口。从库的角度来看,它提供了以下API:

● fromXML -从给定的XML字符串创建BPMN树

● toXML - 向BPMN 2.0 XML编写BPMN对象树

BPMN元模型对于bpmn -js是必不可少的,因为它允许我们验证我们使用的BPMN 2.0文档,提供正确的建模规则,并导出所有遵循BPMN模型的人都能理解的有效BPMN文档。

把东西连接起来(bpmn-js)

我们学过bpms -js是建立在diagram-js和bpms -moddle之上的。它将两者联系在一起,并添加BPMN外观。这包括BPMN调色板、BPMN背景板以及BPMN 2.0特定规则。在本节中,我们将解释它在建模的不同阶段是如何工作的。

当我们导入BPMN 2.0文档时,bpmn-moddle会将其从XML解析为对象树。bpmn-js呈现该树的所有可见元素,即在画布上创建各自的形状和连接。因此,它将BPMN元素和图形元素联系在一起。这将产生一个结构,如下所示,用于初始事件形状。

{

id: 'StartEvent_1',

x: 100,

y: 100,

width: 50,

height: 50,

businessObject: {

$attrs: Object

$parent: {

$attrs: Object

$parent: ModdleElement

$type: 'bpmn:Process'

flowElements: Array[1]

id: 'Process_1'

isExecutable: false

}

$type: 'bpmn:StartEvent'

id: 'StartEvent_1'

}

}

您可以通过businessObject属性从每个图形元素访问底层BPMN类型。

由于BpmnRenderer,bpmn -js也知道每个BPMN元素的样子。通过插入渲染周期,您还可以定义单个BPMN元素的自定义表示。

一旦导入完成,我们就可以开始建模了。我们使用规则来允许或不允许某些建模操作。这些规则由BpmnRules定义。我们将这些规则基于OMG定义的BPMN 2.0标准。然而,正如前面提到的,其他人也可能与规则评估挂钩,以贡献不同的行为。

建模模块捆绑了BPMN 2.0相关的建模功能。它添加了BPMN 2.0特定的建模行为,并负责在用户执行的每个建模操作中更新BPMN 2.0文档树(cf. BpmnUpdater)。请查看它,以更深入地了解规则、行为和BPMN更新周期。

当纯粹从库的角度来看bpmn-js时,值得一提的是它可以有三种形式:

● Viewer展示图

● NavigatedViewer显示和导航BPMN图

● Modeler 建模BPMN图

版本之间的唯一区别是它们捆绑了不同的功能集。NavigatedViewer添加了用于导航画布的模块,Modeler添加了大量用于创建、编辑和与画布上的元素交互的功能。

bpmn-js起步的更多相关文章

  1. bpmn.js & BPMN diagram

    bpmn.js & BPMN diagram BPMN 2.0 for the web https://github.com/bpmn-io/bpmn-js https://demo.bpmn ...

  2. 关于h5使用bpmn.js

    bpmn.js网站地址:https://bpmn.io/toolkit/bpmn-js/ bpmnjs是一款工作流绘制框架,遵循了bpmn2.0规范,实现从前台绘制工作流到后台执行的效果. 图示: 但 ...

  3. SpringBoot+Activiti+bpmn.js+Vue.js+Elementui(OA系统审批流)

    引言:OA系统用到请假.加班.调休.离职,需要使用工作流进行流程审批 一:activiti流程设计器的选择(通过学习activiti工作流过程中,发现一款好的流程设计器将会更好的方便的设计好流程(主要 ...

  4. Node.js起步 -- (1)

    先来简单介绍nodeJS 我们知道JavaScript是运行在浏览器中的,浏览器为它提供了一个上下文(context),从而让JavaScript得以解析执行. nodeJS其实可以这么理解,它是另外 ...

  5. 陪你去看 Lodash.js 起步

    lodash 起步(数组) Lodash 是一个较为流行的 JavaScript 的实用工具库. 在开发过程中如果能熟练使用一些工具库提供的方法,有利于提高开发效率. 笔者从 API 上入手,不分析其 ...

  6. Vue.js起步

    Vue.js是一套构建用户界面的 渐进式框架,Vue 采用自底向上增量开发的设计,Vue 的核心库只关注视图层.Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用. V ...

  7. Vue.js 起步

    通过实例来看下 Vue 构造器中需要哪些内容 测试时这段代码我直接写在index.html中 <!DOCTYPE html> <html> <head> <m ...

  8. 第五篇:vue.js起步

    <div id="vue_det"> //使改动全部在指定的 div 内,div 外部不受影响 <h1>site : {{site}}</h1> ...

  9. Vue.js:起步

    ylbtech-Vue.js:起步 1.返回顶部 1. Vue.js 起步 每个 Vue 应用都需要通过实例化 Vue 来实现. 语法格式如下: var vm = new Vue({ // 选项 }) ...

  10. Vue.js官方文档学习笔记(一)起步篇

    Vue.js起步 Vue.js介绍 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库 ...

随机推荐

  1. IP通信基础原理课堂笔记----HCL(1)

    PC端配置:打开接口,配置ip地址 交换机配置:①创建VLAN system-view vlan 10 vlan 20 ②配置PC端接口 interface gi 1/0/1 port link-ty ...

  2. ES6 模板字符串Template String

    1. 模板字符串简介: 顾名思义,模板字符串是用来定义一个模板是使用的,就像Vue,React中的template语法. 首先,先来了解一下template string的基本用法: 在ES5中,我们 ...

  3. QT自定义控件系列(二) --- Loading加载动画控件

    本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...

  4. .Net memory management Learning Notes

    Managed Heaps In general it can be categorized into 1) SOH and 2) LOH.  size lower than 85K will be ...

  5. Android Studio 入口程序的设置方法

    在src -> main中 ,打开 AndroidManifest.xml 这个文件 下面这里有两个窗口,如果要想把哪个窗口设置成入口窗体,只要把下面红色的放在这个节点中就可以了 <act ...

  6. 大数据学习-2 认识Hadoop

    一.什么是Hadoop? Hadoop可以简单的理解为一个数据存储和数据分析分布式系统.随着互联网的普及产生的数据是非常的庞大的,那么我们怎么去处理这么大量的数据呢?传统的单一计算机肯定是完成不了的, ...

  7. QT | 一些学习心得

    1. 如何使控件随着窗口大小变化而自动填充? 选中控件中最外层的那个控件,如centralWidget(不要去选中内部的小控件,这样能够保证内部的相对位置) 然后对centralWidget选择布局方 ...

  8. 软件测试_MYSQL

    # MYSQL## 基础知识点### 进入数据库:在偏好设置中打开 — 打开终端 /usr/local/mysql/bin/mysql -u root -p### 可以把完整的命令分成几行打,完后用分 ...

  9. Swift中enum, struct, class的有关使用方法

    import Foundation print("Hello, World!") let a = var b = var c = a + b; c = //重载:函数名相同, 函数 ...

  10. ORA-28000: the account is locked解决

    首先使用具有sysdba权限的账户登陆,如sys账户和system账户 新建一个sql窗体,并执行语句解锁被锁定的账户,如我这里sgyw账户: alter user sgyw account unlo ...