流程图编辑控件示例-https://huang-qing.github.io/workflow-editor/
-
支持IE8+及现代浏览器。
-
流程图支持横向流程图和纵向流程图。通过开始节点和结束节点的位置自动调整流程图的模式,在不同的流程图模式下,连线的展示方式不同。
-
支持流程模版的编辑和浏览模式。编辑模式中会出现工具栏菜单,用其创建节点和连线;浏览模式中显示流程图,并根据流程图大小自动调整画布大小。
-
流程图支持节点、连线的验证显示;连线的条件显示;浏览模式节点的Tooptip显示。
-
支持全局和实例配置工具栏节点、连线皮肤,事件等相关配置项。
注意:以/
结束
$.workflow.config.basePath = "XXXX/";
配置的Id要保证唯一性
$.workflow.config.guid='xxxxxx'
流程状态默认有两个:
RUN
执行中COMPLETE
完成
$.workflow.config.state.RUN = {
fill: "270-#fffce1-#ffff99",
stroke: "#edd770"
}
$.workflow.config.event.toggle = function (pid, prevProps, currProps, props){}
$.workflow.config.event.validate = function (pid, props){}
流程节点的验证事件-示例
$.workflow.config.event.validate = function (pid, props) {
console.log({ pid: pid, props: props });
var list = [];
//根据实际情况添加验证提示信息
for (var i in this.path) {
list.push({ key: i, value: "天空中会亮的星 星星星星" });
}
return list;
};
$.workflow.config.event.lineMoveEnd = function (pid, currProps, props, direction){}
$.workflow.config.event.selectTemplate = function (pid, props){}
$.extend(true, $.workflow.config.rect, {
attr: {
r: 8,
fill: "270-#fff-#d7d7d7",
stroke: '#ccc',
"stroke-width": 1,
"stroke-width-active": 2,
"stroke-active": '#0099cc'
}
});
$.extend(true, $.workflow.config.path, {
attr: {
stroke: '#0099ff',
"stroke-width": 2,
"stroke-width-active": 3,
"arrow-end": 'block'
},
rect: {
attr: {
width: 4,
height: 4,
fill: "#0066cc",
stroke: "#0066cc",
"stroke-width": 1,
cursor: "opinter"
}
}
});
编辑状态下,选择工具栏流程节点类型
菜单,进入节点添加状态。在画布中点击鼠标左键添加(可连续添加多个);点击右键结束并恢复为选择状态。
编辑状态下,选择工具栏连线
菜单,进入连线添加状态。在画布中选择连线起始位置,按下鼠标左键并移动鼠标至结束位置,完成画线的动作(可连续添加多个);点击右键结束并恢复为选择状态。
showType
: 显示类型
image
text
null
: 此类型下不会在工具栏模版中显示
name
: 节点的类型
text
: 节点显示名称
img
: 节点的默认图片
nodeType
: 节点的类型。为null
时为非创建节点类型(可以理解为功能菜单,不是流程图中的节点类型)
{
showType: 'image',
name: '<<save>>',
text: {
text: '保存'
},
img: {
src: '~/images/save.png'
},
nodeType: null
}
$.workflow.config.tools.states
示例:
$.extend(true, $.workflow.config.tools.states, {
load: {
showType: 'image',
type: 'load',
name: '<<load>>',
text: {
text: '加载'
},
img: {
src: './images/load.png',
width: 16,
height: 16
},
nodeType: null,
},
view: {
showType: 'image',
type: 'view',
name: '<<view>>',
text: {
text: '浏览'
},
img: {
src: './images/view.png',
width: 16,
height: 16
},
nodeType: null
},
save: {
showType: 'image',
type: 'save',
name: '<<save>>',
text: {
text: '保存'
},
img: {
src: '~/images/save.png',
width: 16,
height: 16
},
nodeType: null
}
});
$.workflow.config.tools.event
示例:
$.extend(true, $.workflow.config.tools.event, {
load: function (pid, props) {
opt.restore = restore2;
$("#paper").workflow(opt);
},
view: function (pid, props) {
opt.editable = false;
$("#paper").workflow(opt);
},
save: function (pid, props) {
var restore = $("#paper").workflow('save');
}
});
Name
: 流程图标题
DisplayName
: 流程图显示标题
Description
: 流程图说明
NodeList
: 流程图节点数据
LinkList
: 流程图连线数据
{
"Name": "并行或流程",
"DisplayName": "并行或流程",
"Description": "",
"NodeList": [],
"LinkList": []
}
NodeID
: 节点Id。开始节点和结束节点固定为StartNode
和EndNode
;其它的节点id更加配置项guid生成。
NodeType
: 节点类型。默认有以下类型:
StartNode
: 开始EndNode
: 结束FlowSwitch
: 分支FlowAnd
: 并行与FlowOr
: 并行或FlowExecute
: 执行FlowAudit
: 评审FlowCheck
: 签收FlowBusiness
: 业务
NodeText
: 节点名称
CenterX
: 节点中心位置X坐标
CenterY
: 节点中心位置Y坐标
ImagePath
: 节点显示图片。此项为空时,根据节点类型NodeType
匹配显示。
Tooltip
: 在浏览模式时有效。使用\n
换行显示。
State
: 节点状态。默认2个状态RUN
和COMPLETE
{
"NodeID": "StartNode",
"NodeType": "StartNode",
"NodeText": "开始",
"CenterX": 300,
"CenterY": 78,
"State": "COMPLETE"
"ImagePath": "workflow-editor/img/StartNode.png",
"Tooltip": "我是Tooltip...."
}
LinkID
: 连线Id。
StartNodeID
: 关联的起始流程节点
EndNodeID
: 关联的结束流程节点
StartX
: 起始位置X轴坐标
StartY
: 起始位置Y轴坐标
EndX
: 结束位置X轴坐标
EndY
: 结束位置Y轴坐标
DisplayType
: 流程线类型,在绘图的时候会自动赋值。包括3种:
straightLine
: 直线brokenHLine
: 水平折线brokenVLine
: 垂直折线
FirstLength
: 绘制折线的拐点参数,绘图时自动赋值。保存为整型。
ConditionText
: 条件文本显示
State
: 流程线状态
{
"LinkID": "LINEb0baa3eed45d4cd7b5ba48480a6cc588",
"StartNodeID": "StartNode",
"StartX": 304,
"StartY": 73,
"EndNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-SNode",
"EndX": 303,
"EndY": 194,
"DisplayType": 0,
"FirstLength": 0,
"ConditionText": '一二三',
"State": "COMPLETE"
}
配置项也可以通过示例进行配置。
pid
: 流程图的id
basePath
: 此插件文件(workflow-editor.js)所在的Web站点部署路径
restore
: 流程图数据
editable
: 是否为编辑模式。默认为true
//节点数据
var restore = {
"Name": "并行或流程",
"DisplayName": "并行或流程",
"Description": "",
"NodeList": [{
"NodeID": "StartNode",
"NodeType": "StartNode",
"NodeText": "开始",
"CenterX": 300,
"CenterY": 78,
"Tooltip": "我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n",
"PluginList": []
}, {
"NodeID": "EndNode",
"NodeType": "EndNode",
"NodeText": "结束",
"CenterX": 293,
"CenterY": 557,
"Tooltip": "我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n",
"PluginList": []
}, {
"NodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-SNode",
"NodeType": "FlowOr",
"NodeText": "分支开始",
"CenterX": 299,
"CenterY": 218,
"ImagePath": "workflow-editor/img/tools/FlowOr.png",
"PluginList": [],
"Tooltip": "我是Tooltip.... \n 啊哈哈啊哈哈哈 \n ",
"State": "COMPLETE"
}, {
"NodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-ENode",
"NodeType": "FlowOr",
"NodeText": "分支结束",
"ExtendProperty": null,
"CenterX": 295,
"CenterY": 431,
"ImagePath": "~/workflow-editor/img/tools/FlowOr.png",
"PluginList": []
}, {
"NodeFlag": "",
"ShowOrder": "000",
"EffectivityTime": 0,
"AdjectiveRemindTime": 0,
"IsIgnoreDefaultActor": false,
"TaskType": null,
"ChangeActorNodeList": [{
"Name": "NODE3af3acdbcd3440bf809ac30a3700fa15",
"IsAllowChange": false,
"IsValidateNull": false,
"IsValidateCustomNull": false
}],
"AuditActor": [{
"Name": "User",
"Actors": "USERINFO_Test1;USERINFO_Test2;"
}],
"ResultList": [{
"Name": "通过",
"ParameterName": "Result",
"ParameterValue": 1
}, {
"Name": "不通过",
"ParameterName": "Result",
"ParameterValue": 2
}],
"NodeID": "NODE026c3bdaed0c46d0a07b3f39c944f119",
"NodeType": "FlowExecute",
"NodeText": "执行1执行1执行",
"ExtendProperty": null,
"CenterX": 193,
"CenterY": 326,
"ImagePath": "workflow-editor/img/tools/FlowExecute.png",
"Tooltip": "我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n我是Tooltip.... \n 啊哈哈啊哈哈哈 \n",
"State": "RUN",
"PluginList": [{
"Name": "SendFlowMessage",
"BeforeExec": true,
"Content": "{\"MessageType\":{\"RTX\":false,\"Email\":false,\"InstantMessage\":true},\"SendUser\":{\"CURRENTUSER\":true,\"PROMOTER\":false}}"
}]
},
{
"NodeFlag": "fsgsdfg",
"ShowOrder": "000",
"EffectivityTime": 3064,
"AdjectiveRemindTime": 1563,
"IsIgnoreDefaultActor": false,
"TaskType": "",
"ChangeActorNodeList": [{
"Name": "NODE026c3bdaed0c46d0a07b3f39c944f119",
"IsAllowChange": false,
"IsValidateNull": false,
"IsValidateCustomNull": false
}],
"AuditActor": [{
"Name": "User",
"Actors": "USERINFO_System;"
}],
"ResultList": [{
"Name": "通过",
"ParameterName": "Result",
"ParameterValue": 1
}, {
"Name": "不通过",
"ParameterName": "Result",
"ParameterValue": 2
}],
"NodeID": "NODE3af3acdbcd3440bf809ac30a3700fa15",
"NodeType": "FlowExecute",
"NodeText": "执行2",
"ExtendProperty": null,
"CenterX": 412,
"CenterY": 325,
"Tooltip": "Tooltip:测试\n我是Tooltip....",
"State": "RUN",
"PluginList": [{
"Name": "SendFlowMessage",
"BeforeExec": true,
"Content": "{\"MessageType\":{\"RTX\":false,\"Email\":false,\"InstantMessage\":true},\"SendUser\":{\"CURRENTUSER\":true,\"PROMOTER\":false}}"
}]
}
],
"LinkList": [{
"LinkID": "LINEb0baa3eed45d4cd7b5ba48480a6cc588",
"StartNodeID": "StartNode",
"StartX": 304,
"StartY": 73,
"EndNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-SNode",
"EndX": 303,
"EndY": 194,
"DisplayType": 0,
"FirstLength": 0,
"Conditions": [],
"HaveCondition": 0,
"ConditionText": '一二三',
"Tooltip": "Tooltip: 测试 \n 我是Tooltip.... \n 啊哈哈啊哈哈哈 \n",
"State": "COMPLETE"
}, {
"LinkID": "LINEd7e4d670466c46218f295d228aebf37d",
"StartNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-SNode",
"StartX": 299,
"StartY": 240,
"EndNodeID": "NODE026c3bdaed0c46d0a07b3f39c944f119",
"EndX": 194,
"EndY": 300,
"DisplayType": 1,
"FirstLength": 49,
"Conditions": [],
"HaveCondition": 0,
"ConditionText": '1+1=2?',
"Tooltip": "Tooltip:测试/n我是Tooltip....",
"State": "COMPLETE"
}, {
"LinkID": "LINEbcf4705be3f24b9a81391defd3376532",
"StartNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-SNode",
"StartX": 299,
"StartY": 240,
"EndNodeID": "NODE3af3acdbcd3440bf809ac30a3700fa15",
"EndX": 412,
"EndY": 305,
"DisplayType": 1,
"FirstLength": 52,
"Conditions": [],
"HaveCondition": 0,
"ConditionText": '1+1=2?',
"Tooltip": "Tooltip:测试 我是Tooltip....",
"State": "COMPLETE"
}, {
"LinkID": "LINEb72d43761b4040e8911d32cbad70652b",
"StartNodeID": "NODE026c3bdaed0c46d0a07b3f39c944f119",
"StartX": 194,
"StartY": 344,
"EndNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-ENode",
"EndX": 295,
"EndY": 409,
"DisplayType": 1,
"FirstLength": 50,
"Conditions": [],
"HaveCondition": 0,
"ConditionText": '天马流星拳'
}, {
"LinkID": "LINEbd51561424674ce184e6f1db8291c899",
"StartNodeID": "NODE3af3acdbcd3440bf809ac30a3700fa15",
"StartX": 412,
"StartY": 349,
"EndNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-ENode",
"EndX": 295,
"EndY": 409,
"DisplayType": 1,
"FirstLength": 50,
"Conditions": [],
"HaveCondition": 0,
"ConditionText": '1+1=2?'
}, {
"LinkID": "LINE011022ab7c6d46ec890920c07244e3c2",
"StartNodeID": "NODE43a1ec2fb4a143fcb915183b4b0c890d-ENode",
"StartX": 306,
"StartY": 438,
"EndNodeID": "EndNode",
"EndX": 302,
"EndY": 603,
"DisplayType": 0,
"FirstLength": 0,
"Conditions": [],
"HaveCondition": 0,
"ConditionText": '1+1=2?'
}]
}
//配置项
var opt = {
pid: "pid",
basePath: './workflow-editor/',
tools: {
states: {
load: {
showType: 'image',
type: 'load',
name: '<<load>>',
text: {
text: '加载'
},
img: {
src: './images/load.png',
width: 16,
height: 16
},
nodeType: null,
},
view: {
showType: 'image',
type: 'view',
name: '<<view>>',
text: {
text: '浏览'
},
img: {
src: './images/view.png',
width: 16,
height: 16
},
nodeType: null
},
save: {
showType: 'image',
type: 'save',
name: '<<save>>',
text: {
text: '保存'
},
img: {
src: '~/images/save.png',
width: 16,
height: 16
},
nodeType: null
}
},
event: {
load: function (pid, props) {
opt.restore = restore2;
$("#paper").workflow(opt);
},
view: function (pid, props) {
opt.editable = false;
$("#paper").workflow(opt);
},
save: function (pid, props) {
var restore = $("#paper").workflow('save');
}
},
},
restore: restore
};
$("#paper").workflow(opt);