主要修改一下功能:javascript
1.將線類型精簡成一個path.css
2.增長駁回線路 rejectpath。java
3.增長path_p ,path_arr屬性,記錄線軌跡。node
4.去除自定義屬性顯示。jquery
5.增長右鍵菜單支持。web
6.支持bootstrap .json
(function ($) { var myflow = {}; myflow.config = { editable: true, allowStateMutiLine:true, moving:{ flag:false, prepdot:{x:0,y:0}, dots:[], isNewDot:false, temp:[], preRect:null }, historys:[], lineHeight: 15, basePath: '', rect: {// 狀態 attr: { x: 10, y: 10, width: 100, height: 50, r: 5, fill: '90-#fff-#C0C0C0', stroke: '#000', "stroke-width": 1 }, showType: 'image&text', // image,text,image&text type: 'normal', name: { text: 'normal', 'font-style': 'italic' }, text: { text: '普通', 'font-size': 13 }, margin: 5, props: [], img: {} }, path: {// 路徑轉換 attr: { path: { path: 'M10 10L100 100', stroke: '#1296DB', fill: "none", "stroke-width": 2, cursor: "pointer" }, arrow: { path: 'M10 10L10 10', stroke: '#1296DB', fill: "#808080", "stroke-width": 2, radius: 4 }, fromDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, toDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, bigDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, smallDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 3 }, text: { cursor: "move", 'background': '#000' } }, text: { patten: '', textPos: { x: 0, y: -10 } }, props: { text: { name: "text", label: "顯示", value: "", editor: function() { return new myflow.editors.textEditor() } } } }, lpath: {// 流路徑 attr: { path: { path: 'M10 10L100 100', stroke: '#1E90FF', fill: "none", "stroke-width": 2, cursor: "pointer" }, arrow: { path: 'M10 10L10 10', stroke: '#1E90FF', fill: "#1E90FF", "stroke-width": 2, radius: 4 }, fromDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, toDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, bigDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, smallDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 3 }, text: { cursor: "move", 'background': '#000' } }, text: { patten: '', textPos: { x: 0, y: -10 } }, props: { text: { name: "text", label: "顯示", value: "", editor: function() { return new myflow.editors.textEditor() } }, tmp0: { name: "tmp0", label: "關聯流1", value: "", editor: function() { return new myflow.editors.inputEditor() } }, tmp1: { name: "tmp1", label: "關聯流2", value: "", editor: function() { return new myflow.editors.inputEditor() } } } }, jpath: {// 路徑轉換 attr: { path: { path: 'M10 10L100 100', stroke: '#FFC125', fill: "none", "stroke-width": 2, cursor: "pointer" }, arrow: { path: 'M10 10L10 10', stroke: '#FFC125', fill: "#FFC125", "stroke-width": 2, radius: 4 }, fromDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, toDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, bigDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, smallDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 3 }, text: { cursor: "move", 'background': '#000' } }, text: { patten: '', textPos: { x: 0, y: -10 } }, props: { text: { name: "text", label: "顯示", value: "", editor: function() { return new myflow.editors.textEditor() } }, tmp0: { name: "tmp0", label: "關聯積1", value: "", editor: function() { return new myflow.editors.inputEditor() } }, tmp1: { name: "tmp1", label: "關聯積2", value: "", editor: function() { return new myflow.editors.inputEditor() } } } }, cpath: {// 參數 attr: { path: { path: 'M10 10L100 100', stroke: '#8B3626', fill: "none", "stroke-width": 2, cursor: "pointer" }, arrow: { path: 'M10 10L10 10', stroke: '#8B3626', fill: "#8B3626", "stroke-width": 2, radius: 4 }, fromDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, toDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, bigDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 2 }, smallDot: { width: 5, height: 5, stroke: '#fff', fill: '#000', cursor: "move", "stroke-width": 3 }, text: { cursor: "move", 'background': '#000' } }, text: { patten: '', textPos: { x: 0, y: -10 } }, props: { text: { name: "text", label: "顯示", value: "", editor: function() { return new myflow.editors.textEditor() } }, tmp0: { name: "tmp0", label: "關聯參數1", value: "", editor: function() { //我要取到path的from,再根據from的值取到設備類型type,再根據type生成{name,value} //console.log(from.getEquipmentType()); return new myflow.editors.selectEditor([{name:'',value:0},{name:'溫度',value:1},{name:'bbb',value:2}]) } }, tmp1: { name: "tmp1", label: "關聯參數2", value: "", editor: function() { return new myflow.editors.selectEditor([{name:'aaa',value:1},{name:'bbb',value:2}]) } } } }, tools: {// 工具欄 attr: { left: 10, top: 50 }, pointer: {}, path: {}, states: { "normal": { type: "normal" }, "circulation": { type: "circulation" }, "meet": { type: "meet" } }, save: { onclick: function (data) { alert(data); } } }, props: {// 屬性編輯器 attr: { top: 30, right: 30 }, props: {} }, restore: '', activeRects: {// 當前激活狀態 rects: [], rectAttr: { stroke: '#ff0000', "stroke-width": 2 } }, historyRects: {// 歷史激活狀態 rects: [], pathAttr: { path: { stroke: '#00ff00' }, arrow: { stroke: '#00ff00', fill: "#00ff00" } } } }; myflow.util = { isLine: function (p1, p2, p3) {// 三個點是否在一條直線上 var s, p2y; if ((p1.x - p3.x) == 0) s = 1; else s = (p1.y - p3.y) / (p1.x - p3.x); p2y = (p2.x - p3.x) * s + p3.y; // $('body').append(p2.y+'-'+p2y+'='+(p2.y-p2y)+', '); if ((p2.y - p2y) < 10 && (p2.y - p2y) > -10) { p2.y = p2y; return true; } return false; }, center: function (p1, p2) {// 兩個點的中間點 return { x: (p1.x - p2.x) / 2 + p2.x, y: (p1.y - p2.y) / 2 + p2.y }; }, // nextId: (function () { // var uid = 0; // return function () { // return ++uid; // }; // })(), nextId:function(){ return new Date().getTime(); }, connPoint: function (rect, p) {// 計算矩形中心到p的連線與矩形的交叉點 var start = p, end = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }; // 計算正切角度 var tag = (end.y - start.y) / (end.x - start.x); tag = isNaN(tag) ? 0 : tag; var rectTag = rect.height / rect.width; // 計算箭頭位置 var xFlag = start.y < end.y ? -1 : 1, yFlag = start.x < end.x ? -1 : 1, arrowTop, arrowLeft; // 按角度判斷箭頭位置 if (Math.abs(tag) > rectTag && xFlag == -1) {// top邊 arrowTop = end.y - rect.height / 2; arrowLeft = end.x + xFlag * rect.height / 2 / tag; } else if (Math.abs(tag) > rectTag && xFlag == 1) {// bottom邊 arrowTop = end.y + rect.height / 2; arrowLeft = end.x + xFlag * rect.height / 2 / tag; } else if (Math.abs(tag) < rectTag && yFlag == -1) {// left邊 arrowTop = end.y + yFlag * rect.width / 2 * tag; arrowLeft = end.x - rect.width / 2; } else if (Math.abs(tag) < rectTag && yFlag == 1) {// right邊 arrowTop = end.y + rect.width / 2 * tag; arrowLeft = end.x + rect.width / 2; } return { x: arrowLeft, y: arrowTop }; }, arrow: function (p1, p2, r) {// 畫箭頭,p1 開始位置,p2 結束位置, r前頭的邊長 var atan = Math.atan2(p1.y - p2.y, p2.x - p1.x) * (180 / Math.PI); var centerX = p2.x - r * Math.cos(atan * (Math.PI / 180)); var centerY = p2.y + r * Math.sin(atan * (Math.PI / 180)); var x2 = centerX + r * Math.cos((atan + 120) * (Math.PI / 180)); var y2 = centerY - r * Math.sin((atan + 120) * (Math.PI / 180)); var x3 = centerX + r * Math.cos((atan + 240) * (Math.PI / 180)); var y3 = centerY - r * Math.sin((atan + 240) * (Math.PI / 180)); return [p2, { x: x2, y: y2 }, { x: x3, y: y3 }]; } } myflow.rect = function (o, r,id) { var _this = this, _uid = myflow.util.nextId(), _o = $.extend(true, {}, myflow.config.rect, o), _id =id || 'rect' + _uid, _r = r, // Raphael畫筆 _rect, _img, // 圖標 _name, // 狀態名稱 _text, // 顯示文本 _ox, _oy; // 拖動時,保存起點位置; //console.log(_o); _rect = _r.rect(_o.attr.x, _o.attr.y, _o.attr.width, _o.attr.height, _o.attr.r).hide().attr(_o.attr); _img = _r.image(myflow.config.basePath + _o.img.src, _o.attr.x + _o.img.width / 2, _o.attr.y + (_o.attr.height - _o.img.height) / 2, _o.img.width, _o.img.height).hide(); _name = _r.text( _o.attr.x + _o.img.width + (_o.attr.width - _o.img.width) / 2, _o.attr.y + myflow.config.lineHeight / 2, _o.name.text).hide() .attr(_o.name); _text = _r.text( _o.attr.x + _o.img.width + (_o.attr.width - _o.img.width) / 2, _o.attr.y + (_o.attr.height - myflow.config.lineHeight) / 2 + myflow.config.lineHeight, _o.text.text).hide() .attr(_o.text); // 文本 // 拖動處理---------------------------------------- _rect.drag(function (dx, dy) { dragMove(dx, dy); }, function () { dragStart() }, function () { dragUp(); }); _img.drag(function (dx, dy) { dragMove(dx, dy); }, function () { dragStart() }, function () { dragUp(); }); _name.drag(function (dx, dy) { dragMove(dx, dy); }, function () { dragStart() }, function () { dragUp(); }); _text.drag(function (dx, dy) { dragMove(dx, dy); }, function () { dragStart() }, function () { dragUp(); }); var dragMove = function (dx, dy) {// 拖動中 if (!myflow.config.editable) return; var x = (_ox + dx); // -((_ox+dx)%10); var y = (_oy + dy); // -((_oy+dy)%10); _bbox.x = x - _o.margin; _bbox.y = y - _o.margin; resize(); }; var dragStart = function () {// 開始拖動 _ox = _rect.attr("x"); _oy = _rect.attr("y"); _rect.attr({ opacity: 0.5 }); _img.attr({ opacity: 0.5 }); _text.attr({ opacity: 0.5 }); }; var dragUp = function () {// 拖動結束 _rect.attr({ opacity: 1 }); _img.attr({ opacity: 1 }); _text.attr({ opacity: 1 }); }; // 改變大小的邊框 var _bpath, _bdots = {}, _bw = 5, _bbox = { x: _o.attr.x - _o.margin, y: _o.attr.y - _o.margin, width: _o.attr.width + _o.margin * 2, height: _o.attr.height + _o.margin * 2 }; _bpath = _r.path('M0 0L1 1').hide(); _bdots['t'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 's-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 't'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 't'); }, function () { }); // 上 _bdots['lt'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 'nw-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'lt'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'lt'); }, function () { }); // 左上 _bdots['l'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 'w-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'l'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'l'); }, function () { }); // 左 _bdots['lb'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 'sw-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'lb'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'lb'); }, function () { }); // 左下 _bdots['b'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 's-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'b'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'b'); }, function () { }); // 下 _bdots['rb'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 'se-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'rb'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'rb'); }, function () { }); // 右下 _bdots['r'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 'w-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'r'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'r') }, function () { }); // 右 _bdots['rt'] = _r.rect(0, 0, _bw, _bw).attr({ fill: '#000', stroke: '#fff', cursor: 'ne-resize' }).hide().drag(function (dx, dy) { bdragMove(dx, dy, 'rt'); }, function () { bdragStart(this.attr('x') + _bw / 2, this.attr('y') + _bw / 2, 'rt') }, function () { }); // 右上 $([_bdots['t'].node, _bdots['lt'].node, _bdots['l'].node, _bdots['lb'].node, _bdots['b'].node, _bdots['rb'].node, _bdots['r'].node, _bdots['rt'].node]).click(function () { return false; }); var bdragMove = function (dx, dy, t) { if (!myflow.config.editable) return; var x = _bx + dx, y = _by + dy; switch (t) { case 't': _bbox.height += _bbox.y - y; _bbox.y = y; break; case 'lt': _bbox.width += _bbox.x - x; _bbox.height += _bbox.y - y; _bbox.x = x; _bbox.y = y; break; case 'l': _bbox.width += _bbox.x - x; _bbox.x = x; break; case 'lb': _bbox.height = y - _bbox.y; _bbox.width += _bbox.x - x; _bbox.x = x; break; case 'b': _bbox.height = y - _bbox.y; break; case 'rb': _bbox.height = y - _bbox.y; _bbox.width = x - _bbox.x; break; case 'r': _bbox.width = x - _bbox.x; break; case 'rt': _bbox.width = x - _bbox.x; _bbox.height += _bbox.y - y; _bbox.y = y; break; } resize(); // $('body').append(t); }; var bdragStart = function (ox, oy, t) { _bx = ox; _by = oy; }; // 初始化操做 _o = $.extend(true, _o, o); // 事件處理- _text.node, _name.node, _img.node------------------------------- $([_rect.node, _text.node, _name.node, _img.node]).bind("contextmenu", function (e) { if (_this.getId() == _id) { _textself = _text; myflow.config.tools.contextmenu(e, _this, _textself,"rect", function (txt) { if (_this.getId() == _id) { _textself.attr({ text: txt }); } }); } return false; }); $([_rect.node, _text.node, _name.node, _img.node]).bind("dblclick", function (e, src) { myflow.config.tools.dblclickRect(_this.getId(), _this.toJson()); }); $([_rect.node, _text.node, _name.node, _img.node]).bind('click', function () { if (!myflow.config.editable) return; showBox(); if (_this.getId() == _id) { _textself = _text; myflow.config.tools.clickRect(_this, _textself, function (txt) { if (_this.getId() == _id) { _textself.attr({ text: txt }); } }); } var mod = $(_r).data('mod'); switch (mod) { case 'pointer': $(_r).data('currNode', _this); break; case 'jpath': var pre= $(_r).data('currNode'); if (pre && pre.getId().substring(0, 4) == 'rect') { if(pre.getId() != _id){ $(_r).trigger('addjpath', [pre, _this]); } } $(_r).data('currNode', _this); break; case 'rejectpath'://駁回連線 var pre = $(_r).data('currNode'); if (pre && pre.getId() != _id && pre.getId().substring(0, 4) == 'rect') { $(_r).trigger('addpathfallback', [pre, _this]); } $(_r).data('currNode', _this); break; case 'lpath': var pre= $(_r).data('currNode'); if (pre && pre.getId().substring(0, 4) == 'rect') { if(pre.getId() != _id){ $(_r).trigger('addlpath', [pre, _this]); } } $(_r).data('currNode', _this); break; case 'cpath': var pre= $(_r).data('currNode'); if (pre && pre.getId().substring(0, 4) == 'rect') { if(pre.getId() != _id){ $(_r).trigger('addcpath', [pre, _this]); } } $(_r).data('currNode', _this); break; case 'path': var pre = $(_r).data('currNode'); if (pre && pre.getId().substring(0, 4) == 'rect') { if(pre.getId() != _id){ $(_r).trigger('addpath', [pre, _this]); } } $(_r).data('currNode', _this); break; } $(_r).trigger('click', _this); return false; }); var clickHandler = function (e, src) { if (!myflow.config.editable) return; if (myflow.config.moving.flag) { if(src.getId().substring(0, 4) == '0000'){ myflow.config.moving.isNewDot=true; } if(myflow.config.moving.preRect == src&&myflow.config.moving.temp.length>2){ myflow.config.moving.temp.pop().remove(); myflow.config.moving.temp.pop().remove(); myflow.config.moving.isNewDot=true; } } if (src.getId() == _id) { // $(_r).trigger('showprops', [_o.props, src]); } else { hideBox(); } }; $(_r).bind('click', clickHandler); //this.setText = function (src,text) { // if (src.getId() == _id) { // _text.attr({ // text: text // }); // } //} //var textchangeHandler = function (e, text, src) { // if (src.getId() == _id) { // _text.attr({ // text: text // }); // } //}; //$(_r).bind('textchange', textchangeHandler); //設備類型改變函數 // var equipmentTypeChangeHandler=function(e,v,src){ // debugger; // if(src.getType()=="task"){ // //console.log(_o); // console.log(src); // //_o.props.assignee["label"]="改!"; // //src.extend(true,); // } // } // $(_r).bind('equipmentTypeChange',equipmentTypeChangeHandler); // 私有函數----------------------- // 邊框路徑 function getBoxPathString() { return 'M' + _bbox.x + ' ' + _bbox.y + 'L' + _bbox.x + ' ' + (_bbox.y + _bbox.height) + 'L' + (_bbox.x + _bbox.width) + ' ' + (_bbox.y + _bbox.height) + 'L' + (_bbox.x + _bbox.width) + ' ' + _bbox.y + 'L' + _bbox.x + ' ' + _bbox.y; } // 顯示邊框 function showBox() { _bpath.show(); for (var k in _bdots) { _bdots[k].show(); } } // 隱藏 function hideBox() { _bpath.hide(); for (var k in _bdots) { _bdots[k].hide(); } } // 根據_bbox,更新位置信息 function resize() { var rx = _bbox.x + _o.margin, ry = _bbox.y + _o.margin, rw = _bbox.width - _o.margin * 2, rh = _bbox.height - _o.margin * 2; var rxattr = { x: rx, y: ry, width: rw, height: rh, }; if (_o.showType == "textcirculation") { //傳閱節點 rxattr.stroke='#0cba52'; } _rect.attr(rxattr); switch (_o.showType) { case 'image': _img.attr({ x: rx + (rw - _o.img.width) / 2, y: ry + (rh - _o.img.height) / 2 }).show(); break; case 'text': _rect.show(); _text.attr({ x: rx + rw / 2, y: ry + rh / 2 }).show(); // 文本 break; case 'textcirculation': _rect.show(); if (_o.IsCurActive) { //流程實例當前節點 _text.attr({ x: rx + rw / 2, y: ry + rh / 2, fill: "red" }).show();// 文本 } else { _text.attr({ x: rx + rw / 2, y: ry + rh / 2 }).show();// 文本 } break; case 'image&text': _rect.show(); _name.attr({ x: rx + _o.img.width + (rw - _o.img.width) / 2, y: ry + myflow.config.lineHeight / 2 }).show(); _text.attr({ x: rx + _o.img.width + (rw - _o.img.width) / 2, y: ry + (rh - myflow.config.lineHeight) / 2 + myflow.config.lineHeight }).show(); // 文本 _img.attr({ x: rx + _o.img.width / 2, y: ry + (rh - _o.img.height) / 2 }).show(); break; } _bdots['t'].attr({ x: _bbox.x + _bbox.width / 2 - _bw / 2, y: _bbox.y - _bw / 2 }); // 上 _bdots['lt'].attr({ x: _bbox.x - _bw / 2, y: _bbox.y - _bw / 2 }); // 左上 _bdots['l'].attr({ x: _bbox.x - _bw / 2, y: _bbox.y - _bw / 2 + _bbox.height / 2 }); // 左 _bdots['lb'].attr({ x: _bbox.x - _bw / 2, y: _bbox.y - _bw / 2 + _bbox.height }); // 左下 _bdots['b'].attr({ x: _bbox.x - _bw / 2 + _bbox.width / 2, y: _bbox.y - _bw / 2 + _bbox.height }); // 下 _bdots['rb'].attr({ x: _bbox.x - _bw / 2 + _bbox.width, y: _bbox.y - _bw / 2 + _bbox.height }); // 右下 _bdots['r'].attr({ x: _bbox.x - _bw / 2 + _bbox.width, y: _bbox.y - _bw / 2 + _bbox.height / 2 }); // 右 _bdots['rt'].attr({ x: _bbox.x - _bw / 2 + _bbox.width, y: _bbox.y - _bw / 2 }); // 右上 _bpath.attr({ path: getBoxPathString() }); $(_r).trigger('rectresize', _this); }; this.GetConfig = function () { return _config; } this.ChangePhaseType = function (showTypeTmp, typeTmp) { _o.showType = showTypeTmp;// "textcirculation"; _o.type = typeTmp;// "state"; } // 函數---------------- //取設備類型函數 //this.getEquipmentType = function () { // var equipmentType=null; // for(var k in _o.props){ // if(k=="equipmentType") // equipmentType = _o.props[k].value; // } // if(equipmentType!=null) // return equipmentType; //}; //取節點類型 this.getType=function(){ var type=null; type=_o.type; return type; } // 轉化json字串 this.toJson = function () { var data = "{type:'" + _o.type + "',ID:'" + (!_o.ID ? "" : _o.ID) + "',text:{text:'" + (!_text.node.textContent ? "" : _text.node.textContent) + "'}, attr:{ x:" + Math.round(_rect.attr('x')) + ", y:" + Math.round(_rect.attr('y')) + ", width:" + Math.round(_rect.attr('width')) + ", height:" + Math.round(_rect.attr('height')) + "}}"; //", props:{" //for (var k in _o.props) { // data += k + ":{value:'" // + _o.props[k].value + "'},"; //} //if (data.substring(data.length - 1, data.length) == ',') // data = data.substring(0, data.length - 1); //data += "}}"; return data; }; // 從數據中恢復圖 this.restore = function (data) { var obj = data; // if (typeof data === 'string') // obj = eval(data); //console.log(obj); _o = $.extend(true, _o, data); _text.attr({ text: obj.text.text }); resize(); }; this.getBBox = function () { return _bbox; }; this.getId = function () { return _id; }; this.remove = function () { _rect.remove(); _text.remove(); _name.remove(); _img.remove(); _bpath.remove(); for (var k in _bdots) { _bdots[k].remove(); } }; this.text = function () { return _text.attr('text'); }; this.attr = function (attr) { if (attr) _rect.attr(attr); }; resize(); // 初始化位置 }; myflow.path = function (o, r, from, to, guid, ec, dots, id) { var _this = this, _r = r, _o = $.extend(true, o, myflow.config.path), _path, _markpath, _arrow, _text,_textPos, _ox, _oy, _from = from, _to = to, _id = id || 'path' + myflow.util.nextId(), _dotList, _autoText = true; _o.lineID = guid; oec = (ec > 0 ? (parseInt(ec) == 1 ? 25 : parseInt(ec) * 9 + 22) : 0); if (o.text != null) { _textPos = o.text.textPos; } if (o.lineType != "path") { _o.attr.path.stroke = "#ff0000"; _o.attr.path.fill = "none"; _o.attr.arrow.stroke = "#ff0000"; _o.attr.arrow.fill = "#808080"; // _o = $.extend(_o, { attr: { path: { storke: "#ff0000", fill: "#808080" }, arrow: { storke: "#ff0000", fill: "#808080" } } }); } // _o.props.PathType = { value: "1" }; // 點 function dot(type, pos, left, right) { var _this = this, _t = type, _n, _lt = left, _rt = right, _ox, _oy, // 緩存移動前時位置 _pos = pos; // 緩存位置信息{x,y}, 注意:這是計算出中心點 switch (_t) { case 'from': _n = _r.rect(pos.x - _o.attr.fromDot.width / 2, pos.y - _o.attr.fromDot.height / 2, _o.attr.fromDot.width, _o.attr.fromDot.height) .attr(_o.attr.fromDot); break; case 'big': _n = _r.rect(pos.x - _o.attr.bigDot.width / 2, pos.y - _o.attr.bigDot.height / 2, _o.attr.bigDot.width, _o.attr.bigDot.height) .attr(_o.attr.bigDot); break; case 'small': _n = _r.rect(pos.x - _o.attr.smallDot.width / 2, pos.y - _o.attr.smallDot.height / 2, _o.attr.smallDot.width, _o.attr.smallDot.height) .attr(_o.attr.smallDot); break; case 'to': _n = _r.rect(pos.x - _o.attr.toDot.width / 2, pos.y - _o.attr.toDot.height / 2, _o.attr.toDot.width, _o.attr.toDot.height) .attr(_o.attr.toDot); break; } if (_n && (_t == 'big' || _t == 'small')) { _n.drag(function (dx, dy) { dragMove(dx, dy); }, function () { dragStart() }, function () { dragUp(); }); // 初始化拖動 var dragMove = function (dx, dy) {// 拖動中 var x = (_ox + dx), y = (_oy + dy); _this.moveTo(x, y); }; var dragStart = function () {// 開始拖動 if (_t == 'big') { _ox = _n.attr("x") + _o.attr.bigDot.width / 2; _oy = _n.attr("y") + _o.attr.bigDot.height / 2; } if (_t == 'small') { _ox = _n.attr("x") + _o.attr.smallDot.width / 2; _oy = _n.attr("y") + _o.attr.smallDot.height / 2; } console.log(_t); }; var dragUp = function () {// 拖動結束 }; } $(_n.node).click(function () { return false; }); this.type = function (t) { if (t) _t = t; else return _t; }; this.node = function (n) { if (n) _n = n; else return _n; }; this.left = function (l) { if (l) _lt = l; else return _lt; }; this.right = function (r) { if (r) _rt = r; else return _rt; }; this.remove = function () { _lt = null; _rt = null; _n.remove(); }; this.pos = function (pos) { if (pos) { _pos = pos; _n.attr({ x: _pos.x - _n.attr('width') / 2, y: _pos.y - _n.attr('height') / 2 }); return this; } else { return _pos } }; this.moveTo = function (x, y) { this.pos({ x: x, y: y }); switch (_t) { case 'from': if (_rt && _rt.right() && _rt.right().type() == 'to') { _rt.right().pos(myflow.util.connPoint( _to.getBBox(), _pos)); } if (_rt && _rt.right()) { _rt .pos(myflow.util.center(_pos, _rt.right() .pos())); } break; case 'big': if (_rt && _rt.right() && _rt.right().type() == 'to') { _rt.right().pos(myflow.util.connPoint( _to.getBBox(), _pos)); } if (_lt && _lt.left() && _lt.left().type() == 'from') { _lt.left().pos(myflow.util.connPoint(_from .getBBox(), _pos)); } if (_rt && _rt.right()) { _rt .pos(myflow.util.center(_pos, _rt.right() .pos())); } if (_lt && _lt.left()) { _lt.pos(myflow.util.center(_pos, _lt.left().pos())); } // 三個大點在一條線上,移除中間的小點 var pos = { x: _pos.x, y: _pos.y }; if (myflow.util.isLine(_lt.left().pos(), pos, _rt .right().pos())) { _t = 'small'; _n.attr(_o.attr.smallDot); this.pos(pos); var lt = _lt; _lt.left().right(_lt.right()); _lt = _lt.left(); lt.remove(); var rt = _rt; _rt.right().left(_rt.left()); _rt = _rt.right(); rt.remove(); // $('body').append('ok.'); } break; case 'small': // 移動小點時,轉變爲大點,增長倆個小點 if (_lt && _rt && !myflow.util.isLine(_lt.pos(), { x: _pos.x, y: _pos.y }, _rt.pos())) { _t = 'big'; _n.attr(_o.attr.bigDot); var lt = new dot('small', myflow.util.center(_lt .pos(), _pos), _lt, _lt .right()); _lt.right(lt); _lt = lt; var rt = new dot('small', myflow.util.center(_rt .pos(), _pos), _rt.left(), _rt); _rt.left(rt); _rt = rt; } break; case 'to': if (_lt && _lt.left() && _lt.left().type() == 'from') { _lt.left().pos(myflow.util.connPoint(_from .getBBox(), _pos)); } if (_lt && _lt.left()) { _lt.pos(myflow.util.center(_pos, _lt.left().pos())); } break; } if (!_o.path_p || _o.path_p == "") { refreshpath(); } }; } function dotList() { // if(!_from) throw '沒有from節點!'; var _fromDot, _toDot, _fromBB = _from.getBBox(), _toBB = _to .getBBox(), _fromPos, _toPos; _fromPos = myflow.util.connPoint(_fromBB, { x: _toBB.x + _toBB.width / 2, y: _toBB.y + _toBB.height / 2 }); _toPos = myflow.util.connPoint(_toBB, _fromPos); _fromDot = new dot('from', _fromPos, null, new dot('small', { x: (_fromPos.x + _toPos.x) / 2 + oec, y: (_fromPos.y + _toPos.y) / 2 })); _fromDot.right().left(_fromDot); _toDot = new dot('to', _toPos, _fromDot.right(),null); _fromDot.right().right(_toDot); // 轉換爲path格式的字串 this.toPathString = function () { if (!_fromDot) return ''; //alert(_o.path_p); if (o.path_p&&o.path_p != "") { var arrrrr = [o.path_p, o.path_arr]; o.path_p = ""; o.path_arr = ""; return arrrrr; } var d = _fromDot, p = 'M' + d.pos().x + ' ' + d.pos().y, arr = ''; // 線的路徑 while (d.right()) { d = d.right(); p += 'L' + d.pos().x + ' ' + d.pos().y; } // 箭頭路徑 var arrPos = myflow.util.arrow(d.left().pos(), d.pos(), _o.attr.arrow.radius); arr = 'M' + arrPos[0].x + ' ' + arrPos[0].y + 'L' + arrPos[1].x + ' ' + arrPos[1].y + 'L' + arrPos[2].x + ' ' + arrPos[2].y + 'z'; return [p, arr]; }; this.toJson = function () { var bigdot = "[", d = _fromDot; var fromdot = "[", smalldot = "[", todot = "["; while (d) { if (d.type() == 'from') { fromdot += "{x:" + Math.round(d.pos().x) + ",y:" + Math.round(d.pos().y) + "},"; } if (d.type() == 'small') { smalldot += "{x:" + Math.round(d.pos().x) + ",y:" + Math.round(d.pos().y) + "},"; } if (d.type() == 'to') { todot += "{x:" + Math.round(d.pos().x) + ",y:" + Math.round(d.pos().y) + "},"; } if (d.type() == 'big') bigdot += "{x:" + Math.round(d.pos().x) + ",y:" + Math.round(d.pos().y) + "},"; d = d.right(); } if (fromdot.substring(fromdot.length - 1, fromdot.length) == ',') fromdot = fromdot.substring(0, fromdot.length - 1); fromdot += "]"; if (smalldot.substring(smalldot.length - 1, smalldot.length) == ',') smalldot = smalldot.substring(0, smalldot.length - 1); smalldot += "]"; if (todot.substring(todot.length - 1, todot.length) == ',') todot = todot.substring(0, todot.length - 1); todot += "]"; if (bigdot.substring(bigdot.length - 1, bigdot.length) == ',') bigdot = bigdot.substring(0, bigdot.length - 1); bigdot += "]"; return bigdot; }; this.restore = function (data) { var obj = data, d = _fromDot.right(); if (obj.length) { for (var i = 0; i < obj.length; i++) { if (!d) { break; } d.moveTo(obj[i].x, obj[i].y); d.moveTo(obj[i].x, obj[i].y); d = d.right(); } } this.hide(); }; this.fromDot = function () { return _fromDot; }; this.toDot = function () { return _toDot; }; this.midDot = function () {// 返回中間點 var mid = _fromDot.right(), end = _fromDot.right().right(); while (end.right() && end.right().right()) { end = end.right().right(); mid = mid.right(); } return mid; }; this.show = function () { var d = _fromDot; while (d) { d.node().show(); d = d.right(); } }; this.hide = function () { var d = _fromDot; while (d) { d.node().hide(); d = d.right(); } }; this.remove = function () { var d = _fromDot; while (d) { if (d.right()) { d = d.right(); d.left().remove(); } else { d.remove(); d = null; } } }; } // 初始化操做 _o = $.extend(true, _o, o); _path = _r.path(_o.attr.path.path).attr(_o.attr.path); _markpath=_r.path(_o.attr.path.path) .attr({fill: "none",stroke: "white","stroke-miterlimit": 10,"stroke-width": 14,"-webkit-tap-highlight-color": "rgba(0, 0, 0, 0)","visibility":"hidden","pointer-events": "stroke","cursor": "crosshair"}); _arrow = _r.path(_o.attr.arrow.path).attr(_o.attr.arrow); _dotList = new dotList(); _dotList.hide(); _text = _r.text(0, 0, _o.text.text || _o.text.patten.replace('{from}', _from.text()).replace('{to}', _to.text())).attr(_o.attr.text); _text.drag(function (dx, dy) { if (!myflow.config.editable) return; _text.attr({ x: _ox + dx, y: _oy + dy }); }, function () { _ox = _text.attr('x'); _oy = _text.attr('y'); }, function () { var mid = _dotList.midDot().pos(); _textPos = { x: _text.attr('x') - mid.x, y: _text.attr('y') - mid.y }; }); refreshpath(); // 初始化路徑 // 事件處理--------------------這裏看不懂 $([_path.node, _text.node, _arrow.node, _markpath.node]).bind("contextmenu", function (e) { if (_this.getId() == _id) { _textself = _text; myflow.config.tools.contextmenu(e, _this, _textself,"path", function (txt) { if (_this.getId() == _id) { _textself.attr({ text: txt }); } }); } return false; }); $([_path.node, _markpath.node, _arrow.node, _text.node]).bind("dblclick", function () { myflow.config.tools.dblclickPath(_from, _to, _path); });//雙擊線事件 $([_path.node,_markpath.node, _arrow.node, _text.node]).bind('click', function () { if (!myflow.config.editable) return; $(_r).trigger('click', _this); $(_r).data('currNode', _this); myflow.config.tools.clickPath(_id); return false; }); // 處理點擊事件,線或矩形 var clickHandler = function (e, src) { if (!myflow.config.editable) return; if (src && src.getId() == _id) { _dotList.show(); // $(_r).trigger('showprops', [_o.props, _this]); } else { _dotList.hide(); } var mod = $(_r).data('mod'); switch (mod) { // case 'pointer': // console.log("點擊的是點") // break; // case 'path': // console.log("點擊的是線") // break; } }; $(_r).bind('click', clickHandler); // 刪除事件處理 var removerectHandler = function (e, src) { if (!myflow.config.editable) return; if (src && (src.getId() == _from.getId() || src.getId() == _to.getId())) { $(_r).trigger('removepath', _this); } }; $(_r).bind('removerect', removerectHandler); // 矩形移動時間處理 var rectresizeHandler = function (e, src) { if (!myflow.config.editable) return; if (_from && _from.getId() == src.getId()) { var rp; if (_dotList.fromDot().right().right().type() == 'to') { rp = { x: _to.getBBox().x + _to.getBBox().width / 2, y: _to.getBBox().y + _to.getBBox().height / 2 }; } else { rp = _dotList.fromDot().right().right().pos(); } var p = myflow.util.connPoint(_from.getBBox(), rp); _dotList.fromDot().moveTo(p.x, p.y); refreshpath(); } if (_to && _to.getId() == src.getId()) { var rp; if (_dotList.toDot().left().left().type() == 'from') { rp = { x: _from.getBBox().x + _from.getBBox().width / 2, y: _from.getBBox().y + _from.getBBox().height / 2 }; } else { rp = _dotList.toDot().left().left().pos(); } var p = myflow.util.connPoint(_to.getBBox(), rp); _dotList.toDot().moveTo(p.x, p.y); refreshpath(); } }; $(_r).bind('rectresize', rectresizeHandler); var textchangeHandler = function (e, v, src) { if (src.getId() == _id) {// 改變自身文本 _text.attr({ text: v }); _autoText = false; } //$('body').append('['+_autoText+','+_text.attr('text')+','+src.getId()+','+_to.getId()+']'); if (_autoText) { if (_to.getId() == src.getId()) { //$('body').append('change!!!'); _text.attr({ text: _o.text.patten.replace('{from}', _from.text()).replace('{to}', v) }); } else if (_from.getId() == src.getId()) { //$('body').append('change!!!'); _text.attr({ text: _o.text.patten.replace('{from}', v) .replace('{to}', _to.text()) }); } } }; $(_r).bind('textchange', textchangeHandler); // 函數------------------------------------------------- this.from = function () { return _from; }; this.getFrom=function(){ var from=null; from=_from; return from; } this.getTo=function(){ var to=null; to=_to; return to; } this.to = function () { return _to; }; this.getprops = function () { return _o.props; }; this.getlineType = function () { return _o.lineType; }; // 轉化json數據 this.toJson = function () { var _tPos = _dotList.toPathString(); var data = "{lineID:'" + (!_o.lineID ? "" : _o.lineID) + "',lineType:'" + _o.lineType + "',from:'" + _from.getId() + "',to:'" + _to.getId() + "', dots:" + _dotList.toJson() + ",path_p:'" + _tPos[0] + "',path_arr:'" + _tPos[1] + "',text:{text:'" + _text.attr('text') + "',textPos:{x:" + Math.round(_textPos.x) + ",y:" + Math.round(_textPos.y) + "}}}"; //, props:{"; //for (var k in _o.props) { // data += k + ":{value:'" // + _o.props[k].value + "'},"; //} //if (data.substring(data.length - 1, data.length) == ',') // data = data.substring(0, data.length - 1); //data += '}}'; return data; }; // 恢復 this.restore = function (data) { var obj = data; _o = $.extend(true, _o, data); if (_o.text.text != null) { //$('body').append('['+_text.attr('text')+','+_o.text.text+']'); if (_text.attr('text') != _o.text.text) { //$('body').append('['+_text.attr('text')+','+_o.text.text+']'); _text.attr({ text: _o.text.text }); _autoText = false; } } if (obj.dots != null) { _dotList.restore(obj.dots); } }; // 刪除 this.remove = function () { _dotList.remove(); _path.remove(); _markpath.remove(); _arrow.remove(); _text.remove(); try { $(_r).unbind('click', clickHandler); } catch (e) { } try { $(_r).unbind('removerect', removerectHandler); } catch (e) { } try { $(_r).unbind('rectresize', rectresizeHandler);; } catch (e) { } try { $(_r).unbind('textchange', textchangeHandler); } catch (e) { } }; // 刷新路徑 function refreshpath() { var p = _dotList.toPathString(), mid = _dotList.midDot().pos(); _path.attr({ path: p[0] }); _markpath.attr({ path:p[0] }); _arrow.attr({ path: p[1] }); _text.attr({ x: mid.x + _textPos.x, y: mid.y + _textPos.y }); // $('body').append('refresh.'); } this.getId = function () { return _id; }; this.text = function () { return _text.attr('text'); }; this.attr = function (attr) { if (attr && attr.path) _path.attr(attr.path); if (attr && attr.arrow) _arrow.attr(attr.arrow); // $('body').append('aaaaaa'); }; if(dots){ //_dotList.restore(dots); // rectresizeHandler(null,_to); // $("#path").click(); // $(_r).data('currNode', null); } return _this; }; //myflow.props = function (o, r) { // var _this = this, _pdiv = $('#myflow_props').hide().draggable({ // handle: '#myflow_props_handle' // }).resizable().css(myflow.config.props.attr).bind('click', // function () { // return false; // }), _tb = _pdiv.find('table'), _r = r, _src; // var showpropsHandler = function (e, props, src) { // if (_src && _src.getId() == src.getId()) {// 連續點擊不刷新 // return; // } // _src = src; // $(_tb).find('.editor').each(function () { // var e = $(this).data('editor'); // if (e) // e.destroy(); // }); // _tb.empty(); // // _pdiv.show(); // //for (var k in props) { // // _tb.append('<tr><th>' + props[k].label + '</th><td><div id="p' // // + k + '" class="editor"></div></td></tr>'); // // if (props[k].editor) // // props[k].editor().init(props, k, 'p' + k, src, _r); // // // $('body').append(props[i].editor+'a'); // //} // }; // this.restore = function (data) { // var obj = data; // // if (typeof data === 'string') // // obj = eval(data); // //console.log(obj); // _tb = $.extend(true, _tb, data); // }; // $(_r).bind('showprops', showpropsHandler); //}; // 屬性編輯器 myflow.editors = { textEditor: function () { var _props, _k, _div, _src, _r; this.init = function (props, k, div, src, r) { _props = props; _k = k; _div = div; _src = src; _r = r; $('<input style="width:100%;"/>').val(_src.text()).change( function () { props[_k].value = $(this).val(); $(_r).trigger('textchange', [$(this).val(), _src]); }).appendTo('#' + _div); // $('body').append('aaaa'); $('#' + _div).data('editor', this); }; this.destroy = function () { $('#' + _div + ' input').each(function () { _props[_k].value = $(this).val(); $(_r).trigger('textchange', [$(this).val(), _src]); }); // $('body').append('destroy.'); }; } }; // 初始化流程 myflow.init = function (c, o) { var _w = $(window).width(), _h = $(window).height(), _r = Raphael(c, _w * 1.5, _h * 1.5), _states = {}, _paths = {}; $.extend(true, myflow.config, o); /** * 刪除: 刪除狀態時,觸發removerect事件,鏈接在這個狀態上當路徑監聽到這個事件,觸發removepath刪除自身; * 刪除路徑時,觸發removepath事件 */ $(document).keydown(function (arg) { if (!myflow.config.editable) return; if (arg.keyCode == 46) { var c = $(_r).data('currNode'); if (c) { if (c.getId().substring(0, 4) == 'rect') { if (!myflow.config.tools.deleteRect(c.getId(), c.toJson()))//刪除成功繼續執行 { return false; } //添加到歷史記錄 myflow.config.historys.push({state:"removerect",object:c,data:getJson()}); $(_r).trigger('removerect', c); /*清除自定義軌跡*/ myflow.config.moving.temp.map(function(item,index){ item.remove(); }) myflow.config.moving={ flag:false, prepdot:{x:0,y:0}, dots:[], isNewDot:false, preRect:null, temp:[] }; myflow.config.tools.deleteRected(c.getId(), c.toJson()); } else if (c.getId().substring(0, 4) == 'path') { if (!myflow.config.tools.deletePath(c.getId())) { return false; } //添加到歷史記錄 myflow.config.historys.push({state:"removepath",object:c,data:getJson()}); $(_r).trigger('removepath', c); myflow.config.tools.deletePathed(c.getId()); } $(_r).removeData('currNode'); } } }); $(document).click(function () { $(_r).data('currNode', null); myflow.config.tempData={ paths:_paths, states:_states } //$(_r).trigger('click', { // getId: function () { // return '00000000'; // } //}); //$(_r).trigger('showprops', [myflow.config.props.props, { // getId: function () { // return '00000000'; // } //}]); }); // 刪除事件 var removeHandler = function (e, src) { if (!myflow.config.editable) return; if (src.getId().substring(0, 4) == 'rect') { _states[src.getId()] = null; src.remove(); delete _states[src.getId()]; } else if (src.getId().substring(0, 4) == 'path') { _paths[src.getId()] = null; src.remove(); delete _paths[src.getId()]; } }; $(_r).bind('removepath', removeHandler); $(_r).bind('removerect', removeHandler); // 添加節點 $(_r).bind('addrect', function (e, type, o) { var data = getJson(); if (myflow.config.tools.addRect && !myflow.config.tools.addRect(myflow.config.tools.states[type], o)) { return false; } var rect = new myflow.rect($.extend(true, { type:type}, myflow.config.tools.states[type], o), _r); if (myflow.config.tools.addRected) myflow.config.tools.addRected(rect.getId(), rect.toJson()); _states[rect.getId()] = rect; //添加到歷史記錄 myflow.config.historys.push({state:"addrect",object:rect,data:data}); }); function getNodeID(obj) { var json = obj.toJson(); var str = json.split(',')[1]; return str.substring(4, str.length - 1); } // 添加路徑 var addPathHandler = function (e, from, to,dots) { var data = getJson(); if (from.getType() == "start" && to.getType() == "end") {//結束節點不能退回 return false; } if (myflow.config.tools.addPath && !myflow.config.tools.addPath(_paths,from,to)) { return false; } var bExists = false; $.each(_paths, function (nIndex, nObj) { if ( (nObj.from().getId() == from.getId() && nObj.to().getId() == to.getId() && nObj.getlineType() == "path") || (nObj.from().getId() == to.getId() && nObj.to().getId() == from.getId() && nObj.getlineType() == "path") ) { bExists = true; return; } }); if (bExists) return; var path = new myflow.path({ lineType: "path" }, _r, from, to, null, null, dots, null); myflow.config.tools.addPathed(path.getId(),path.toJson()); _paths[path.getId()] = path; //添加到歷史記錄 myflow.config.historys.push({state:"addpath",object:path,data:data}); }; var addjpathHandler = function (e, from, to, dots) { var data=getJson(); var path = new myflow.jpath({}, _r, from, to,null,null,dots,null); myflow.config.tools.addPathed(path.getId(),path.toJson()); _paths[path.getId()] = path; }; var addlpathHandler = function (e, from, to,dots) { var data=getJson(); var path = new myflow.lpath({}, _r, from, to,null,null,dots,null); myflow.config.tools.addPathed(path.getId(), path.toJson()); _paths[path.getId()] = path; }; var addcpathHandler = function (e, from, to,dots) { var data=getJson(); var path = new myflow.cpath({}, _r, from, to,null,null,dots,null); myflow.config.tools.addPathed(path.getId(),path.toJson()); _paths[path.getId()] = path; }; // 添加路徑_駁回 var addRejectpathHandler = function (e, from, to, dots) { //看下這兩個節點間有沒有聯繫,若是有,則不容許再畫了 var bExists = false; if (from.getType() == "end") {//結束節點不能退回 return false; } // var path = new myflow.rejectpath({}, _r, from, to); if (myflow.config.tools.addPath && !myflow.config.tools.addPath(_paths, from, to)) { return false; } $.each(_paths, function (nIndex, nObj) { if ( (nObj.from().getId() == from.getId() && nObj.to().getId() == to.getId() && nObj.getlineType() == "rejectpath") || (nObj.from().getId() == to.getId() && nObj.to().getId() == from.getId() && nObj.getlineType() == "rejectpath") ) { bExists = true; return; } }); //console.log(bExists); if (bExists) return; var path = new myflow.path({ lineType: "rejectpath" }, _r, from, to, null, null, dots, null); myflow.config.tools.addPathed(path.getId(), path.toJson()); _paths[path.getId()] = path; // CPFlowGlobal_IsNeedSave = true; }; $(_r).bind('addpath', addPathHandler); $(_r).bind('addjpath', addjpathHandler); $(_r).bind('addlpath', addlpathHandler); $(_r).bind('addcpath', addcpathHandler); $(_r).bind('addpathfallback', addRejectpathHandler); var path,rect,circle; $("#myflow").mousemove(function (e) { var moving = myflow.config.moving; if(moving.flag){ var pre = $(_r).data('currNode'); if(path&&!moving.isNewDot){ path.remove();circle.remove(); }else{ moving.isNewDot=false; } var dot = moving.prepdot; if(pre&&pre.getBBox()){ dot = myflow.util.connPoint(pre.getBBox(), {x:e.pageX,y:e.pageY}); } var x = e.pageX-10, y = e.pageY-10; circle=_r.circle(x, y, 6).attr({fill: 'red',stroke: '#fff',cursor: 'move'}); path = _r.path('M' + dot.x + ' ' + dot.y + 'L' + x + ' ' + y + 'z') .attr({stroke: '#808080',fill: "none","stroke-width": 2,cursor: "pointer"}); moving.temp.push(circle); moving.temp.push(path); } }) $("#myflow").click(function(e){ if(myflow.config.moving.flag){ var dot={ x:e.pageX-10, y:e.pageY-10 }; myflow.config.moving.prepdot=dot; myflow.config.moving.dots.push(dot); } }) this.getData = function () { return eval("(" + getJson() + ")"); } this.checkData = function () { return saveCheck(); } // 模式 $(_r).data('mod', 'pointer'); if (myflow.config.editable) { // 工具欄 $("#myflow_tools").draggable({ handle: '#myflow_tools_handle' }).css(myflow.config.tools.attr); $("#activtiy-dynamic-container").draggable({ handle: '#activtiy-dynamic-container_handle' }); $('#myflow_tools .node').hover(function () { $(this).addClass('mover'); }, function () { $(this).removeClass('mover'); }); $('#myflow_tools .selectable').click(function (e) { $('.selected').removeClass('selected'); $(this).addClass('selected'); $(_r).data('mod', this.id); }); $('#myflow_tools .state').each(function () { $(this).draggable({ helper: 'clone' }); }); $(c).droppable({ accept: '.state', drop: function (e, ui) { var temp = ui.helper.context.innerHTML; var _self = e; var x = e.pageX - $(this).offset().left; var y = e.pageY - $(this).offset().top; var id = temp.substring(temp.indexOf(">") + 1, temp.length).replace(/^\s\s*/, '').replace(/\s\s*$/, ''); $(_r).trigger('addrect', [ui.helper.attr('type'), { attr: { x:x, y: y } }, id]); } }); //保存校驗事件,必定要有開始和結束節點,一個設備必定要同時具有from和to function saveCheck(){ // debugger; var flag=0; var eqList=[]; var fromList=[]; var toList=[]; var error=null; for (var i in _states) { if(_states[i].getType()=="start"||_states[i].getType()=="end"){ flag+=1; }else if(_states[i].getType()=="normal"){ eqList.push(_states[i].getId()); } } console.log(eqList); if(flag<2){ error="缺乏開始或結束節點"; return error; } for (var j in _paths){ fromList.push(_paths[j].from().getId()); toList.push(_paths[j].to().getId()); } console.log(fromList); console.log(toList); for (var k=0;k<eqList.length;k++){ if($.inArray(eqList[k],fromList)==-1||$.inArray(eqList[k],toList)==-1){ error="每一個任務都應有輸入和輸出"; return error; }; } return error; } function getJson() { var data = '{states:{'; for (var k in _states) { if (_states[k]) { data += _states[k].getId() + ':' + _states[k].toJson() + ','; } } if (data.substring(data.length - 1, data.length) == ',') data = data.substring(0, data.length - 1); data += '},paths:{'; for (var k in _paths) { if (_paths[k]) { data += _paths[k].getId() + ':' + _paths[k].toJson() + ','; } } if (data.substring(data.length - 1, data.length) == ',') data = data.substring(0, data.length - 1); data += '}}'; //,props:{props:{'; //for (var c in myflow.config.props.props) { // data += c + ":{value:'" + myflow.config.props.props[c].value + "'}," //} //if (data.substring(data.length - 1, data.length) == ",") { // data = data.substring(0, data.length - 1) //} //data += '}}}'; return data; } $('#myflow_save').click(function () {// 保存 error=saveCheck(); if(error!=null){ alert(error); }else{ myflow.config.tools.save(getJson()); alert("保存成功"); } //myflow.config.tools.save(getJson()); }); $('#myflow_publish').click(function () {// 發佈 myflow.config.tools.publish(getJson()) }); $('#myflow_revoke').click(function(){//撤銷 var temp=myflow.config.historys.pop(); if(temp){ switch(temp.state){ case "addpath": $(_r).trigger('removepath', temp.object); break; case "addrect": $(_r).trigger('removerect', temp.object); break; case "removepath": restore(eval("(" + temp.data + ")")); break; case "removerect": restore(eval("(" + temp.data + ")")); break; } }else{ alert("沒有東西能夠撤銷!"); } }); $("#myflow_redraw").click(function(){ //重繪 if(_states){ for(var k in _states){ _states[k].remove(); } } if(_paths){ for(var k in _paths){ _paths[k].remove(); } } _states={}; _paths={}; myflow.config.moving.temp.map(function(item,index){ item.remove(); }) myflow.config.moving={ flag:false, prepdot:{x:0,y:0}, dots:[], isNewDot:false, preRect:null, temp:[] }; }); $("#pointer").click(function(){ //重繪 myflow.config.moving.temp.map(function(item,index){ item.remove(); }) myflow.config.moving={ flag:false, prepdot:{x:0,y:0}, dots:[], isNewDot:false, preRect:null, temp:[] }; }) // 屬性框 // new myflow.props({}, _r); } // 恢復 if (o.restore) { restore(o.restore); } function restore(data){ var rmap = {}; if (data.states) { for (var k in data.states) { if(!_states[k]){ var rect = new myflow.rect($.extend(true,{},myflow.config.tools.states[data.states[k].type],data.states[k]), _r,k); rect.restore(data.states[k]); rmap[k] = rect; _states[rect.getId()] = rect; } } } if (data.paths) { for (var k in data.paths) { //if (data.paths[k].lineType == 'rejectpath') { // var from = rmap && rmap[data.paths[k].from] || _states[data.paths[k].from]; // var to = rmap && rmap[data.paths[k].to] || _states[data.paths[k].to]; // var p = new myflow.rejectpath($.extend(true, {}, myflow.config.tools.rejectpath, data.paths[k]), _r, from, to, null, null, data.paths[k].dots, k); // p.restore(data.paths[k]); // _paths[p.getId()] = p; //} //else { var from=rmap&&rmap[data.paths[k].from] || _states[data.paths[k].from]; var to = rmap && rmap[data.paths[k].to] || _states[data.paths[k].to]; var p = new myflow.path(data.paths[k], _r, from, to, null, null, data.paths[k].dots, k); p.restore(data.paths[k]); _paths[p.getId()] = p; // } } //for (var k in data.paths) { // if(!_paths[k]){ // if(data.paths[k].lineType=='path'){ // var from=rmap&&rmap[data.paths[k].from] || _states[data.paths[k].from]; // var to=rmap&&rmap[data.paths[k].to] || _states[data.paths[k].to]; // var p = new myflow.path($.extend(true, {},myflow.config.tools.path, data.paths[k]), _r, from,to,null,null,null,k); // p.restore(data.paths[k]); // _paths[p.getId()] = p; // } // else if(data.paths[k].lineType=='jpath'){ // var from=rmap&&rmap[data.paths[k].from] || _states[data.paths[k].from]; // var to=rmap&&rmap[data.paths[k].to] || _states[data.paths[k].to]; // var p = new myflow.jpath($.extend(true, {},myflow.config.tools.path, data.paths[k]), _r, from,to,null,null,null,k); // p.restore(data.paths[k]); // _paths[p.getId()] = p; // } // else if(data.paths[k].lineType=='lpath'){ // var from=rmap&&rmap[data.paths[k].from] || _states[data.paths[k].from]; // var to=rmap&&rmap[data.paths[k].to] || _states[data.paths[k].to]; // var p = new myflow.lpath($.extend(true, {},myflow.config.tools.path, data.paths[k]), _r, from,to,null,null,null,k); // p.restore(data.paths[k]); // _paths[p.getId()] = p; // } // else if(data.paths[k].lineType=='cpath'){ // var from=rmap&&rmap[data.paths[k].from] || _states[data.paths[k].from]; // var to=rmap&&rmap[data.paths[k].to] || _states[data.paths[k].to]; // var p = new myflow.cpath($.extend(true, {},myflow.config.tools.path, data.paths[k]), _r, from,to,null,null,null,k); // p.restore(data.paths[k]); // _paths[p.getId()] = p; // } // } //} } // if(data.props){ // for(var s in data.props){ // var n=new myflow.props($.extend(true,{},myflow.config.tools.props[data.props[s].type],data.props[s]),_r,s) // n.restore(data.props[s]); // } // } } // 歷史狀態 var hr = myflow.config.historyRects, ar = myflow.config.activeRects; if (hr.rects.length || ar.rects.length) { var pmap = {}, rmap = {}; for (var pid in _paths) {// 先組織MAP if (!rmap[_paths[pid].from().text()]) { rmap[_paths[pid].from().text()] = { rect: _paths[pid].from(), paths: {} }; } rmap[_paths[pid].from().text()].paths[_paths[pid].text()] = _paths[pid]; if (!rmap[_paths[pid].to().text()]) { rmap[_paths[pid].to().text()] = { rect: _paths[pid].to(), paths: {} }; } } for (var i = 0; i < hr.rects.length; i++) { if (rmap[hr.rects[i].name]) { rmap[hr.rects[i].name].rect.attr(hr.rectAttr); } for (var j = 0; j < hr.rects[i].paths.length; j++) { if (rmap[hr.rects[i].name].paths[hr.rects[i].paths[j]]) { rmap[hr.rects[i].name].paths[hr.rects[i].paths[j]] .attr(hr.pathAttr); } } } for (var i = 0; i < ar.rects.length; i++) { if (rmap[ar.rects[i].name]) { rmap[ar.rects[i].name].rect.attr(ar.rectAttr); } for (var j = 0; j < ar.rects[i].paths.length; j++) { if (rmap[ar.rects[i].name].paths[ar.rects[i].paths[j]]) { rmap[ar.rects[i].name].paths[ar.rects[i].paths[j]] .attr(ar.pathAttr); } } } } } //獲取from的type // 添加jquery方法 $.fn.myflow = function (o) { return this.each(function () { myflow.init(this, o); }); }; $.myflow = myflow; })(jQuery); var myFlowMenu = { renderMenu: function (e, items) { var _id = Notify.Guid() + "_myflowcontextmenu"; if ($(".myflowcontextmenu").hasClass("myflowcontextmenu")) { $(".myflowcontextmenu").remove(); } var $menu = $('<div id="' + _id + '" class="dropdown bootstrapMenu myflowcontextmenu" style="z-index:10000;position:absolute;" />'); var $ul = $('<ul class="dropdown-menu" style="position:static;display:block;font-size:0.9em;" />'); $menu.css({ left: e.pageX, top: e.pageY }); $("body").on('click', function (evt) { var destElement = evt.toElement || evt.relatedTarget; $menu.hide(); $menu.remove(); }); var itemsClick = {}; $.each(items, function (index, item) { itemsClick[item.action] = item.onClick; if (item.icon && item.icon != "") { $ul.append( '<li role="presentation" data-action="' + item.action + '">' + '<a href="#" role="menuitem">' + '<i class="fa ' + (item.icon || '') + '"></i> ' + '<span class="actionName">' + item.text + '</span>' + '</a>' + '</li>' ); } else { $ul.append( '<li role="presentation" data-action="' + item.action + '">' + '<a href="#" role="menuitem"><span class="actionName">' + item.text + '</span></a>' + '</li>' ); } }); $("body").append($menu); $menu.show(); $ul.find("li").on("click", function (e) { if (itemsClick[$(this).attr("data-action")]) { itemsClick[$(this).attr("data-action")](e); } }); $menu.on("contextmenu", function () { return false; }); return $menu.append($ul); } }
js初始化 this.Workflow = $(this.workFlowId).myflow( { allowStateMutiLine: true, basePath: "", restore: result, editable: true,//把默認修改屬性的功能給關閉了 tools: { contextmenu: function (e, $this, $text,type, func) { var items = [{ text: "備註", icon: "fa fa-user", action: "attr1", onClick: function (result) { $("#flow-text-remark-modal").find("#flow-text-remark").val($text.node.textContent); $("#flow-text-remark-modal").modal("show"); $("#flow-text-remark-modal").find(".btn-primary").click(function () { var text = $("#flow-text-remark-modal").find("#flow-text-remark").val(); if (!text || text == "") { text = ""; } func(text); $("#flow-text-remark-modal").modal("hide"); myWorkflow.saveWorkFlow(); }); } }]; if (type == "rect") { items.push({ text: "屬性", icon: "fa fa-user", action: "attr", onClick: function (result) { } }); } myFlowMenu.renderMenu(e, items); }, save: function (data) { }, publish: function (data) { console.log("發佈", eval("(" + data + ")")); }, //添加路徑時觸發 返回true or false addPath: function (paths, from, to) { console.log("添加路徑", paths, from, to); return true; }, //添加路徑成功時觸發 addPathed: function (id, data) { console.log("添加路徑成功", id, data); myWorkflow.saveWorkFlow(); //console.log(eval("(" + data + ")").from); }, ///添加節點 addRect: function (state, o) { if (state.type == "start" || state.type == "end") { return false; } console.log("添加節點", state + o); return true; }, addRected: function (rect, id, data) { myWorkflow.saveWorkFlow(); console.log("添加節點成功", id, eval("(" + data + ")")); return true; }, clickPath: function (id) { console.log("點擊線",id) }, dblclickPath: function (from,to,path) { }, clickRect: function ($this, $text, func) { myWorkflow.ActivtiyReset(); $(myWorkflow.activtiyContainer).css({ "display": "block" }); $(myWorkflow.activtiyContainer).find("#ActivityName").val($text.node.textContent); $(myWorkflow.activtiyContainer).find("#ActivityName").trigger("change", [$this, $text, func]); // alert($(myWorkflow.activtiyContainer).find("#ActivityName").val()); myWorkflow.setActivtiy($this.getId(),$this); // console.log("單擊節點,"+data); }, dblclickRect: function (id, data) { console.log("雙擊節點", id, eval("(" + data + ")")); }, //刪除線前 deletePath: function (id) { console.log("刪除線前", id); return true; }, //刪除線成功後 deletePathed: function (id) { console.log("刪除線", id); myWorkflow.saveWorkFlow(); }, deleteRect: function (id, data) { var rect=eval("(" + data + ")"); //console.log("刪除節點", id, rect); if (rect.type == "start" || rect.type == "end") { console.log("開始結束節點不能刪除"); return false; } return true; }, deleteRected:function(id,data) { myWorkflow.saveWorkFlow(); }, equipmentTypeChange: function (event, value, data) { console.log(event); } , revoke: function (id) { } } });