领导有一个搞内控流程优化的思路,找我问问有没有什么想法。想将公司后台的风险库,控制库,组织机构等与内控流程联系起来,用的比较普遍的流程图设计软件就visio了。有没有一个办法可以把visio嵌入到B/S系统中呢。
带着这个疑问到网络上试着搜索着。突然一个词进入我的视线--mxgraph。B/S结构,可以加泳道,多种图形形状和图片,支持导出图片等支持一定让这个web流程设计项目增色不少。于是决定找了一个破解版本下来研究研究。
在本机搭好环境后,拿给咨询部的同事看了看,觉得不错,要是支持visio里德标准流程图的图元就好了。于是仔细看了看它底层画图用的是vml,就有一点信心按照自己的想法画些图元出来了。说干就干。于是就开始了图元创造。
mxclient.js这个文件是mxgraph的核心的js文件。那些图元及编辑器等就是在这里边定义的。
首先声明几个形状
//create shape by ryan start ---------- SHAPE_RYAN: 'ryan', SHAPE_STORAGE: 'storage', SHAPE_RECORD : 'record', SHAPE_TAPE : 'tape', SHAPE_HANDINPUT : 'handinput', SHAPE_HANDOPERATOR : 'handoperator', SHAPE_DATA: 'data', SHAPE_CIRCULATION: 'circulation', SHAPE_CARD: 'card', SHAPE_PREFLOW : 'preflow', SHAPE_INTERNALSTORAGE : 'internalstorage', //create shape by ryan end ----------
让这些形状继承默认的形状
//create shape by ryan start -------------------------------- mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_RYAN] = mxRyan; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_STORAGE] = mxStorage; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_RECORD] = mxRecord; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_TAPE] = mxTape; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_HANDINPUT] = mxHandInput; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_HANDOPERATOR] = mxHandOperator; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_DATA] = mxData; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_CIRCULATION] = mxCirculation; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_CARD] = mxCard; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_PREFLOW] = mxPreflow; mxCellRenderer.prototype.defaultShapes[mxConstants.SHAPE_INTERNALSTORAGE] = mxInternalStorage; //create shape by ryan end --------------------------------
下面是这些形状的具体画法的方法
//create shape by ryan start---------------------------------------- function mxRyan(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxRyan.prototype = new mxActor(); mxRyan.prototype.constructor = mxActor; mxRyan.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, h);//start from path.lineTo(0, 0);// line to path.lineTo(w, 0);// line to path.lineTo(w, h);//line to path.curveTo(w * 0.4, h - w * 0.20 , 2.4 * w * 0.20, h + w * 0.20 , 0, h);// radian path.close(); }; function mxTape(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxTape.prototype = new mxActor(); mxTape.prototype.constructor = mxActor; mxTape.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, h); path.lineTo(0, 0); path.curveTo(w * 0.4, w * 0.20 , 2.8 * w * 0.20, - w * 0.20 , w, 0); path.lineTo(w, h); path.curveTo(w * 0.4, h - w * 0.20 , 2.4 * w * 0.20, h + w * 0.20 , 0, h); path.close(); }; function mxStorage(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxStorage.prototype = new mxActor(); mxStorage.prototype.constructor = mxActor; mxStorage.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, 0); path.curveTo(0, 0, -0.26 * w, 0.50 * h, 0, h); path.lineTo(w, h); path.curveTo(w, h, 0.74 * w, 0.50 * h, w, 0); path.lineTo(w, 0); path.close(); }; function mxRecord(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxRecord.prototype = new mxActor(); mxRecord.prototype.constructor = mxActor; mxRecord.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, 0); path.curveTo(0, 0, -0.26 * w, 0.50 * h, 0, h); path.lineTo(w, h); path.curveTo(w, h, 0.74 * w, 0.50 * h, w, 0); path.curveTo(w, 0, 1.24 * w, 0.50 * h, w, h); path.curveTo(w, h, 0.74 * w, 0.50 * h, w, 0); path.close(); }; function mxHandInput(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxHandInput.prototype = new mxActor(); mxHandInput.prototype.constructor = mxActor; mxHandInput.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, h/2); path.lineTo(0, h); path.lineTo(w, h); path.lineTo(w, 0); path.close(); }; function mxHandOperator(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxHandOperator.prototype = new mxActor(); mxHandOperator.prototype.constructor = mxActor; mxHandOperator.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, 0); path.lineTo(w * 0.25, h); path.lineTo(w * 0.75, h); path.lineTo(w, 0); path.close(); }; function mxData(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxData.prototype = new mxActor(); mxData.prototype.constructor = mxActor; mxData.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(w * 0.125, 0); path.lineTo(-w * 0.125, h); path.lineTo(w * 0.875, h); path.lineTo(w * 1.125, 0); path.close(); }; function mxCirculation(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxCirculation.prototype = new mxActor(); mxCirculation.prototype.constructor = mxActor; mxCirculation.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, h / 3); path.lineTo(0, h); path.lineTo(w, h); path.lineTo(w, h /3); path.lineTo(w /5 * 4, 0); path.lineTo(w /5, 0); path.close(); }; function mxCard(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxCard.prototype = new mxActor(); mxCard.prototype.constructor = mxActor; mxCard.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, h / 3); path.lineTo(0, h); path.lineTo(w, h); path.lineTo(w, 0); path.lineTo(w /5, 0); path.close(); }; function mxPreflow(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxPreflow.prototype = new mxActor(); mxPreflow.prototype.constructor = mxActor; mxPreflow.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, 0); path.lineTo(0, h); path.lineTo(w, h); path.lineTo(w, 0); path.lineTo(0, 0); path.moveTo(w /7 , 0); path.lineTo(w /7 , h); path.moveTo(w /7 * 6 , 0); path.lineTo(w /7 * 6 , h); path.close(); }; function mxPreflow(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxPreflow.prototype = new mxActor(); mxPreflow.prototype.constructor = mxActor; mxPreflow.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, 0); path.lineTo(0, h); path.lineTo(w, h); path.lineTo(w, 0); path.lineTo(0, 0); path.moveTo(w /7 , 0); path.lineTo(w /7 , h); path.moveTo(w /7 * 6 , 0); path.lineTo(w /7 * 6 , h); path.close(); }; function mxInternalStorage(bounds, fill, stroke, strokewidth){ this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = strokewidth || 1; }; mxInternalStorage.prototype = new mxActor(); mxInternalStorage.prototype.constructor = mxActor; mxInternalStorage.prototype.redrawPath = function(path, x, y, w, h){ path.moveTo(0, 0); path.lineTo(0, h); path.lineTo(w, h); path.lineTo(w, 0); path.lineTo(0, 0); path.moveTo(w /7 , 0); path.lineTo(w /7 , h); path.moveTo(0 , w / 7); path.lineTo(w, w / 7); path.close(); }; //create shape by ryan end ----------
然后我们再GraphEditor.js中添加到库中
//create shape by ryan insertVertexTemplate(library, graph, '文档', 'images/ryan.gif', 'shape=ryan', 80, 60); insertVertexTemplate(library, graph, '数据', 'images/data.gif', 'shape=data', 80, 60); insertVertexTemplate(library, graph, '存储数据', 'images/storage.gif', 'shape=storage', 80, 60); insertVertexTemplate(library, graph, '直接数据', 'images/record.gif', 'shape=record', 80, 60); insertVertexTemplate(library, graph, '纸带', 'images/tape.gif', 'shape=tape', 80, 60); insertVertexTemplate(library, graph, '手动输入', 'images/handinput.gif', 'shape=handinput', 100, 50); insertVertexTemplate(library, graph, '手动操作', 'images/handoperator.gif', 'shape=handoperator', 80, 60);