因为现在做一个基于Activit的工作流OA,在设计过程中需要显示用户设计出来的流程图。

所以需要使用一个流程图插件,可以用来加载流程,也可以直接通过拖拽的方式设计流程。

思来想去,搜索了很多插件,最后选择了jsplubm这款插件

官网地址是jsplumbtoolkit.com

流程包含了基本的用户任务,连接线。整个流程自上而下,且包含了“层”的概念,比如节点2和节点3是一个层的,节点4是单独一个层的,

主要是方便理清具体执行的顺序。

通过自己手动解析流程,可以展示基本的直线顺序流,并行切分汇聚顺序流,或者逆向的顺序流。当然这些都是后端的逻辑。

我是直接使用插件的flowchat demo (https://jsplumbtoolkit.com/community/demo/flowchart/index.html)直接改的

看了这个demo,我发现需要需要我手动在网页上添加用户任务

节点2

具体实施中,每个用户任务都用一个div表示 class是插件定义的 然后使用top和left属性确定他在页面上的位置。

id是用户任务的id

当流程执行的时候,在某个时刻,永远只会执行某一层的一个或者多个用户任务。

所以我们必须有个节点的数据,这个数据是金字塔一样一层一层盖上去的。

第一层是起始节点,第二层是起始节点的下级节点,第三层是第二层所有节点的下级节点。。。。

然后在网页上,用DIV一个个画出来,并附上相关的属性。

//加载所有的节点

//data 所有的节点数据

//FlowID 流程定义ID

function loadMe(data,FlowID){

nodes=new Array();

for(var i=0;i

CreateSequence(FlowID,data);//创建连接线

initcontrol(); // 初始化每个节点

}

var nodes=new Array();

//构建一行节点

//itmes:这行的所有元素集合

//rows: 第几行 value >=1

function createActivity(items,rows){

var height=50+(rows-1)*100 //高顿

var MarginLeft=new Array();

//更具不同的元素个数 初始化元素的左边距

switch(items.length){

case 1:

MarginLeft[0]=180;

break;

case 2:

MarginLeft[0]=120;

MarginLeft[1]=240;

break;

case 3:

MarginLeft[0]=60;

MarginLeft[1]=180;

MarginLeft[2]=300;

break;

case 4:

MarginLeft[0]=10;

MarginLeft[1]=130;

MarginLeft[2]=250;

MarginLeft[3]=380;

break;

}

for(var i=0;i

var mdiv='

'+items[i].NODE_NAME +'

';

$('#canvas').append(mdiv);

}

}

节点创建后就需要初始化节点的基本功能以及创建连接线了,基本代码如下

function CreateSequence(FlowID, Rowsdata) {

var instance = window.jsp = jsPlumb.getInstance({

// default drag options 默认拖动选项

DragOptions : {

cursor : 'pointer',

zIndex : 2000

},

// the overlays to decorate each connection with. note that the label

// overlay uses a function to generate the label text; in this

// case it returns the 'labelText' member that we set on each connection

// in the 'init' method below.

// 默认连接线的样式

ConnectionOverlays : [ [ "Arrow", { // 连接线箭头的样式

location : 1,

visible : true,

id : "ARROW",

length : 10,

events : { // 点击连接线事件

click : function() {

alert("you clicked on the arrow overlay")

}

}

} ],

// [ "Label", {

// location: 0.1,

// id: "label",

// cssClass: "aLabel",

// events:{

// tap:function() { alert("hey"); }

// }

// }]

],

Container : "canvas"

});

var basicType = {

connector : "statemachine",

proximityLimit : 1,

paintStyle : {

dashstyle : "0 0",

strokeStyle : "#61B7CF",

lineWidth : 2

}, // dashstyle 虚设置为线

hoverPaintStyle : {

strokeStyle : "#61B7CF"

},

// overlays: [

// "Arrow"

// ]

};

instance.registerConnectionType("basic", basicType);

// this is the paint style for the connecting lines..

var connectorPaintStyle = {

lineWidth : 2,

strokeStyle : "#61B7CF",

joinstyle : "round",

outlineColor : "white",

outlineWidth : 2

},

// .. and this is the hover style.

connectorHoverStyle = {

lineWidth : 2,

strokeStyle : "#61B7CF",

outlineWidth : 0,

outlineColor : "#61B7CF"

}, endpointHoverStyle = {

fillStyle : "#61B7CF",

strokeStyle : "#61B7CF"

},

// the definition of source endpoints (the small blue ones)

sourceEndpoint = {

endpoint : "Blank", // 隐藏连接点 显示连接点 Dot Blank

paintStyle : {

strokeStyle : "#7AB02C",

fillStyle : "transparent",

radius : 4,

lineWidth : 3

},

maxConnections : -1,

isSource : true,

connectorOverlays : [ [ "Arrow", {

width : 5,

length : 1,

location : 0

} ] ],

// gap 连接点的缺口 stub 线的最短高度和宽度 cornerRadius 连接点折点的弧度 StateMachine

// Flowchart

connector : [ "Flowchart", {

stub : [ 20, 30 ],

gap : 0,

cornerRadius : 5,

alwaysRespectStubs : true

} ],

connectorStyle : connectorPaintStyle,

hoverPaintStyle : endpointHoverStyle,

connectorHoverStyle : connectorHoverStyle,

dragOptions : {},

overlays : [ [ "Label", {

location : [ 0.5, 1.5 ],

// label: "Drag",

// cssClass: "endpointSourceLabel",

// visible:false

} ] ]

},

// the definition of target endpoints (will appear when the user drags a

// connection)

targetEndpoint = {

endpoint : "Blank", // DOt21

paintStyle : {

fillStyle : "#7AB02C",

radius : 5

},

hoverPaintStyle : endpointHoverStyle,

maxConnections : 30,

dropOptions : {

hoverClass : "hover",

activeClass : "active"

},

isTarget : true,

overlays : [ [ "Label", {

location : [ 0.5, -0.5 ],

label : "Drop",

cssClass : "endpointTargetLabel",

visible : false

} ] ]

}, init = function(connection) {

// connection.getOverlay("label").setLabel(connection.sourceId.substring(15)

// + "-" + connection.targetId.substring(15));

};

var _addEndpoints = function(toId, sourceAnchors, targetAnchors) {

for (var i = 0; i < sourceAnchors.length; i++) {

var sourceUUID = toId + sourceAnchors[i];

instance.addEndpoint(toId, sourceEndpoint, {

anchor : sourceAnchors[i],

uuid : sourceUUID

});

}

for (var j = 0; j < targetAnchors.length; j++) {

var targetUUID = toId + targetAnchors[j];

instance.addEndpoint(toId, targetEndpoint, {

anchor : targetAnchors[j],

uuid : targetUUID

});

}

};

// suspend drawing and initialise.

instance.batch(function() {

var Sequence;

$.ajax({

type : 'POST',

async : false,

url : "Form/GetSequenceByFlowID",

data : "ActivityID=" + FlowID,

success : function(data) {

Sequence = data;

},

error : function(data) {

alert("连接线数据加载失败:" + data)

},

// DataType:json

});

if (Sequence.length == 0) {// 只有一个开始节点

$('.window.jtk-node').attr("class","window jtk-node jsplumb"+ "-endpoint-anchor jsplumb-draggable jsplumb-connected");

return;

}

for (var x = 0; x < Sequence.length; x++) {

_addEndpoints(Sequence[x].SOURE_NODE, [ "BottomCenter" ], [

"TopCenter", "LeftMiddle", "RightMiddle" ]);

_addEndpoints(Sequence[x].TARGET_NODE, [ "BottomCenter" ],

[ "TopCenter", "LeftMiddle", "RightMiddle" ]);

console.log('xxx');

}

instance.bind("connection", function(connInfo, originalEvent) {

init(connInfo.connection);

});

// make all the window divs draggable

instance.draggable(jsPlumb

.getSelector(".flowchart-demo .window"), {

grid : [ 20, 20 ]

});

// 判断连接线是不是撤回的

function isBack(SOURE_NODE, TARGET_NODE) {

for (var i = 0; i < Rowsdata.length; i++) {

for (var x = 0; x < Rowsdata[i].length; x++) {

if (Rowsdata[i][x].NODE_ID == SOURE_NODE) {

SOURE_NODE = i;

}

}

}

for (var i = 0; i < Rowsdata.length; i++) {

for (var x = 0; x < Rowsdata[i].length; x++) {

if (Rowsdata[i][x].NODE_ID == TARGET_NODE) { SOURE_NODE = i; }

}

}

return SOURE_NODE > SOURE_NODE;

}

在这个方法中初始化每个节点,比如添加端点【endpoints 】,设置连接线的样式,设置箭头的样式,设置点击连接线的事件等等。

执行到这个的时候,流程图基本上就画出来了。

而且你可以拖动它。

Tips:

默认情况下端点是显示出来的,你还可以设置每个端点最多能连出或者连入多少条线,或者隐藏这个端点。

但隐藏后你就不能手动修改连接线了

附件

很久之前写的demo

http://pan.baidu.com/s/1miyEvCs

参考文档:http://www.cnblogs.com/sggx/p/3836432.html

activiti前端画图转化_用于Activiti前端显示流程图的插件相关推荐

  1. activiti前端画图转化_记Activiti入门使用-2 流程绘制、导入及开始一个流程

    一.流程绘制与导入 百度啥的找了好多bpmn绘制工具,都不尽如人意,大多数都不能编辑网关出口的跳转条件,最后还是选择了activiti官方的那个绘图的app... 啥都好,就是线不能弯,很难受.(后来 ...

  2. activiti前端画图转化_activiti在线画流程图

    springboot2.2 activiti6.0 activiti-modeler 5.22.0 注明:版本不一样会导致报错 效果图 代码分享: 链接:https://pan.baidu.com/s ...

  3. j2ee可以用于前端开发吗_用于J2EE开发的Cloud IDE

    j2ee可以用于前端开发吗 随着许多传统软件工具进入云计算,我想看看它们与传统工具的比较. 我的兴趣是J2EE技术​​,并开始寻找一种云服务,该服务使我能够开发,测试和部署J2EE应用程序. 我很快发 ...

  4. 前端面试面向对象_面向初级前端开发人员的面试问题

    前端面试面向对象 The purpose of this article is to familiarize fresh Front-End Web Developers with text book ...

  5. 前端填空题_一年前端面试总结|入职字节|2020.8

    站在未来看现在 你当像鸟飞向你的山 前言     普通本科,软件工程专业,2019年毕业进入奇安信集团(前360企业安全),实习期间遇到一群可以一起嗨的朋友,感觉很幸福,也很庆幸能够遇到hin nic ...

  6. python前端开发招聘_【天津前端开发招聘_最新天津前端开发招聘信息】-前程无忧...

    天津卓众信息技术有限公司天津-西青区0.6-1万/月11-23 学历要求:本科|工作经验:3-4年|公司性质:民营公司|公司规模:少于50人 1.根据产品设计实现产品的页面交互和数据逻辑展示,负责前端 ...

  7. 前端学习路线_前端学习路线图

    2020年全新前端学习路线图分享给大家! 学习是一个循序渐进的过程,是一件非常难得坚持的事情.如果真的想学习前端开发,一定要下决心! 我这里分享给你的前端学习路线图,希望对你有帮助,以下为2020年更 ...

  8. Python 3/前端 画图工具:Matplotlib,canvajs,pyecharts

    之前我一直是用Matplotlib画图,写了挺多博客: Python:matplotlib绘图时指定图像大小,放大图像 matplotlib绘制平滑的曲线 Matplotlib使用日期作为横坐标 ma ...

  9. 乾坤 微前端_微前端架构初探以及我的前端技术盘点

    前言 最近几年微前端一直是前端界的热门议题, 它类似于微服务架构, 主要面向于浏览器端,能将一个复杂而庞大的单体应用拆分为多个功能模块清晰且独立的子应用,且共同服于务同一个主应用.各个子应用可以独立运 ...

最新文章

  1. 医学影像AI:全球市场展望
  2. OneAPM挂牌新三板,资本市场一片看好!
  3. 你真的了解 i++, ++i 和 i+++++i 以及 i+++i++ 吗?
  4. [网络安全自学篇] 八十.WHUCTF之WEB类解题思路WP(代码审计、文件包含、过滤绕过、SQL注入)
  5. 转.我在MySQL的那些年
  6. Go学习笔记—并发高级
  7. 使用X.509数字证书加密解密实务(一)-- 证书的获得和管理
  8. 中文文本纠错算法实现
  9. java中字符串和数组如何比较_[Java教程]javascript中数组和字符串的方法比较
  10. 指针的高阶用法——指向指针的指针
  11. GDI+中的图片处理类Image或Bitmap
  12. vue中实现页面全屏和指定元素全屏
  13. AlterID.exe 报错问题
  14. 智伴机器人班尼怎么联网_智伴机器人官网
  15. vue语音播放通知功能
  16. 前端分页加载功能实现?
  17. 腾讯云服务器Lighthouse和CVM区别
  18. C++链接报错:which may bind externally can not be used when making a shared object; recompile with -fPIC
  19. mmorpg无缝地图
  20. 算法入门DP-免费馅饼

热门文章

  1. Redis学习总结(15)——Redis 基本数据类型使用场景
  2. Java虚拟机学习总结(1)——JVM内存模型
  3. php mysql_fetch_field_PHP mysqli_fetch_field() 函数
  4. python矩阵元素排序,使用Python基于列表值对矩阵列进行排序
  5. Opencv实现多幅图片拼接在一起
  6. mysql5.0.x统计每秒增删改查替换数及系统每秒磁盘IO
  7. SQL内连接-外连接join,left join,right join,full join
  8. 监控openfire数据
  9. 下了班----你干啥
  10. Exchange server 2007中启用pop3和IMAP4协议访问