利用jsplumb画流程图

来源:互联网 发布:淘宝店铺退款率在哪看 编辑:程序博客网 时间:2024/06/05 06:45

http://blog.csdn.net/u013705066/article/details/53740327?locationNum=3&fps=1

最近根据项目的需求,需要做一个流程审批系统。经过对各个绘制流程图的代码对比,最终选用了jsplumb.js来做。因为该JS有完整的API介绍并且提供付费版的技术支持。因为项目初期并不需要用到过多的toolkit版的功能,因此暂时用的是社区版进行开发。

我在用这个绘制流程图的时候,觉得一个流程图里就两个要素,一个是节点,一个是连线,也就是jsplumb里所谓的connector。因此在建数据库的时候建了两张表,分别保存节点和线。

以下是封装的flowchart.js

/** * [Flowchart 根据需求对流程图的封装] * 依赖jquery.js * @method Flowchart * @param  {[array]}  node [description] * @param  {[array]}  line [description] */function Flowchart(node , line){    //流程图的节点图    this.node = node;    //流程图的线    this.line = line;}Flowchart.prototype = {    constructor : Flowchart,    instance : jsPlumb.getInstance({        DragOptions: { cursor: 'pointer', zIndex: 2000 },        ConnectionOverlays: [            [ "Arrow", {//箭头的样式                location: 1,                visible:true,                width:11,                length:11,                id:"ARROW",            }],            [ "Label", {//连线上的label                location: 0.4,                id: "label",                cssClass: "aLabel",            }]        ],        Container: "canvas" //画布容器    }),    config : {        nodeName : 'LCTNODE',//对应html里节点的ID前缀        elementName : 'node',        editable : false,        sourceEndpoint : {            endpoint: "Dot",            paintStyle: {                //stroke: "#7AB02C",                fill: "transparent",                radius: 7,                strokeWidth: 1            },            isSource: true,            connector: [ "Flowchart", {                stub: [40, 60],                //gap: 10,                cornerRadius: 5,//连线的弯曲度                alwaysRespectStubs: true            } ],//流程图的线            connectorStyle: {                strokeWidth: 2,                stroke: "#61B7CF",                joinstyle: "round",                outlineStroke: "white",                outlineWidth: 5            },            connectorHoverStyle: {                strokeWidth: 3,                stroke: "#216477",                outlineWidth: 5,                outlineStroke: "white"            },            maxConnections : 3,        },        targetEndpoint : {            endpoint: "Dot",            paintStyle: {                //fill: "#7AB02C",                radius: 7            },            maxConnections: 3,            isTarget: true,        }    },    _addEndpoints : function(){        for(var i in this.node){            var _node = this.node[i];            //画出点            if(_node.source){                _node.source = _node.source.split(',');            }else{                _node.source = [];            }            for(var j = 0; j < _node.source.length; j++ ){                //设置uuid的规则  例如'LCTNODE1bottomCenter'                var sourceUUID = this.config.nodeName + _node.id + _node.source[j];                this.instance.addEndpoint(this.config.nodeName + _node.id , this.config.sourceEndpoint, {                    anchor: _node.source[j],                    uuid: sourceUUID                });            }            //画入点            if(_node.target){                _node.target = _node.target.split(',');            }else{                _node.target = [];            }            for(var j = 0; j < _node.target.length; j++ ){                //设置uuid的规则  例如'LCTNODE1bottomCenter'                var sourceUUID = this.config.nodeName + _node.id + _node.target[j];                this.instance.addEndpoint(this.config.nodeName + _node.id , this.config.targetEndpoint, {                    anchor: _node.target[j],                    uuid: sourceUUID                });            }        }    },    _connect : function(){        for(var i in this.line){            var _line = this.line[i];            var source = this.config.nodeName + _line.node_id + _line.source;            var target = this.config.nodeName + _line.next_node_id + _line.target;            var connection = this.instance.connect({                uuids: [source, target],                editable: this.config.editable,            });            if(connection){                connection.getOverlay('label').setLabel(_line.label);            }        }    },    _helper : {        uuid2nodeId : function(uuid){            var arr = uuid.match(/\d+/);            return arr[0];        },        uuid2AnchorLocation : function(uuid){            var str = uuid.replace(/(.*)\d+/ , '');            return str;        }    },    // _render : function(){    //  var renderer = jsPlumbToolkit.Support.ingest({    //      jsPlumb:this.instance,    //  });    // },    show : function(){        this._addEndpoints();        this._connect();        //this._render();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146

前端HTML界面是用vue循环的从数据库里取出的数据

<div class="jtk-demo-canvas canvas-wide flowchart-demo jtk-surface jtk-surface-nopan" id="canvas">    <div v-for="jtknode in node"         class="window jtk-node {{jtknode.className}}"         id="LCTNODE{{jtknode.id}}"         style="{{jtknode.style}}"         @click="open(jtknode)">        <strong>{{jtknode.label}}</strong>    </div></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

页面里调用的时候在jsplumb加载完成后传入节点数据和线的数据

//加载流程图工具    jsPlumb.ready(function () {        var flowchart = new Flowchart(flowchartData.node , flowchartData.line);        flowchart.show();    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

写完以后 好像得介绍以下表的结构 
节点表node 
懒得建表了 直接贴sql了

---- 表的结构 `flowchart_node`--CREATE TABLE `flowchart_node` (  `id` int(10) UNSIGNED NOT NULL,  `flowchart_id` int(10) UNSIGNED NOT NULL COMMENT '流程图的id,对应flowchart表里的id',  `type` enum('START','END','APPROVE','PROCESS','SWITCH') NOT NULL COMMENT 'START开始END结束APPROVE审批节点PROCESS流程节点SWITCH分支节点',  `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '备注',  `source` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '节点的出点,用逗号分隔',  `target` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '节点的入点,用逗号分隔',  `label` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '节点里显示的文字',  `style` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '节点的样式,通常包括节点在画布的位置样式等') ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='流程图的节点图 这里我们把每一个流程图里的每一个节点都存到这里,';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

连线表line

---- 表的结构 `flowchart_line`--CREATE TABLE `flowchart_line` (  `id` int(10) UNSIGNED NOT NULL,  `node_id` int(10) UNSIGNED NOT NULL COMMENT '对应flowchart_node表里的id,即线的起点所在的节点',  `source` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '线的起点,同node区分,一个node可以有多个出点和入点,单是一条线只有唯一的起点和终点',  `target` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '线的终点 ',  `label` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '线上显示的文字',  `next_node_id` int(10) UNSIGNED NOT NULL COMMENT '对应pro_flowchart_node的id ,即该线的终点所在的节点id',  `flowchart_id` int(10) UNSIGNED NOT NULL COMMENT '对应流程图的id') ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='流程图的线对应的表 每一个流程图的一条线都应该在这里有备份';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

以上是从我们的流程审批系统里摘出来的部分代码。 
实现了从数据库里获得数据然后在画布上利用jsplumb.js画出来。其他可以根据自己的情况去搞。。。 
后期会根据需要发布jsplumb的toolkit版的使用代码。。。