diff --git a/OpenAuth.Mvc/OpenAuth.Mvc.csproj b/OpenAuth.Mvc/OpenAuth.Mvc.csproj index d191cc15..67f755e2 100644 --- a/OpenAuth.Mvc/OpenAuth.Mvc.csproj +++ b/OpenAuth.Mvc/OpenAuth.Mvc.csproj @@ -179,30 +179,20 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -617,6 +607,9 @@ + + + diff --git a/OpenAuth.Mvc/Views/FlowSchemes/Design.cshtml b/OpenAuth.Mvc/Views/FlowSchemes/Design.cshtml index b857221c..3512385a 100644 --- a/OpenAuth.Mvc/Views/FlowSchemes/Design.cshtml +++ b/OpenAuth.Mvc/Views/FlowSchemes/Design.cshtml @@ -2,7 +2,7 @@ @section header { - + }
diff --git a/OpenAuth.Mvc/js/flow-ui/flow.css b/OpenAuth.Mvc/js/flow-ui/flow.css deleted file mode 100644 index ba831015..00000000 --- a/OpenAuth.Mvc/js/flow-ui/flow.css +++ /dev/null @@ -1,77 +0,0 @@ -v\:group,v\:rect,v\:imagedata,v\:oval,v\:line,v\:polyline,v\:stroke,v\:textbox{display:inline-block;background:transparent} -.GooFlow{margin:0px;background:#F7F7F7;border-right:#ccc 0px solid;font: 12px Arial, Helvetica, sans-serif;-moz-user-select:none;-webkit-user-select:none;float:left;} -.GooFlow_head{clear:both;height:22px;padding:1px;display:none;} -.GooFlow_tool{float:left;margin:0px 1px;overflow:hidden;clear:left;border-radius:3px;margin-top:2px;margin-left:3px;} -.GooFlow_tool_div{overflow:hidden;border-radius:2px;width:54px;} -.GooFlow_tool span{height:0px;overflow:hidden;border-bottom:#ccc 1px solid;border-top:#FFFFFF 1px solid;margin:1px;clear:both;display:block;} -.GooFlow_tool_btn{display:block;border:0px;height:50px;width:50px;cursor:default;margin:1px;margin-top:2px;margin-bottom:2px; outline :none;border:#F7F7F7 1px solid;border-radius:8px} -.GooFlow_tool_btn b{cursor:pointer;} -.GooFlow_tool_btn:hover{border:#8E9DA6 1px solid;opacity: 0.8;} -.GooFlow_tool_btndown{display:block;border:0px;height:50px;width:50px;cursor:default;margin:1px;margin-top:2px;margin-bottom:2px; outline :none;border:#ccc 1px solid;background:#fff;border-radius:8px} -.GooFlow_tool_btndown b{cursor:pointer;} -.GooFlow_work{float:right;margin:0px;border-left:#ccc 1px solid;position:relative;overflow:scroll} -.GooFlow_work .GooFlow_work_inner{background-image:url(img/wallbg.png) ;position:relative;overflow:hidden} -.GooFlow_work .GooFlow_work_group{cursor:default;position:absolute;overflow:hidden;top:0px;left:0px} -.GooFlow_area{position:absolute;} -.GooFlow_area .lock{cursor:default;} -.GooFlow_area .bg{cursor:move;filter:Alpha(Opacity=30);-moz-opacity:0.3;opacity: 0.3;border-radius:10px;} -.GooFlow_work .lock .bg{cursor:default;} -.GooFlow_area label{cursor:text;top:1px;left:1px;position:absolute;display:block;font-size:12px;text-indent:18px;height:18px;line-height:18px} -.GooFlow_work .lock label{cursor:default;} -.GooFlow_area b{display:block;height:18px;width:18px;top:0px;left:0px;position:absolute;cursor:pointer} -.GooFlow_work .area_red .bg{border:1px solid red;background-color:#EB4F2D} -.GooFlow_work .area_red label{color:red;background:url(img/gooflow_bullet.png) no-repeat 1px 1px} -.GooFlow_work .area_yellow .bg{border:1px solid #CD925A;background-color:#F5B93D} -.GooFlow_work .area_yellow label{color:#FFBA1D;background:url(img/gooflow_bullet.png) no-repeat 1px -16px} -.GooFlow_work .area_blue .bg{border:1px solid #347BB1;background-color:#43A4EE} -.GooFlow_work .area_blue label{color:#347BB1;background:url(img/gooflow_bullet.png) no-repeat 1px -33px} -.GooFlow_work .area_green .bg{border:1px solid green;background-color:#7FBA2E} -.GooFlow_work .area_green label{color:green;background:url(img/gooflow_bullet.png) no-repeat 1px -50px} -.GooFlow_work svg{display:block;position:absolute} -.GooFlow_work v\:group{position:relative;display:block} -.GooFlow_work v\:group v\:line{overflow:visible} -.GooFlow_work v\:group v\:polyline{overflow:visible} -.GooFlow_work v\:group div{cursor:text;position:absolute;overflow:visible;display:inline;float:left;white-space: nowrap} -.GooFlow_work .draw{color:#ff3300} - -.GooFlow_item{ - position:absolute;background:#A1DCEB;border:#A1DCEB solid 1px; - border-radius:3px;background-color:#C1DCFC;box-shadow:1px 1px 2px rgba(99,99,99,2); -} -.GooFlow table{padding:1px;border-radius:2px} -.GooFlow td{ vertical-align:middle;text-align:center;padding:0px;cursor:default;word-wrap:break-word;word-break:break-all} -.GooFlow .ico{width:18px;cursor:move} -.GooFlow i{display:block;width:18px;height:18px;overflow:hidden} - -.GooFlow b{display:block;width:48px;height:48px;overflow:hidden;} -.GooFlow .item_startround{background:#5CCB41;width:52px;height:52px;border:#5e8800 solid 1px;overflow:visible} -.GooFlow .item_startround table{border:0px;padding:2px;width:50px;height:50px;} -.GooFlow .item_startround .span{font-weight: bold;color:#fff; display:block;text-align:center;position:absolute;top:18px;left:-14px;width:80px;overflow:visible;text-align:center;padding:0px;cursor:default;word-wrap: break-word;word-break:break-all} -.GooFlow .item_endround{background:#DE2922;width:52px;height:52px;border:#BE0E0E solid 1px;overflow:visible} -.GooFlow .item_endround table{border:0px;padding:2px;width:50px;height:50px;} -.GooFlow .item_endround .span{font-weight: bold;color:#fff; display:block;text-align:center;position:absolute;top:18px;left:-15px;width:80px;overflow:visible;text-align:center;padding:0px;cursor:default;word-wrap: break-word;word-break:break-all} -.GooFlow .gentlenode{background:#DC5E2B;color:#FFFFFF;} -.GooFlow div .rs_right{display:none;overflow:hidden;position:absolute;right:-1px;top:-1px;height:100%;width:6px;cursor:w-resize} -.GooFlow div .rs_bottom{display:none;overflow:hidden;position:absolute;left:-1px;bottom:-1px;width:100%;height:6px;cursor:n-resize} -.GooFlow div .rs_rb{position:absolute;right:-1px;bottom:-1px;width:9px;height:9px;overflow:hidden;cursor:nw-resize;background:url(img/gooflow_tip.png) no-repeat 0px -8px;} -.GooFlow div .rs_close{z-index:10;position:absolute;right:-12px;top:-12px;width:24px;height:24px;overflow:hidden;cursor:pointer;background:url(img/ui_close.png) no-repeat 0px 0px} -.GooFlow .rs_ghost{position:absolute;display:none;overflow:hidden;border:#8EA4C1 1px dashed;background:#F2F2F2;filter:Alpha(Opacity=60);-moz-opacity:0.6;opacity: 0.6;z-index:10;border-radius:10px;} -.GooFlow .item_focus{border:#4A5B79 1px solid;box-shadow:2px 2px 19px #444;opacity:0.9;cursor:pointer;} -.GooFlow .item_mark{border:#ff3300 1px solid} -.GooFlow .item_mark td{cursor:crosshair} -.GooFlow textarea{position:absolute;border:#4A5B79 1px solid;display:none;font-size:12px;overflow-y:visible;width:100px;z-index:10001} -.GooFlow .GooFlow_line_oper{height:15px;background-color:#D8E8FC;border:#ccc 1px solid;position:absolute;z-index:10000;} -.GooFlow .GooFlow_line_move{filter:Alpha(Opacity=50);-moz-opacity:0.5;opacity:0.5;overflow:hidden;position:absolute;z-index:9999;background:url(0) no-repeat} -.GooFlow .GooFlow_line_oper b{display:inline-block;width:15px;height:15px;margin-left:2px;cursor:pointer} -.GooFlow .b_l1{background:url(img/GooFlow_line_oper.png) no-repeat 1px 1px} -.GooFlow .b_l2{background:url(img/GooFlow_line_oper.png) no-repeat 1px -14px} -.GooFlow .b_l3{background:url(img/GooFlow_line_oper.png) no-repeat 1px -29px} -.GooFlow .b_x{background:url(img/GooFlow_line_oper.png) no-repeat 1px -44px;margin-left:10px} -.GooFlow .ico_cursor{background:url(img/10.png) no-repeat 0px 0px} -.GooFlow .ico_direct{background:url(img/9.png) no-repeat 0px 0px} -.GooFlow .ico_startround{background:url(img/2.png) no-repeat 0px 0px} -.GooFlow .ico_endround{background:url(img/7.png) no-repeat 0px 0px} -.GooFlow .ico_stepnode{background:url(img/4.png) no-repeat 0px 0px} -.GooFlow .ico_shuntnode{background:url(img/5.png) no-repeat 0px 0px} -.GooFlow .ico_confluencenode{background:url(img/3.png) no-repeat 0px 0px} -.GooFlow .ico_group{background:url(img/11.png) no-repeat 0px 0px} \ No newline at end of file diff --git a/OpenAuth.Mvc/js/flow-ui/gooflow.js b/OpenAuth.Mvc/js/flow-ui/gooflow.js deleted file mode 100644 index d8944dc9..00000000 --- a/OpenAuth.Mvc/js/flow-ui/gooflow.js +++ /dev/null @@ -1,2279 +0,0 @@ -layui.define("jquery", - function(exports) { - var jQuery = layui.jquery, - $ = layui.jquery; - - //定义一个区域图类: - function GooFlow(bgDiv, property) { - if (navigator.userAgent.indexOf("MSIE 8.0") > 0 || - navigator.userAgent.indexOf("MSIE 7.0") > 0 || - navigator.userAgent.indexOf("MSIE 6.0") > 0) - GooFlow.prototype.useSVG = ""; - else GooFlow.prototype.useSVG = "1"; - //初始化区域图的对象 - this.$id = bgDiv.attr("id"); - this.$bgDiv = bgDiv; //最父框架的DIV - this.$bgDiv.addClass("GooFlow"); - var width = (property.width || 800) - 2; - var height = (property.height || 500) - 2; - this.$bgDiv.css({ width: width + "px", height: height + "px" }); - this.$tool = null; //左侧工具栏对象 - this.$head = null; //顶部标签及工具栏按钮 - this.$title = "newFlow_1"; //流程图的名称 - this.$nodeRemark = {}; //每一种结点或按钮的说明文字,JSON格式,key为类名,value为用户自定义文字说明 - this.$nowType = "cursor"; //当前要绘制的对象类型 - this.$lineData = {}; - this.$lineCount = 0; - this.$nodeData = {}; - this.$nodeCount = 0; - this.$areaData = {}; - this.$areaCount = 0; - this.$lineDom = {}; - this.$nodeDom = {}; - this.$areaDom = {}; - this.$max = property.initNum || 1; //计算默认ID值的起始SEQUENCE - this.$focus = ""; //当前被选定的结点/转换线ID,如果没选中或者工作区被清空,则为"" - this.$cursor = "default"; //鼠标指针在工作区内的样式 - this.$editable = false; //工作区是否可编辑 - this.$deletedItem = {}; //在流程图的编辑操作中被删除掉的元素ID集合,元素ID为KEY,元素类型(node,line.area)为VALUE - var headHeight = 0; - var tmp = ""; - if (property.haveHead) { - tmp = "
"; - for (var x = 0; x < property.headBtns.length; ++x) { - tmp += "" - } - tmp += "
"; - this.$head = $(tmp); - this.$bgDiv.append(this.$head); - headHeight = 24; - //以下是当工具栏按钮被点击时触发的事件自定义(虚函数),格式为function(),因为可直接用THIS操作对象本身,不用传参;用户可自行重定义: - this.onBtnNewClick = null; //新建流程图按钮被点中 - this.onBtnOpenClick = null; //打开流程图按钮定义 - this.onBtnSaveClick = null; //保存流程图按钮定义 - this.onFreshClick = null; //重载流程图按钮定义 - if (property.headBtns) - this.$head.on("click", - { inthis: this }, - function(e) { - if (!e) e = window.event; - var tar = e.target; - if (tar.tagName == "DIV" || tar.tagName == "SPAN") return; - else if (tar.tagName == "a") tar = tar.childNode[0]; - var This = e.data.inthis; - //定义顶部操作栏按钮的事件 - switch ($(tar).attr("class")) { - case "ico_new": - if (This.onBtnNewClick != null) This.onBtnNewClick(); - break; - case "ico_open": - if (This.onBtnOpenClick != null) This.onBtnOpenClick(); - break; - case "ico_save": - if (This.onBtnSaveClick != null) This.onBtnSaveClick(); - break; - case "ico_undo": - This.undo(); - break; - case "ico_redo": - This.redo(); - break; - case "ico_reload": - if (This.onFreshClick != null) This.onFreshClick(); - break; - } - }); - } - var toolWidth = 0; - if (property.haveTool) { - this.$bgDiv.append("
"); - this.$tool = this.$bgDiv.find(".GooFlow_tool div"); - //未加代码:加入绘图工具按钮 - this.$tool.append(""); - if (property.toolBtns && property.toolBtns.length > 0) { - tmp = ""; - for (var i = 0; i < property.toolBtns.length; ++i) { - tmp += ""; //加入自定义按钮 - } - this.$tool.append(tmp); - } - //加入区域划分框工具开关按钮 - if (property.haveGroup) - this.$tool.append(""); - toolWidth = 31; - this.$nowType = "cursor"; - //绑定各个按钮的点击事件 - this.$tool.on("click", - { inthis: this }, - function(e) { - if (!e) e = window.event; - var tar; - switch (e.target.tagName) { - case "SPAN": - return false; - case "DIV": - return false; - case "B": - tar = e.target.parentNode; - break; - case "A": - tar = e.target; - }; - var type = $(tar).attr("type"); - e.data.inthis.switchToolBtn(type); - return false; - }); - this.$editable = true; //只有具有工具栏时可编辑 - } - width = width - toolWidth - 8; - height = height; - this.$bgDiv.append("
"); - this.$workArea = $("
") - .attr({ - "unselectable": "on", - "onselectstart": 'return false', - "onselect": 'document.selection.empty()' - }); - this.$bgDiv.children(".GooFlow_work").append(this.$workArea); - this.$draw = null; //画矢量线条的容器 - this.initDraw("draw_" + this.$id, width, height); - this.$group = null; - if (property.haveGroup) - this.initGroup(width, height); - if (this.$editable) { - this.$workArea.on("click", - { inthis: this }, - function(e) { - if (!e) e = window.event; - if (!e.data.inthis.$editable) return; - var type = e.data.inthis.$nowType; - if (type == "cursor") { - var t = $(e.target); - var n = t.prop("tagName"); - if (n == "svg" || - (n == "DIV" && t.prop("class").indexOf("GooFlow_work") > -1) || - n == "LABEL") e.data.inthis.blurItem(); - return; - } else if (type == "direct" || type == "group") return; - var X, Y; - var ev = mousePosition(e), t = getElCoordinate(this); - X = ev.x - t.left + this.parentNode.scrollLeft - 1; - Y = ev.y - t.top + this.parentNode.scrollTop - 1; - - var name = "新建节点" + e.data.inthis.$max; - var type = e.data.inthis.$nowType; - if (type == 'startround') { - name = "开始"; - } - if (type == 'endround') { - name = "结束"; - } - var executeadd = true; - var _nodeData = e.data.inthis.$nodeData; - $.each(_nodeData, - function(i) { - if (_nodeData[i].name == name) { - alert(name + '节点不能重复'); - executeadd = false; - return false; - } - }) - if (executeadd) { - e.data.inthis.addNode(e.data.inthis.$id + "_node_" + e.data.inthis.$max, - { name: name, left: X, top: Y, type: e.data.inthis.$nowType, css: '', img: '', }); - e.data.inthis.$max++; - } - }); - //划线时用的绑定 - this.$workArea.mousemove({ inthis: this }, - function(e) { - if (e.data.inthis.$nowType != "direct") return; - var lineStart = $(this).data("lineStart"); - if (!lineStart) return; - var ev = mousePosition(e), t = getElCoordinate(this); - var X, Y; - X = ev.x - t.left + this.parentNode.scrollLeft; - Y = ev.y - t.top + this.parentNode.scrollTop; - var line = document.getElementById("GooFlow_tmp_line"); - if (GooFlow.prototype.useSVG != "") { - line.childNodes[0].setAttribute("d", - "M " + lineStart.x + " " + lineStart.y + " L " + X + " " + Y); - line.childNodes[1].setAttribute("d", - "M " + lineStart.x + " " + lineStart.y + " L " + X + " " + Y); - if (line.childNodes[1].getAttribute("marker-end") == "url(\"#arrow2\")") - line.childNodes[1].setAttribute("marker-end", "url(#arrow3)"); - else line.childNodes[1].setAttribute("marker-end", "url(#arrow2)"); - } else line.points.value = lineStart.x + "," + lineStart.y + " " + X + "," + Y; - }); - this.$workArea.mouseup({ inthis: this }, - function(e) { - if (e.data.inthis.$nowType != "direct") return; - $(this).css("cursor", "auto").removeData("lineStart"); - var tmp = document.getElementById("GooFlow_tmp_line"); - if (tmp) e.data.inthis.$draw.removeChild(tmp); - }); - //为了结点而增加的一些集体delegate绑定 - this.initWorkForNode(); - //对结点进行移动或者RESIZE时用来显示的遮罩层 - this.$ghost = $("
").attr({ - "unselectable": "on", - "onselectstart": 'return false', - "onselect": 'document.selection.empty()' - }); - this.$bgDiv.append(this.$ghost); - this.$textArea = $(""); - this.$bgDiv.append(this.$textArea); - this.$lineMove = $(""); //操作折线时的移动框 - this.$workArea.append(this.$lineMove); - this.$lineMove.on("mousedown", - { inthis: this }, - function(e) { - if (e.button == 2) return false; - var lm = $(this); - lm.css({ "background-color": "#333" }); - var This = e.data.inthis; - var ev = mousePosition(e), t = getElCoordinate(This.$workArea[0]); - var X, Y; - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop; - var p = This.$lineMove.position(); - var vX = X - p.left, vY = Y - p.top; - var isMove = false; - document.onmousemove = function(e) { - if (!e) e = window.event; - var ev = mousePosition(e); - var ps = This.$lineMove.position(); - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop; - if (This.$lineMove.data("type") == "lr") { - X = X - vX; - if (X < 0) X = 0; - else if (X > This.$workArea.width()) - X = This.$workArea.width(); - This.$lineMove.css({ left: X + "px" }); - } else if (This.$lineMove.data("type") == "tb") { - Y = Y - vY; - if (Y < 0) Y = 0; - else if (Y > This.$workArea.height()) - Y = This.$workArea.height(); - This.$lineMove.css({ top: Y + "px" }); - } - isMove = true; - } - document.onmouseup = function(e) { - if (isMove) { - var p = This.$lineMove.position(); - if (This.$lineMove.data("type") == "lr") - This.setLineM(This.$lineMove.data("tid"), p.left + 3); - else if (This.$lineMove.data("type") == "tb") - This.setLineM(This.$lineMove.data("tid"), p.top + 3); - } - This.$lineMove.css({ "background-color": "transparent" }); - if (This.$focus == This.$lineMove.data("tid")) { - This.focusItem(This.$lineMove.data("tid")); - } - document.onmousemove = null; - document.onmouseup = null; - } - }); - this.$lineOper = - $( - ""); //选定线时显示的操作框 - this.$workArea.append(this.$lineOper); - this.$lineOper.on("click", - { inthis: this }, - function(e) { - if (!e) e = window.event; - if (e.target.tagName != "A" && e.target.tagName != "B") return; - var This = e.data.inthis; - var id = $(this).data("tid"); - switch ($(e.target).attr("class")) { - case "b_x": - This.delLine(id); - this.style.display = "none"; - break; - case "b_l1": - This.setLineType(id, "lr"); - break; - case "b_l2": - This.setLineType(id, "tb"); - break; - case "b_l3": - This.setLineType(id, "sl"); - break; - break; - } - }); - - //下面绑定当结点/线/分组块的一些操作事件,这些事件可直接通过this访问对象本身 - //当操作某个单元(结点/线/分组块)被添加时,触发的方法,返回FALSE可阻止添加事件的发生 - //格式function(id,type,json):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值,json即addNode,addLine或addArea方法的第二个传参json. - this.onItemAdd = null; - //当操作某个单元(结点/线/分组块)被删除时,触发的方法,返回FALSE可阻止删除事件的发生 - //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值 - this.onItemDel = null; - //当操作某个单元(结点/分组块)被移动时,触发的方法,返回FALSE可阻止移动事件的发生 - //格式function(id,type,left,top):id是单元的唯一标识ID,type是单元的种类,有"node","area"两种取值,线line不支持移动,left是新的左边距坐标,top是新的顶边距坐标 - this.onItemMove = null; - //当操作某个单元(结点/线/分组块)被重命名时,触发的方法,返回FALSE可阻止重命名事件的发生 - //格式function(id,name,type):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值,name是新的名称 - this.onItemRename = null; - //当操作某个单元(结点/线)被由不选中变成选中时,触发的方法,返回FALSE可阻止选中事件的发生 - //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line"两种取值,"area"不支持被选中 - this.onItemFocus = null; - //当操作某个单元(结点/线)被由选中变成不选中时,触发的方法,返回FALSE可阻止取消选中事件的发生 - //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line"两种取值,"area"不支持被取消选中 - this.onItemBlur = null; - //当操作某个单元(结点/分组块)被重定义大小或造型时,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 - //格式function(id,type,width,height):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值;width是新的宽度,height是新的高度 - this.onItemResize = null; - //当移动某条折线中段的位置,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 - //格式function(id,M):id是单元的唯一标识ID,M是中段的新X(或Y)的坐标 - this.onLineMove = null; - //当变换某条连接线的类型,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 - //格式function(id,type):id是单元的唯一标识ID,type是连接线的新类型,"sl":直线,"lr":中段可左右移动的折线,"tb":中段可上下移动的折线 - this.onLineSetType = null; - //当用重色标注某个结点/转换线时触发的方法,返回FALSE可阻止重定大小/造型事件的发生 - //格式function(id,type,mark):id是单元的唯一标识ID,type是单元类型("node"结点,"line"转换线),mark为布尔值,表示是要标注TRUE还是取消标注FALSE - this.onItemMark = null; - - if (property.useOperStack && this.$editable) { //如果要使用堆栈记录操作并提供“撤销/重做”的功能,只在编辑状态下有效 - this.$undoStack = []; - this.$redoStack = []; - this.$isUndo = 0; - ///////////////以下是构造撤销操作/重做操作的方法 - //为了节省浏览器内存空间,undo/redo中的操作缓存栈,最多只可放40步操作;超过40步时,将自动删掉最旧的一个缓存 - this.pushOper = function(funcName, paras) { - var len = this.$undoStack.length; - if (this.$isUndo == 1) { - this.$redoStack.push([funcName, paras]); - this.$isUndo = false; - if (this.$redoStack.length > 40) this.$redoStack.shift(); - } else { - this.$undoStack.push([funcName, paras]); - if (this.$undoStack.length > 40) this.$undoStack.shift(); - if (this.$isUndo == 0) { - this.$redoStack.splice(0, this.$redoStack.length); - } - this.$isUndo = 0; - } - }; - //将外部的方法加入到GooFlow对象的事务操作堆栈中,在过后的undo/redo操作中可以进行控制,一般用于对流程图以外的附加信息进行编辑的事务撤销/重做控制; - //传参func为要执行方法对象,jsonPara为外部方法仅有的一个面向字面的JSON传参,由JSON对象带入所有要传的信息; - //提示:为了让外部方法能够被UNDO/REDO,需要在编写这些外部方法实现时,加入对该方法执行后效果回退的另一个执行方法的pushExternalOper - this.pushExternalOper = function(func, jsonPara) { - this.pushOper("externalFunc", [func, jsonPara]); - }; - //撤销上一步操作 - this.undo = function() { - if (this.$undoStack.length == 0) return; - var tmp = this.$undoStack.pop(); - this.$isUndo = 1; - if (tmp[0] == "externalFunc") { - tmp[1][0](tmp[1][1]); - } else { - //传参的数量,最多支持6个. - switch (tmp[1].length) { - case 0: - this[tmp[0]](); - break; - case 1: - this[tmp[0]](tmp[1][0]); - break; - case 2: - this[tmp[0]](tmp[1][0], tmp[1][1]); - break; - case 3: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2]); - break; - case 4: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2], tmp[1][3]); - break; - case 5: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2], tmp[1][3], tmp[1][4]); - break; - case 6: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2], tmp[1][3], tmp[1][4], tmp[1][5]); - break; - } - } - }; - //重做最近一次被撤销的操作 - this.redo = function() { - if (this.$redoStack.length == 0) return; - var tmp = this.$redoStack.pop(); - this.$isUndo = 2; - if (tmp[0] == "externalFunc") { - tmp[1][0](tmp[1][1]); - } else { - //传参的数量,最多支持6个. - switch (tmp[1].length) { - case 0: - this[tmp[0]](); - break; - case 1: - this[tmp[0]](tmp[1][0]); - break; - case 2: - this[tmp[0]](tmp[1][0], tmp[1][1]); - break; - case 3: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2]); - break; - case 4: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2], tmp[1][3]); - break; - case 5: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2], tmp[1][3], tmp[1][4]); - break; - case 6: - this[tmp[0]](tmp[1][0], tmp[1][1], tmp[1][2], tmp[1][3], tmp[1][4], tmp[1][5]); - break; - } - } - }; - } - $(document).keydown({ inthis: this }, - function(e) { - //绑定键盘操作 - var This = e.data.inthis; - if (This.$focus == "") return; - switch (e.keyCode) { - case 46: //删除 - This.delNode(This.$focus, true); - This.delLine(This.$focus); - break; - } - }); - } - } - - GooFlow.prototype = { - useSVG: "", - getSvgMarker: function(id, color) { - var m = document.createElementNS("http://www.w3.org/2000/svg", "marker"); - m.setAttribute("id", id); - m.setAttribute("viewBox", "0 0 6 6"); - m.setAttribute("refX", 5); - m.setAttribute("refY", 3); - m.setAttribute("markerUnits", "strokeWidth"); - m.setAttribute("markerWidth", 6); - m.setAttribute("markerHeight", 6); - m.setAttribute("orient", "auto"); - var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttribute("d", "M 0 0 L 6 3 L 0 6 z"); - path.setAttribute("fill", color); - path.setAttribute("stroke-width", 0); - m.appendChild(path); - return m; - }, - initDraw: function(id, width, height) { - var elem; - if (GooFlow.prototype.useSVG != "") { - this.$draw = document.createElementNS("http://www.w3.org/2000/svg", "svg"); //可创建带有指定命名空间的元素节点 - this.$workArea.prepend(this.$draw); - var defs = document.createElementNS("http://www.w3.org/2000/svg", "defs"); - this.$draw.appendChild(defs); - defs.appendChild(GooFlow.prototype.getSvgMarker("arrow1", "gray")); - defs.appendChild(GooFlow.prototype.getSvgMarker("arrow2", "#ff3300")); - defs.appendChild(GooFlow.prototype.getSvgMarker("arrow3", "#ff3300")); - } else { - this.$draw = document.createElement("v:group"); - this.$draw.coordsize = width * 3 + "," + height * 3; - this.$workArea.prepend("
"); - this.$workArea.children("div")[0].insertBefore(this.$draw, null); - } - this.$draw.id = id; - this.$draw.style.width = width * 3 + "px"; - this.$draw.style.height = +height * 3 + "px"; - //绑定连线的点击选中以及双击编辑事件 - var tmpClk = null; - if (GooFlow.prototype.useSVG != "") tmpClk = "g"; - else tmpClk = "PolyLine"; - if (this.$editable) { - $(this.$draw).delegate(tmpClk, - "click", - { inthis: this }, - function(e) { - e.data.inthis.focusItem(this.id, true); - }); - $(this.$draw).delegate(tmpClk, - "dblclick", - { inthis: this }, - function(e) { - var This = e.data.inthis; - OpenLine(this.id, This); - //var oldTxt, x, y, from, to; - //var This = e.data.inthis; - //if (GooFlow.prototype.useSVG != "") { - // oldTxt = this.childNodes[2].textContent; - // from = this.getAttribute("from").split(","); - // to = this.getAttribute("to").split(","); - //} else { - // oldTxt = this.childNodes[1].innerHTML; - // var n = this.getAttribute("fromTo").split(","); - // from = [n[0], n[1]]; - // to = [n[2], n[3]]; - //} - //if (This.$lineData[this.id].type == "lr") { - // from[0] = This.$lineData[this.id].M; - // to[0] = from[0]; - //} - //else if (This.$lineData[this.id].type == "tb") { - // from[1] = This.$lineData[this.id].M; - // to[1] = from[1]; - //} - //x = (parseInt(from[0], 10) + parseInt(to[0], 10)) / 2 - 60; - //y = (parseInt(from[1], 10) + parseInt(to[1], 10)) / 2 - 12; - //var t = getElCoordinate(This.$workArea[0]); - //This.$textArea.val(oldTxt).css({ - // display: "block", width: 120, height: 14, - // left: t.left + x - This.$workArea[0].parentNode.scrollLeft, - // top: t.top + y - This.$workArea[0].parentNode.scrollTop - //}).data("id", This.$focus).focus(); - //This.$workArea.parent().one("mousedown", function (e) { - // if (e.button == 2) return false; - // This.setName(This.$textArea.data("id"), This.$textArea.val(), "line"); - // This.$textArea.val("").removeData("id").hide(); - //}); - }); - } - }, - initGroup: function(width, height) { - this.$group = - $("
"); //存放背景区域的容器 - this.$workArea.prepend(this.$group); - if (!this.$editable) return; - //区域划分框操作区的事件绑定 - this.$group.on("mousedown", - { inthis: this }, - function(e) { //绑定RESIZE功能以及移动功能 - if (e.button == 2) return false; - var This = e.data.inthis; - if (This.$nowType != "group") return; - if (This.$textArea.css("display") == "block") { - This.setName(This.$textArea.data("id"), This.$textArea.val(), "area"); - This.$textArea.val("").removeData("id").hide(); - return false; - }; - if (!e) e = window.event; - var cursor = $(e.target).css("cursor"); - var id = e.target.parentNode; - switch (cursor) { - case "nw-resize": - id = id.parentNode; - break; - case "w-resize": - id = id.parentNode; - break; - case "n-resize": - id = id.parentNode; - break; - case "move": - break; - default: - return; - } - id = id.id; - var hack = 1; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 0; - var ev = mousePosition(e), t = getElCoordinate(This.$workArea[0]); - - var X, Y; - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop; - if (cursor != "move") { - This.$ghost.css({ - display: "block", - width: This.$areaData[id].width - 2 + "px", - height: This.$areaData[id].height - 2 + "px", - top: This.$areaData[id].top + - t.top - - This.$workArea[0].parentNode.scrollTop + - hack + - "px", - left: This.$areaData[id].left + - t.left - - This.$workArea[0].parentNode.scrollLeft + - hack + - "px", - cursor: cursor - }); - var vX = (This.$areaData[id].left + This.$areaData[id].width) - X; - var vY = (This.$areaData[id].top + This.$areaData[id].height) - Y; - } else { - var vX = X - This.$areaData[id].left; - var vY = Y - This.$areaData[id].top; - } - var isMove = false; - This.$ghost.css("cursor", cursor); - document.onmousemove = function(e) { - if (!e) e = window.event; - var ev = mousePosition(e); - if (cursor != "move") { - X = ev.x - - t.left + - This.$workArea[0].parentNode.scrollLeft - - This.$areaData[id].left + - vX; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop - This.$areaData[id].top + vY; - if (X < 200) X = 200; - if (Y < 100) Y = 100; - switch (cursor) { - case "nw-resize": - This.$ghost.css({ width: X - 2 + "px", height: Y - 2 + "px" }); - break; - case "w-resize": - This.$ghost.css({ width: X - 2 + "px" }); - break; - case "n-resize": - This.$ghost.css({ height: Y - 2 + "px" }); - break; - } - } else { - if (This.$ghost.css("display") == "none") { - This.$ghost.css({ - display: "block", - width: This.$areaData[id].width - 2 + "px", - height: This.$areaData[id].height - 2 + "px", - top: This.$areaData[id].top + - t.top - - This.$workArea[0].parentNode.scrollTop + - hack + - "px", - left: This.$areaData[id].left + - t.left - - This.$workArea[0].parentNode.scrollLeft + - hack + - "px", - cursor: cursor - }); - } - X = ev.x - vX; - Y = ev.y - vY; - if (X < t.left - This.$workArea[0].parentNode.scrollLeft) - X = t.left - This.$workArea[0].parentNode.scrollLeft; - else if (X + This.$workArea[0].parentNode.scrollLeft + This.$areaData[id].width > - t.left + This.$workArea.width()) - X = t.left + - This.$workArea.width() - - This.$workArea[0].parentNode.scrollLeft - - This.$areaData[id].width; - if (Y < t.top - This.$workArea[0].parentNode.scrollTop) - Y = t.top - This.$workArea[0].parentNode.scrollTop; - else if (Y + This.$workArea[0].parentNode.scrollTop + This.$areaData[id].height > - t.top + This.$workArea.height()) - Y = t.top + - This.$workArea.height() - - This.$workArea[0].parentNode.scrollTop - - This.$areaData[id].height; - This.$ghost.css({ left: X + hack + "px", top: Y + hack + "px" }); - } - isMove = true; - } - document.onmouseup = function(e) { - This.$ghost.empty().hide(); - document.onmousemove = null; - document.onmouseup = null; - if (!isMove) return; - if (cursor != "move") - This.resizeArea(id, This.$ghost.outerWidth(), This.$ghost.outerHeight()); - else - This.moveArea(id, - X + This.$workArea[0].parentNode.scrollLeft - t.left, - Y + This.$workArea[0].parentNode.scrollTop - t.top); - return false; - } - }); - //绑定修改文字说明功能 - this.$group.on("dblclick", - { inthis: this }, - function(e) { - var This = e.data.inthis; - if (This.$nowType != "group") return; - if (!e) e = window.event; - if (e.target.tagName != "LABEL") return false; - var oldTxt = e.target.innerHTML; - var p = e.target.parentNode; - var x = parseInt(p.style.left, 10) + 18, y = parseInt(p.style.top, 10) + 1; - var t = getElCoordinate(This.$workArea[0]); - This.$textArea.val(oldTxt).css({ - display: "block", - width: 100, - height: 14, - left: t.left + x - This.$workArea[0].parentNode.scrollLeft, - top: t.top + y - This.$workArea[0].parentNode.scrollTop - }).data("id", p.id).focus(); - This.$workArea.parent().one("mousedown", - function(e) { - if (e.button == 2) return false; - if (This.$textArea.css("display") == "block") { - This.setName(This.$textArea.data("id"), This.$textArea.val(), "area"); - This.$textArea.val("").removeData("id").hide(); - } - }); - return false; - }); - //绑定点击事件 - this.$group.mouseup({ inthis: this }, - function(e) { - - var This = e.data.inthis; - if (This.$nowType != "group") return; - if (!e) e = window.event; - switch ($(e.target).attr("class")) { - case "rs_close": - This.delArea(e.target.parentNode.parentNode.id); - return false; //删除该分组区域 - case "bg": - return; - } - switch (e.target.tagName) { - case "LABEL": - return false; - case "B": //绑定变色功能 - var id = e.target.parentNode.id; - switch (This.$areaData[id].color) { - case "red": - This.setAreaColor(id, "yellow"); - break; - case "yellow": - This.setAreaColor(id, "blue"); - break; - case "blue": - This.setAreaColor(id, "green"); - break; - case "green": - This.setAreaColor(id, "red"); - break; - } - return false; - } - if (e.data.inthis.$ghost.css("display") == "none") { - var X, Y; - var ev = mousePosition(e), t = getElCoordinate(this); - X = ev.x - t.left + this.parentNode.parentNode.scrollLeft - 1; - Y = ev.y - t.top + this.parentNode.parentNode.scrollTop - 1; - var color = ["red", "yellow", "blue", "green"]; - e.data.inthis.addArea(e.data.inthis.$id + "_area_" + e.data.inthis.$max, - { - name: "area_" + e.data.inthis.$max, - left: X, - top: Y, - color: color[e.data.inthis.$max % 4], - width: 200, - height: 100 - }); - e.data.inthis.$max++; - return false; - } - }); - }, - //每一种类型结点及其按钮的说明文字 - setNodeRemarks: function(remark) { - if (this.$tool != null) { - this.$tool.children("a").each(function() { - this.title = remark[$(this).attr("id").split("btn_")[1]]; - }); - this.$nodeRemark = remark; - } - }, - - //切换左边工具栏按钮,传参TYPE表示切换成哪种类型的按钮 - switchToolBtn: function(type) { - this.$tool.children("#" + this.$id + "_btn_" + this.$nowType.split(" ")[0]) - .attr("class", "GooFlow_tool_btn"); - if (this.$nowType == "group") { - this.$workArea.prepend(this.$group); - for (var key in this.$areaDom) - this.$areaDom[key].addClass("lock").children("div:eq(1)").css("display", "none"); - } - this.$nowType = type; - this.$tool.children("#" + this.$id + "_btn_" + type.split(" ")[0]) - .attr("class", "GooFlow_tool_btndown"); - if (this.$nowType == "group") { - this.blurItem(); - this.$workArea.append(this.$group); - for (var key in this.$areaDom) - this.$areaDom[key].removeClass("lock").children("div:eq(1)").css("display", ""); - } - if (this.$textArea.css("display") == "none") this.$textArea.removeData("id").val("").hide(); - }, - //增加一个流程结点,传参为一个JSON,有id,name,top,left,width,height,type(结点类型)等属性 - addNode: function(id, json) { - if (this.onItemAdd != null && !this.onItemAdd(id, "node", json)) return; - if (this.$undoStack && this.$editable) { - this.pushOper("delNode", [id]); - } - var mark = json.type; - if (json.type != "startround" && json.type != "endround") { - if (!json.width || json.width < 86) json.width = 150; - if (!json.height || json.height < 24) json.height = 65; - if (!json.top || json.top < 0) json.top = 0; - if (!json.left || json.left < 0) json.left = 0; - var hack = 0; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 2; - this.$nodeDom[id] = $("
" + - json.name + - "
"); - if (json.type.indexOf(" mix") > -1) this.$nodeDom[id].addClass(mark); - //json.css = mark; - //json.img = mark; - } else { - json.width = 24; - json.height = 24; - var name = json.name; - if (json.type == 'startround') { - name = "开始"; - } - if (json.type == 'endround') { - name = "结束"; - } - this.$nodeDom[id] = $("
" + - name + - "
"); - } - var ua = navigator.userAgent.toLowerCase(); - if (ua.indexOf('msie') != -1 && ua.indexOf('8.0') != -1) - this.$nodeDom[id].css("filter", - "progid:DXImageTransform.Microsoft.Shadow(color=#94AAC2,direction=135,strength=2)"); - this.$workArea.append(this.$nodeDom[id]); - this.$nodeData[id] = json; - ++this.$nodeCount; - if (this.$editable) { - this.$nodeData[id].alt = true; - if (this.$deletedItem[id]) delete this.$deletedItem[id]; //在回退删除操作时,去掉该元素的删除记录 - } - }, - initWorkForNode: function() { - //绑定点击事件 - this.$workArea.delegate(".GooFlow_item", - "click", - { inthis: this }, - function(e) { - e.data.inthis.focusItem(this.id, true); - $(this).removeClass("item_mark"); - //if (!$(this).hasClass("item_startround")) { - // LoadrightMenu("#" + this.id); - //} - //if (!$(this).hasClass("item_endround")) { - // LoadrightMenu("#" + this.id); - //} - }); - //绑定右击事件 - this.$workArea.delegate(".GooFlow_item", - "contextmenu", - { inthis: this }, - function(e) { - e.data.inthis.focusItem(this.id, true); - $(this).removeClass("item_mark"); - return false; - }); - //绑定用鼠标移动事件 - this.$workArea.delegate(".ico", - "mousedown", - { inthis: this }, - function(e) { - if (!e) e = window.event; - if (e.button == 2) return false; - var This = e.data.inthis; - if (This.$nowType == "direct") return; - var Dom = $(this).parents(".GooFlow_item"); - var id = Dom.attr("id"); - This.focusItem(id, true); - var hack = 1; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 0; - var ev = mousePosition(e), t = getElCoordinate(This.$workArea[0]); - - Dom.children("table").clone().prependTo(This.$ghost); - var X, Y; - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop; - var vX = X - This.$nodeData[id].left, vY = Y - This.$nodeData[id].top; - var isMove = false; - document.onmousemove = function(e) { - if (!e) e = window.event; - var ev = mousePosition(e); - if (X == ev.x - vX && Y == ev.y - vY) return false; - X = ev.x - vX; - Y = ev.y - vY; - - if (isMove && This.$ghost.css("display") == "none") { - This.$ghost.css({ - display: "block", - width: $('#' + id).width() - 2 + "px", - height: $('#' + id).height() - 2 + "px", - top: This.$nodeData[id].top + - t.top - - This.$workArea[0].parentNode.scrollTop + - hack + - "px", - left: This.$nodeData[id].left + - t.left - - This.$workArea[0].parentNode.scrollLeft + - hack + - "px", - cursor: "move" - }); - } - - if (X < t.left - This.$workArea[0].parentNode.scrollLeft) - X = t.left - This.$workArea[0].parentNode.scrollLeft; - else if (X + This.$workArea[0].parentNode.scrollLeft + This.$nodeData[id].width > - t.left + This.$workArea.width()) - X = t.left + - This.$workArea.width() - - This.$workArea[0].parentNode.scrollLeft - - This.$nodeData[id].width; - if (Y < t.top - This.$workArea[0].parentNode.scrollTop) - Y = t.top - This.$workArea[0].parentNode.scrollTop; - else if (Y + This.$workArea[0].parentNode.scrollTop + This.$nodeData[id].height > - t.top + This.$workArea.height()) - Y = t.top + - This.$workArea.height() - - This.$workArea[0].parentNode.scrollTop - - This.$nodeData[id].height; - This.$ghost.css({ left: X + hack + "px", top: Y + hack + "px" }); - isMove = true; - } - document.onmouseup = function(e) { - if (isMove) - This.moveNode(id, - X + This.$workArea[0].parentNode.scrollLeft - t.left, - Y + This.$workArea[0].parentNode.scrollTop - t.top); - This.$ghost.empty().hide(); - document.onmousemove = null; - document.onmouseup = null; - } - }); - if (!this.$editable) return; - //绑定鼠标覆盖/移出事件 - this.$workArea.delegate(".GooFlow_item", - "mouseenter", - { inthis: this }, - function(e) { - if (e.data.inthis.$nowType != "direct") return; - $(this).addClass("item_mark"); - }); - this.$workArea.delegate(".GooFlow_item", - "mouseleave", - { inthis: this }, - function(e) { - if (e.data.inthis.$nowType != "direct") return; - $(this).removeClass("item_mark"); - }); - //绑定连线时确定初始点 - this.$workArea.delegate(".GooFlow_item", - "mousedown", - { inthis: this }, - function(e) { - if (e.button == 2) return false; - var This = e.data.inthis; - if (This.$nowType != "direct") return; - var ev = mousePosition(e), t = getElCoordinate(This.$workArea[0]); - var X, Y; - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop; - This.$workArea.data("lineStart", { "x": X, "y": Y, "id": this.id }).css("cursor", "crosshair"); - var line = GooFlow.prototype.drawLine("GooFlow_tmp_line", [X, Y], [X, Y], true, true); - This.$draw.appendChild(line); - }); - //绑定连线时确定结束点 - this.$workArea.delegate(".GooFlow_item", - "mouseup", - { inthis: this }, - function(e) { - var This = e.data.inthis; - if (This.$nowType != "direct") return; - var lineStart = This.$workArea.data("lineStart"); - if (lineStart) - This.addLine(This.$id + "_line_" + This.$max, - { from: lineStart.id, to: this.id, name: "" }); - This.$max++; - }); - //绑定双击编辑事件 - this.$workArea.delegate(".GooFlow_item > .span", - "dblclick", - { inthis: this }, - function(e) { - var This = e.data.inthis; - var type = $('.item_focus').hasClass('item_startround'); - if (type) { - OpenNode(This); - } - //var oldTxt = this.innerHTML; - //var This = e.data.inthis; - //var id = this.parentNode.id; - //var t = getElCoordinate(This.$workArea[0]); - //This.$textArea.val(oldTxt).css({ - // display: "block", height: $(this).height(), width: 100, - // left: t.left + This.$nodeData[id].left - This.$workArea[0].parentNode.scrollLeft - 24, - // top: t.top + This.$nodeData[id].top - This.$workArea[0].parentNode.scrollTop + 26 - //}) - // .data("id", This.$focus).focus(); - //This.$workArea.parent().one("mousedown", function (e) { - // if (e.button == 2) return false; - // This.setName(This.$textArea.data("id"), This.$textArea.val(), "node"); - // This.$textArea.val("").removeData("id").hide(); - //}); - }); - //节点双击事件 - this.$workArea.delegate(".ico + td", - "dblclick", - { inthis: this }, - function(e) { - var This = e.data.inthis; - OpenNode(This); - //var oldTxt = this.innerHTML; - //var This = e.data.inthis; - //var id = $(this).parents(".GooFlow_item").attr("id"); - //var t = getElCoordinate(This.$workArea[0]); - //This.$textArea.val(oldTxt).css({ - // display: "block", width: $(this).width() + 24, height: $(this).height(), - // left: t.left + 24 + This.$nodeData[id].left - This.$workArea[0].parentNode.scrollLeft, - // top: t.top + 2 + This.$nodeData[id].top - This.$workArea[0].parentNode.scrollTop - //}) - // .data("id", This.$focus).focus(); - //This.$workArea.parent().one("mousedown", function (e) { - // if (e.button == 2) return false; - // This.setName(This.$textArea.data("id"), This.$textArea.val(), "node"); - // This.$textArea.val("").removeData("id").hide(); - //}); - }); - //绑定结点的删除功能 - this.$workArea.delegate(".rs_close", - "click", - { inthis: this }, - function(e) { - if (!e) e = window.event; - e.data.inthis.delNode(e.data.inthis.$focus); - return false; - }); - //绑定结点的RESIZE功能 - this.$workArea.delegate(".GooFlow_item > div > div[class!=rs_close]", - "mousedown", - { inthis: this }, - function(e) { - if (!e) e = window.event; - if (e.button == 2) return false; - var cursor = $(this).css("cursor"); - if (cursor == "pointer") { - return; - } - var This = e.data.inthis; - var id = This.$focus; - This.switchToolBtn("cursor"); - e.cancelBubble = true; - e.stopPropagation(); - var hack = 1; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 0; - var ev = mousePosition(e), t = getElCoordinate(This.$workArea[0]); - This.$ghost.css({ - display: "block", - width: This.$nodeData[id].width - 2 + "px", - height: This.$nodeData[id].height - 2 + "px", - top: This.$nodeData[id].top + t.top - This.$workArea[0].parentNode.scrollTop + hack + "px", - left: This.$nodeData[id].left + - t.left - - This.$workArea[0].parentNode.scrollLeft + - hack + - "px", - cursor: cursor - }); - var X, Y; - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop; - var vX = (This.$nodeData[id].left + This.$nodeData[id].width) - X; - var vY = (This.$nodeData[id].top + This.$nodeData[id].height) - Y; - var isMove = false; - This.$ghost.css("cursor", cursor); - document.onmousemove = function(e) { - if (!e) e = window.event; - var ev = mousePosition(e); - X = ev.x - t.left + This.$workArea[0].parentNode.scrollLeft - This.$nodeData[id].left + vX; - Y = ev.y - t.top + This.$workArea[0].parentNode.scrollTop - This.$nodeData[id].top + vY; - if (X < 86) X = 86; - if (Y < 24) Y = 24; - isMove = true; - switch (cursor) { - case "nw-resize": - This.$ghost.css({ width: X - 2 + "px", height: Y - 2 + "px" }); - break; - case "w-resize": - This.$ghost.css({ width: X - 2 + "px" }); - break; - case "n-resize": - This.$ghost.css({ height: Y - 2 + "px" }); - break; - } - } - document.onmouseup = function(e) { - This.$ghost.hide(); - if (!isMove) return; - if (!e) e = window.event; - This.resizeNode(id, This.$ghost.outerWidth(), This.$ghost.outerHeight()); - document.onmousemove = null; - document.onmouseup = null; - } - }); - }, - //获取结点/连线/分组区域的详细信息 - getItemInfo: function(id, type) { - switch (type) { - case "node": - return this.$nodeData[id] || null; - case "line": - return this.$lineData[id] || null; - case "area": - return this.$areaData[id] || null; - } - }, - //取消所有结点/连线被选定的状态 - blurItem: function() { - if (this.$focus != "") { - var jq = $("#" + this.$focus); - if (jq.prop("tagName") == "DIV") { - if (this.onItemBlur != null && !this.onItemBlur(id, "node")) return false; - jq.removeClass("item_focus").children("div:eq(0)").css("display", "none"); - } else { - if (this.onItemBlur != null && !this.onItemBlur(id, "line")) return false; - if (GooFlow.prototype.useSVG != "") { - if (!this.$lineData[this.$focus].marked) { - jq[0].childNodes[1].setAttribute("stroke", "gray"); - jq[0].childNodes[1].setAttribute("marker-end", "url(#arrow1)"); - } - } else { - if (!this.$lineData[this.$focus].marked) jq[0].strokeColor = "gray"; - } - this.$lineMove.hide().removeData("type").removeData("tid"); - if (this.$editable) this.$lineOper.hide().removeData("tid"); - } - } - this.$focus = ""; - return true; - }, - //选定某个结点/转换线 bool:TRUE决定了要触发选中事件,FALSE则不触发选中事件,多用在程序内部调用。 - focusItem: function(id, bool) { - var jq = $("#" + id); - if (jq.length == 0) return; - if (!this.blurItem()) return; //先执行"取消选中",如果返回FLASE,则也会阻止选定事件继续进行. - if (jq.prop("tagName") == "DIV") { - if (bool && this.onItemFocus != null && !this.onItemFocus(id, "node")) return; - jq.addClass("item_focus"); - if (this.$editable) jq.children("div:eq(0)").css("display", "block"); - this.$workArea.append(jq); - } else { //如果是连接线 - if (this.onItemFocus != null && !this.onItemFocus(id, "line")) return; - if (GooFlow.prototype.useSVG != "") { - jq[0].childNodes[1].setAttribute("stroke", "#ff3300"); - jq[0].childNodes[1].setAttribute("marker-end", "url(#arrow2)"); - } else jq[0].strokeColor = "#ff3300"; - if (!this.$editable) return; - var x, y, from, to; - if (GooFlow.prototype.useSVG != "") { - from = jq.attr("from").split(","); - to = jq.attr("to").split(","); - } else { - var n = jq[0].getAttribute("fromTo").split(","); - from = [n[0], n[1]]; - to = [n[2], n[3]]; - } - from[0] = parseInt(from[0], 10); - from[1] = parseInt(from[1], 10); - to[0] = parseInt(to[0], 10); - to[1] = parseInt(to[1], 10); - //var t=getElCoordinate(this.$workArea[0]); - if (this.$lineData[id].type == "lr") { - from[0] = this.$lineData[id].M; - to[0] = from[0]; - - this.$lineMove.css({ - width: "5px", - height: (to[1] - from[1]) * (to[1] > from[1] ? 1 : -1) + "px", - left: from[0] - 3 + "px", - top: (to[1] > from[1] ? from[1] : to[1]) + 1 + "px", - cursor: "e-resize", - display: "block" - }).data({ "type": "lr", "tid": id }); - } else if (this.$lineData[id].type == "tb") { - from[1] = this.$lineData[id].M; - to[1] = from[1]; - this.$lineMove.css({ - width: (to[0] - from[0]) * (to[0] > from[0] ? 1 : -1) + "px", - height: "5px", - left: (to[0] > from[0] ? from[0] : to[0]) + 1 + "px", - top: from[1] - 3 + "px", - cursor: "s-resize", - display: "block" - }).data({ "type": "tb", "tid": id }); - } - x = (from[0] + to[0]) / 2 - 35; - y = (from[1] + to[1]) / 2 + 6; - this.$lineOper.css({ display: "block", left: x + "px", top: y + "px" }).data("tid", id); - } - this.$focus = id; - this.switchToolBtn("cursor"); - }, - //移动结点到一个新的位置 - moveNode: function(id, left, top) { - if (!this.$nodeData[id]) return; - if (this.onItemMove != null && !this.onItemMove(id, "node", left, top)) return; - if (this.$undoStack) { - var paras = [id, this.$nodeData[id].left, this.$nodeData[id].top]; - this.pushOper("moveNode", paras); - } - if (left < 0) left = 0; - if (top < 0) top = 0; - $("#" + id).css({ left: left + "px", top: top + "px" }); - this.$nodeData[id].left = left; - this.$nodeData[id].top = top; - //重画转换线 - this.resetLines(id, this.$nodeData[id]); - if (this.$editable) { - this.$nodeData[id].alt = true; - } - }, - //设置结点/连线/分组区域的文字信息 - setName: function(id, name, type, setinfo) { - var oldName; - if (type == "node") { //如果是结点 - this.$nodeData[id].setInfo = setinfo; - if (!this.$nodeData[id]) - if (this.$nodeData[id].name == name) - if (this.onItemRename != null && !this.onItemRename(id, name, "node")) - oldName = this.$nodeData[id].name; - this.$nodeData[id].name = name; - if (this.$nodeData[id].type.indexOf("round") > 1) { - this.$nodeDom[id].children(".span").text(name); - } else { - this.$nodeDom[id].find("td:eq(1)").text(name); - var hack = 0; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 2; - var width = this.$nodeDom[id].outerWidth(); - var height = this.$nodeDom[id].outerHeight(); - this.$nodeDom[id].children("table").css({ width: width - 2 + "px", height: height - 2 + "px" }); - this.$nodeData[id].width = width; - this.$nodeData[id].height = height; - } - if (this.$editable) { - this.$nodeData[id].alt = true; - } - //重画转换线 - this.resetLines(id, this.$nodeData[id]); - } else if (type == "line") { //如果是线 - this.$lineData[id].setInfo = setinfo; - if (!this.$lineData[id]) - if (this.$lineData[id].name == name) - if (this.onItemRename != null && !this.onItemRename(id, name, "line")) - oldName = this.$lineData[id].name; - this.$lineData[id].name = name; - if (GooFlow.prototype.useSVG != "") { - this.$lineDom[id].childNodes[2].textContent = name; - } else { - this.$lineDom[id].childNodes[1].innerHTML = name; - var n = this.$lineDom[id].getAttribute("fromTo").split(","); - var x; - if (this.$lineData[id].type != "lr") { - x = (n[2] - n[0]) / 2; - } else { - var Min = n[2] > n[0] ? n[0] : n[2]; - if (Min > this.$lineData[id].M) Min = this.$lineData[id].M; - x = this.$lineData[id].M - Min; - } - if (x < 0) x = x * -1; - this.$lineDom[id].childNodes[1].style.left = - x - this.$lineDom[id].childNodes[1].offsetWidth / 2 + 4 + "px"; - } - if (this.$editable) { - this.$lineData[id].alt = true; - } - } else if (type == "area") { //如果是分组区域 - if (!this.$areaData[id]) return; - if (this.$areaData[id].name == name) return; - if (this.onItemRename != null && !this.onItemRename(id, name, "area")) return; - oldName = this.$areaData[id].name; - this.$areaData[id].name = name; - this.$areaDom[id].children("label").text(name); - if (this.$editable) { - this.$areaData[id].alt = true; - } - } - if (this.$undoStack) { - var paras = [id, oldName, type]; - this.pushOper("setName", paras); - } - }, - //设置结点的尺寸,仅支持非开始/结束结点 - resizeNode: function(id, width, height) { - if (!this.$nodeData[id]) return; - if (this.onItemResize != null && !this.onItemResize(id, "node", width, height)) return; - if (this.$nodeData[id].type == "start" || this.$nodeData[id].type == "end") return; - if (this.$undoStack) { - var paras = [id, this.$nodeData[id].width, this.$nodeData[id].height]; - this.pushOper("resizeNode", paras); - } - var hack = 0; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 2; - this.$nodeDom[id].children("table").css({ width: width - 2 + "px", height: height - 2 + "px" }); - width = this.$nodeDom[id].outerWidth() - hack; - height = this.$nodeDom[id].outerHeight() - hack; - this.$nodeDom[id].children("table").css({ width: width - 2 + "px", height: height - 2 + "px" }); - this.$nodeData[id].width = width; - this.$nodeData[id].height = height; - if (this.$editable) { - this.$nodeData[id].alt = true; - } - //重画转换线 - this.resetLines(id, this.$nodeData[id]); - }, - //删除结点 - delNode: function(id) { - if (!this.$nodeData[id]) return; - if (this.onItemDel != null && !this.onItemDel(id, "node")) return; - //先删除可能的连线 - for (var k in this.$lineData) { - if (this.$lineData[k].from == id || this.$lineData[k].to == id) { - //this.$draw.removeChild(this.$lineDom[k]); - //delete this.$lineData[k]; - //delete this.$lineDom[k]; - this.delLine(k); - } - } - //再删除结点本身 - if (this.$undoStack) { - var paras = [id, this.$nodeData[id]]; - this.pushOper("addNode", paras); - } - delete this.$nodeData[id]; - this.$nodeDom[id].remove(); - delete this.$nodeDom[id]; - --this.$nodeCount; - if (this.$focus == id) this.$focus = ""; - - if (this.$editable) { - //在回退新增操作时,如果节点ID以this.$id+"_node_"开头,则表示为本次编辑时新加入的节点,这些节点的删除不用加入到$deletedItem中 - if (id.indexOf(this.$id + "_node_") < 0) - this.$deletedItem[id] = "node"; - } - }, - //设置流程图的名称 - setTitle: function(text) { - this.$title = text; - if (this.$head) this.$head.children("label").attr("title", text).text(text); - }, - //载入一组数据 - loadData: function(data) { - if (data == undefined) { - data = ""; - } - var t = this.$editable; - this.$editable = false; - if (data.title) this.setTitle(data.title); - if (data.initNum) this.$max = data.initNum; - for (var i in data.nodes) - this.addNode(data.nodes[i].id, data.nodes[i]); - for (var j in data.lines) - this.addLine(data.lines[j].id, data.lines[j]); - for (var k in data.areas) - this.addArea(data.areas[k].id, data.areas[k]); - this.$editable = t; - this.$deletedItem = {}; - }, - //用AJAX方式,远程读取一组数据 - //参数para为JSON结构,与JQUERY中$.ajax()方法的传参一样 - loadDataAjax: function(para) { - var This = this; - $.ajax({ - type: para.type, - url: para.url, - dataType: "json", - data: para.data, - success: function(msg) { - if (para.dataFilter) para.dataFilter(msg, "json"); - This.loadData(msg); - if (para.success) para.success(msg); - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - if (para.error) para.error(textStatus, errorThrown); - } - }) - }, - //把画好的整个流程图导出到一个变量中(其实也可以直接访问GooFlow对象的$nodeData,$lineData,$areaData这三个JSON属性) - exportData: function() { - var ret = { - title: this.$title, - nodes: this.$nodeData, - lines: this.$lineData, - areas: this.$areaData, - initNum: this.$max - }; - - var _nodeobject = [], _lineobject = []; - for (var k1 in ret.nodes) { - if (!ret.nodes[k1].marked) { - delete ret.nodes[k1]["marked"]; - } - ret.nodes[k1]["id"] = k1; - _nodeobject.push(ret.nodes[k1]); - } - ret.nodes = _nodeobject; - for (var k2 in ret.lines) { - if (!ret.lines[k2].marked) { - delete ret.lines[k2]["marked"]; - } - ret.lines[k2]["id"] = k2; - _lineobject.push(ret.lines[k2]); - } - ret.lines = _lineobject; - return ret; - }, - //只把本次编辑流程图中作了变更(包括增删改)的元素导出到一个变量中,以方便用户每次编辑载入的流程图后只获取变更过的数据 - exportAlter: function() { - var ret = { nodes: {}, lines: {}, areas: {} }; - for (var k1 in this.$nodeData) { - if (this.$nodeData[k1].alt) { - ret.nodes[k1] = this.$nodeData[k1]; - } - } - for (var k2 in this.$lineData) { - if (this.$lineData[k2].alt) { - ret.lines[k2] = this.$lineData[k2]; - } - } - for (var k3 in this.$areaData) { - if (this.$areaData[k3].alt) { - ret.areas[k3] = this.$areaData[k3]; - } - } - ret.deletedItem = this.$deletedItem; - return ret; - }, - //变更元素的ID,一般用于快速保存后,将后台返回新元素的ID更新到页面中;type为元素类型(节点,连线,区块) - transNewId: function(oldId, newId, type) { - var tmp; - switch (type) { - case "node": - if (this.$nodeData[oldId]) { - tmp = this.$nodeData[oldId]; - delete this.$nodeData[oldId]; - this.$nodeData[newId] = tmp; - } - break; - case "line": - if (this.$lineData[oldId]) { - tmp = this.$lineData[oldId]; - delete this.$lineData[oldId]; - this.$lineData[newId] = tmp; - } - break; - case "area": - if (this.$areaData[oldId]) { - tmp = this.$areaData[oldId]; - delete this.$areaData[oldId]; - this.$areaData[newId] = tmp; - } - break; - } - }, - //清空工作区及已载入的数据 - clearData: function() { - for (var key in this.$nodeData) { - this.delNode(key); - } - for (var key in this.$lineData) { - this.delLine(key); - } - for (var key in this.$areaData) { - this.delArea(key); - } - this.$deletedItem = {}; - }, - //销毁自己 - destrory: function() { - this.$bgDiv.empty(); - this.$lineData = null; - this.$nodeData = null; - this.$lineDom = null; - this.$nodeDom = null; - this.$areaDom = null; - this.$areaData = null; - this.$nodeCount = 0; - this.$areaCount = 0; - this.$areaCount = 0; - this.$deletedItem = {}; - }, - ///////////以下为有关画线的方法 - //绘制一条箭头线,并返回线的DOM - drawLine: function(id, sp, ep, mark, dash) { - var line; - if (GooFlow.prototype.useSVG != "") { - line = document.createElementNS("http://www.w3.org/2000/svg", "g"); - var hi = document.createElementNS("http://www.w3.org/2000/svg", "path"); - var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - - if (id != "") line.setAttribute("id", id); - line.setAttribute("from", sp[0] + "," + sp[1]); - line.setAttribute("to", ep[0] + "," + ep[1]); - hi.setAttribute("visibility", "hidden"); - hi.setAttribute("stroke-width", 9); - hi.setAttribute("fill", "none"); - hi.setAttribute("stroke", "white"); - hi.setAttribute("d", "M " + sp[0] + " " + sp[1] + " L " + ep[0] + " " + ep[1]); - hi.setAttribute("pointer-events", "stroke"); - path.setAttribute("d", "M " + sp[0] + " " + sp[1] + " L " + ep[0] + " " + ep[1]); - path.setAttribute("stroke-width", 2.0); - path.setAttribute("stroke-linecap", "round"); - path.setAttribute("fill", "none"); - if (dash) path.setAttribute("style", "stroke-dasharray:6,5"); - if (mark) { - path.setAttribute("stroke", "#ff3300"); - path.setAttribute("marker-end", "url(#arrow2)"); - } else { - path.setAttribute("stroke", "gray"); - path.setAttribute("marker-end", "url(#arrow1)"); - } - line.appendChild(hi); - line.appendChild(path); - line.style.cursor = "crosshair"; - if (id != "" && id != "GooFlow_tmp_line") { - var text = document.createElementNS("http://www.w3.org/2000/svg", "text"); - //text.textContent=id; - line.appendChild(text); - var x = (ep[0] + sp[0]) / 2; - var y = (ep[1] + sp[1]) / 2; - text.setAttribute("text-anchor", "middle"); - text.setAttribute("x", x); - text.setAttribute("y", y - 5); - line.style.cursor = "pointer"; - text.style.cursor = "text"; - } - } else { - line = document.createElement("v:polyline"); - if (id != "") line.id = id; - //line.style.position="absolute"; - line.points.value = sp[0] + "," + sp[1] + " " + ep[0] + "," + ep[1]; - line.setAttribute("fromTo", sp[0] + "," + sp[1] + "," + ep[0] + "," + ep[1]); - line.strokeWeight = "1.2"; - line.stroke.EndArrow = "Block"; - line.style.cursor = "crosshair"; - if (id != "" && id != "GooFlow_tmp_line") { - var text = document.createElement("div"); - //text.innerHTML=id; - line.appendChild(text); - var x = (ep[0] - sp[0]) / 2; - var y = (ep[1] - sp[1]) / 2; - if (x < 0) x = x * -1; - if (y < 0) y = y * -1; - text.style.left = x + "px"; - text.style.top = y - 6 + "px"; - line.style.cursor = "pointer"; - } - if (dash) line.stroke.dashstyle = "Dash"; - if (mark) line.strokeColor = "#ff3300"; - else line.strokeColor = "gray"; - } - return line; - }, - //画一条只有两个中点的折线 - drawPoly: function(id, sp, m1, m2, ep, mark) { - var poly, strPath; - if (GooFlow.prototype.useSVG != "") { - poly = document.createElementNS("http://www.w3.org/2000/svg", "g"); - var hi = document.createElementNS("http://www.w3.org/2000/svg", "path"); - var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - if (id != "") poly.setAttribute("id", id); - poly.setAttribute("from", sp[0] + "," + sp[1]); - poly.setAttribute("to", ep[0] + "," + ep[1]); - hi.setAttribute("visibility", "hidden"); - hi.setAttribute("stroke-width", 9); - hi.setAttribute("fill", "none"); - hi.setAttribute("stroke", "white"); - strPath = "M " + sp[0] + " " + sp[1]; - if (m1[0] != sp[0] || m1[1] != sp[1]) - strPath += " L " + m1[0] + " " + m1[1]; - if (m2[0] != ep[0] || m2[1] != ep[1]) - strPath += " L " + m2[0] + " " + m2[1]; - strPath += " L " + ep[0] + " " + ep[1]; - hi.setAttribute("d", strPath); - hi.setAttribute("pointer-events", "stroke"); - path.setAttribute("d", strPath); - path.setAttribute("stroke-width", 2.0); - path.setAttribute("stroke-linecap", "round"); - path.setAttribute("fill", "none"); - if (mark) { - path.setAttribute("stroke", "#ff3300"); - path.setAttribute("marker-end", "url(#arrow2)"); - } else { - path.setAttribute("stroke", "gray"); - path.setAttribute("marker-end", "url(#arrow1)"); - } - poly.appendChild(hi); - poly.appendChild(path); - var text = document.createElementNS("http://www.w3.org/2000/svg", "text"); - //text.textContent=id; - poly.appendChild(text); - var x = (m2[0] + m1[0]) / 2; - var y = (m2[1] + m1[1]) / 2; - text.setAttribute("text-anchor", "middle"); - text.setAttribute("x", x); - text.setAttribute("y", y - 5); - text.style.cursor = "text"; - poly.style.cursor = "pointer"; - } else { - poly = document.createElement("v:Polyline"); - if (id != "") poly.id = id; - poly.filled = "false"; - strPath = sp[0] + "," + sp[1]; - if (m1[0] != sp[0] || m1[1] != sp[1]) - strPath += " " + m1[0] + "," + m1[1]; - if (m2[0] != ep[0] || m2[1] != ep[1]) - strPath += " " + m2[0] + "," + m2[1]; - strPath += " " + ep[0] + "," + ep[1]; - poly.points.value = strPath; - poly.setAttribute("fromTo", sp[0] + "," + sp[1] + "," + ep[0] + "," + ep[1]); - poly.strokeWeight = "1.2"; - poly.stroke.EndArrow = "Block"; - var text = document.createElement("div"); - //text.innerHTML=id; - poly.appendChild(text); - var x = (m2[0] - m1[0]) / 2; - var y = (m2[1] - m1[1]) / 2; - if (x < 0) x = x * -1; - if (y < 0) y = y * -1; - text.style.left = x + "px"; - text.style.top = y - 4 + "px"; - poly.style.cursor = "pointer"; - if (mark) poly.strokeColor = "#ff3300"; - else poly.strokeColor = "gray"; - } - return poly; - }, - //计算两个结点间要连直线的话,连线的开始坐标和结束坐标 - calcStartEnd: function(n1, n2) { - var X_1, Y_1, X_2, Y_2; - //X判断: - var x11 = n1.left, x12 = n1.left + n1.width, x21 = n2.left, x22 = n2.left + n2.width; - //结点2在结点1左边 - if (x11 >= x22) { - X_1 = x11; - X_2 = x22; - } - //结点2在结点1右边 - else if (x12 <= x21) { - X_1 = x12; - X_2 = x21; - } - //结点2在结点1水平部分重合 - else if (x11 <= x21 && x12 >= x21 && x12 <= x22) { - X_1 = (x12 + x21) / 2; - X_2 = X_1; - } else if (x11 >= x21 && x12 <= x22) { - X_1 = (x11 + x12) / 2; - X_2 = X_1; - } else if (x21 >= x11 && x22 <= x12) { - X_1 = (x21 + x22) / 2; - X_2 = X_1; - } else if (x11 <= x22 && x12 >= x22) { - X_1 = (x11 + x22) / 2; - X_2 = X_1; - } - - //Y判断: - var y11 = n1.top, y12 = n1.top + n1.height, y21 = n2.top, y22 = n2.top + n2.height; - //结点2在结点1上边 - if (y11 >= y22) { - Y_1 = y11; - Y_2 = y22; - } - //结点2在结点1下边 - else if (y12 <= y21) { - Y_1 = y12; - Y_2 = y21; - } - //结点2在结点1垂直部分重合 - else if (y11 <= y21 && y12 >= y21 && y12 <= y22) { - Y_1 = (y12 + y21) / 2; - Y_2 = Y_1; - } else if (y11 >= y21 && y12 <= y22) { - Y_1 = (y11 + y12) / 2; - Y_2 = Y_1; - } else if (y21 >= y11 && y22 <= y12) { - Y_1 = (y21 + y22) / 2; - Y_2 = Y_1; - } else if (y11 <= y22 && y12 >= y22) { - Y_1 = (y11 + y22) / 2; - Y_2 = Y_1; - } - return { "start": [X_1, Y_1], "end": [X_2, Y_2] }; - }, - //计算两个结点间要连折线的话,连线的所有坐标 - calcPolyPoints: function(n1, n2, type, M) { - //开始/结束两个结点的中心 - var SP = { x: n1.left + n1.width / 2, y: n1.top + n1.height / 2 }; - var EP = { x: n2.left + n2.width / 2, y: n2.top + n2.height / 2 }; - var sp = [], m1 = [], m2 = [], ep = []; - //如果是允许中段可左右移动的折线,则参数M为可移动中段线的X坐标 - //粗略计算起始点 - sp = [SP.x, SP.y]; - ep = [EP.x, EP.y]; - if (type == "lr") { - //粗略计算2个中点 - m1 = [M, SP.y]; - m2 = [M, EP.y]; - //再具体分析修改开始点和中点1 - if (m1[0] > n1.left && m1[0] < n1.left + n1.width) { - m1[1] = (SP.y > EP.y ? n1.top : n1.top + n1.height); - sp[0] = m1[0]; - sp[1] = m1[1]; - } else { - sp[0] = (m1[0] < n1.left ? n1.left : n1.left + n1.width) - } - //再具体分析中点2和结束点 - if (m2[0] > n2.left && m2[0] < n2.left + n2.width) { - m2[1] = (SP.y > EP.y ? n2.top + n2.height : n2.top); - ep[0] = m2[0]; - ep[1] = m2[1]; - } else { - ep[0] = (m2[0] < n2.left ? n2.left : n2.left + n2.width) - } - } - //如果是允许中段可上下移动的折线,则参数M为可移动中段线的Y坐标 - else if (type == "tb") { - //粗略计算2个中点 - m1 = [SP.x, M]; - m2 = [EP.x, M]; - //再具体分析修改开始点和中点1 - if (m1[1] > n1.top && m1[1] < n1.top + n1.height) { - m1[0] = (SP.x > EP.x ? n1.left : n1.left + n1.width); - sp[0] = m1[0]; - sp[1] = m1[1]; - } else { - sp[1] = (m1[1] < n1.top ? n1.top : n1.top + n1.height) - } - //再具体分析中点2和结束点 - if (m2[1] > n2.top && m2[1] < n2.top + n2.height) { - m2[0] = (SP.x > EP.x ? n2.left + n2.width : n2.left); - ep[0] = m2[0]; - ep[1] = m2[1]; - } else { - ep[1] = (m2[1] < n2.top ? n2.top : n2.top + n2.height); - } - } - return { start: sp, m1: m1, m2: m2, end: ep }; - }, - //初始化折线中段的X/Y坐标,mType='rb'时为X坐标,mType='tb'时为Y坐标 - getMValue: function(n1, n2, mType) { - if (mType == "lr") { - return (n1.left + n1.width / 2 + n2.left + n2.width / 2) / 2; - } else if (mType == "tb") { - return (n1.top + n1.height / 2 + n2.top + n2.height / 2) / 2; - } - }, - //增加一条线 - addLine: function(id, json) { - if (this.onItemAdd != null && !this.onItemAdd(id, "line", json)) return; - if (this.$undoStack && this.$editable) { - this.pushOper("delLine", [id]); - } - var n1 = null, n2 = null; //获取开始/结束结点的数据 - if (json.from == json.to) return; - //避免两个节点间不能有一条以上同向接连线 - for (var k in this.$lineData) { - if ((json.from == this.$lineData[k].from && json.to == this.$lineData[k].to)) - return; - } - var n1 = this.$nodeData[json.from], n2 = this.$nodeData[json.to]; //获取开始/结束结点的数据 - if (!n1 || !n2) return; - var res; - if (json.type && json.type != "sl") - res = GooFlow.prototype.calcPolyPoints(n1, n2, json.type, json.M); - else - res = GooFlow.prototype.calcStartEnd(n1, n2); - if (!res) return; - this.$lineData[id] = {}; - this.$lineData[id].setInfo = json.setInfo; - this.$lineData[id].id = json.id; - if (json.type) { - this.$lineData[id].type = json.type; - this.$lineData[id].M = json.M; - } else this.$lineData[id].type = "sl"; //默认为直线 - this.$lineData[id].from = json.from; - this.$lineData[id].to = json.to; - this.$lineData[id].name = json.name; - if (json.mark) this.$lineData[id].marked = json.mark; - else this.$lineData[id].marked = false; - - if (this.$lineData[id].type == "sl") - this.$lineDom[id] = GooFlow.prototype.drawLine(id, res.start, res.end, json.mark); - else - this.$lineDom[id] = GooFlow.prototype.drawPoly(id, res.start, res.m1, res.m2, res.end, json.mark); - this.$draw.appendChild(this.$lineDom[id]); - if (GooFlow.prototype.useSVG == "") { - this.$lineDom[id].childNodes[1].innerHTML = json.name; - if (this.$lineData[id].type != "sl") { - var Min = (res.start[0] > res.end[0] ? res.end[0] : res.start[0]); - if (Min > res.m2[0]) Min = res.m2[0]; - if (Min > res.m1[0]) Min = res.m1[0]; - this.$lineDom[id].childNodes[1].style.left = (res.m2[0] + res.m1[0]) / 2 - - Min - - this.$lineDom[id].childNodes[1].offsetWidth / 2 + - 4; - Min = (res.start[1] > res.end[1] ? res.end[1] : res.start[1]); - if (Min > res.m2[1]) Min = res.m2[1]; - if (Min > res.m1[1]) Min = res.m1[1]; - this.$lineDom[id].childNodes[1].style.top = (res.m2[1] + res.m1[1]) / 2 - - Min - - this.$lineDom[id].childNodes[1].offsetHeight / 2; - } else - this.$lineDom[id].childNodes[1].style.left = - ((res.end[0] - res.start[0]) * (res.end[0] > res.start[0] ? 1 : -1) - - this.$lineDom[id].childNodes[1].offsetWidth) / - 2 + - 4; - } else this.$lineDom[id].childNodes[2].textContent = json.name; - ++this.$lineCount; - if (this.$editable) { - this.$lineData[id].alt = true; - if (this.$deletedItem[id]) delete this.$deletedItem[id]; //在回退删除操作时,去掉该元素的删除记录 - } - }, - //重构所有连向某个结点的线的显示,传参结构为$nodeData数组的一个单元结构 - resetLines: function(id, node) { - for (var i in this.$lineData) { - var other = null; //获取结束/开始结点的数据 - var res; - if (this.$lineData[i].from == id) { //找结束点 - other = this.$nodeData[this.$lineData[i].to] || null; - if (other == null) continue; - if (this.$lineData[i].type == "sl") - res = GooFlow.prototype.calcStartEnd(node, other); - else - res = GooFlow.prototype.calcPolyPoints(node, - other, - this.$lineData[i].type, - this.$lineData[i].M) - if (!res) break; - } else if (this.$lineData[i].to == id) { //找开始点 - other = this.$nodeData[this.$lineData[i].from] || null; - if (other == null) continue; - if (this.$lineData[i].type == "sl") - res = GooFlow.prototype.calcStartEnd(other, node); - else - res = GooFlow.prototype.calcPolyPoints(other, - node, - this.$lineData[i].type, - this.$lineData[i].M); - if (!res) break; - } - if (other == null) continue; - this.$draw.removeChild(this.$lineDom[i]); - if (this.$lineData[i].type == "sl") { - this.$lineDom[i] = GooFlow.prototype.drawLine(i, res.start, res.end, this.$lineData[i].marked); - } else { - this.$lineDom[i] = - GooFlow.prototype.drawPoly(i, res.start, res.m1, res.m2, res.end, this.$lineData[i].marked); - } - this.$draw.appendChild(this.$lineDom[i]); - if (GooFlow.prototype.useSVG == "") { - this.$lineDom[i].childNodes[1].innerHTML = this.$lineData[i].name; - if (this.$lineData[i].type != "sl") { - var Min = (res.start[0] > res.end[0] ? res.end[0] : res.start[0]); - if (Min > res.m2[0]) Min = res.m2[0]; - if (Min > res.m1[0]) Min = res.m1[0]; - this.$lineDom[i].childNodes[1].style.left = (res.m2[0] + res.m1[0]) / 2 - - Min - - this.$lineDom[i].childNodes[1].offsetWidth / 2 + - 4; - Min = (res.start[1] > res.end[1] ? res.end[1] : res.start[1]); - if (Min > res.m2[1]) Min = res.m2[1]; - if (Min > res.m1[1]) Min = res.m1[1]; - this.$lineDom[i].childNodes[1].style.top = (res.m2[1] + res.m1[1]) / 2 - - Min - - this.$lineDom[i].childNodes[1].offsetHeight / 2 - - 4; - } else - this.$lineDom[i].childNodes[1].style.left = - ((res.end[0] - res.start[0]) * (res.end[0] > res.start[0] ? 1 : -1) - - this.$lineDom[i].childNodes[1].offsetWidth) / - 2 + - 4; - } else this.$lineDom[i].childNodes[2].textContent = this.$lineData[i].name; - } - }, - //重新设置连线的样式 newType= "sl":直线, "lr":中段可左右移动型折线, "tb":中段可上下移动型折线 - setLineType: function(id, newType) { - if (!newType || newType == null || newType == "" || newType == this.$lineData[id].type) return false; - if (this.onLineSetType != null && !this.onLineSetType(id, newType)) return; - if (this.$undoStack) { - var paras = [id, this.$lineData[id].type]; - this.pushOper("setLineType", paras); - if (this.$lineData[id].type != "sl") { - var para2 = [id, this.$lineData[id].M]; - this.pushOper("setLineM", para2); - } - } - var from = this.$lineData[id].from; - var to = this.$lineData[id].to; - this.$lineData[id].type = newType; - var res; - //如果是变成折线 - if (newType != "sl") { - var res = GooFlow.prototype.calcPolyPoints(this.$nodeData[from], - this.$nodeData[to], - this.$lineData[id].type, - this.$lineData[id].M); - this.setLineM(id, this.getMValue(this.$nodeData[from], this.$nodeData[to], newType), true); - } - //如果是变回直线 - else { - delete this.$lineData[id].M; - this.$lineMove.hide().removeData("type").removeData("tid"); - res = GooFlow.prototype.calcStartEnd(this.$nodeData[from], this.$nodeData[to]); - if (!res) return; - this.$draw.removeChild(this.$lineDom[id]); - this.$lineDom[id] = GooFlow.prototype.drawLine(id, - res.start, - res.end, - this.$lineData[id].marked || this.$focus == id); - this.$draw.appendChild(this.$lineDom[id]); - if (GooFlow.prototype.useSVG == "") { - this.$lineDom[id].childNodes[1].innerHTML = this.$lineData[id].name; - this.$lineDom[id].childNodes[1].style.left = - ((res.end[0] - res.start[0]) * (res.end[0] > res.start[0] ? 1 : -1) - - this.$lineDom[id].childNodes[1].offsetWidth) / - 2 + - 4; - } else - this.$lineDom[id].childNodes[2].textContent = this.$lineData[id].name; - } - if (this.$focus == id) { - this.focusItem(id); - } - if (this.$editable) { - this.$lineData[id].alt = true; - } - }, - //设置折线中段的X坐标值(可左右移动时)或Y坐标值(可上下移动时) - setLineM: function(id, M, noStack) { - if (!this.$lineData[id] || M < 0 || !this.$lineData[id].type || this.$lineData[id].type == "sl") - return false; - if (this.onLineMove != null && !this.onLineMove(id, M)) return false; - if (this.$undoStack && !noStack) { - var paras = [id, this.$lineData[id].M]; - this.pushOper("setLineM", paras); - } - var from = this.$lineData[id].from; - var to = this.$lineData[id].to; - this.$lineData[id].M = M; - var ps = GooFlow.prototype.calcPolyPoints(this.$nodeData[from], - this.$nodeData[to], - this.$lineData[id].type, - this.$lineData[id].M); - this.$draw.removeChild(this.$lineDom[id]); - this.$lineDom[id] = GooFlow.prototype.drawPoly(id, - ps.start, - ps.m1, - ps.m2, - ps.end, - this.$lineData[id].marked || this.$focus == id); - this.$draw.appendChild(this.$lineDom[id]); - if (GooFlow.prototype.useSVG == "") { - this.$lineDom[id].childNodes[1].innerHTML = this.$lineData[id].name; - var Min = (ps.start[0] > ps.end[0] ? ps.end[0] : ps.start[0]); - if (Min > ps.m2[0]) Min = ps.m2[0]; - if (Min > ps.m1[0]) Min = ps.m1[0]; - this.$lineDom[id].childNodes[1].style.left = (ps.m2[0] + ps.m1[0]) / 2 - - Min - - this.$lineDom[id].childNodes[1].offsetWidth / 2 + - 4; - Min = (ps.start[1] > ps.end[1] ? ps.end[1] : ps.start[1]); - if (Min > ps.m2[1]) Min = ps.m2[1]; - if (Min > ps.m1[1]) Min = ps.m1[1]; - this.$lineDom[id].childNodes[1].style.top = (ps.m2[1] + ps.m1[1]) / 2 - - Min - - this.$lineDom[id].childNodes[1].offsetHeight / 2 - - 4; - } else this.$lineDom[id].childNodes[2].textContent = this.$lineData[id].name; - if (this.$editable) { - this.$lineData[id].alt = true; - } - }, - //删除转换线 - delLine: function(id) { - if (!this.$lineData[id]) return; - if (this.onItemDel != null && !this.onItemDel(id, "node")) return; - if (this.$undoStack) { - var paras = [id, this.$lineData[id]]; - this.pushOper("addLine", paras); - } - this.$draw.removeChild(this.$lineDom[id]); - delete this.$lineData[id]; - delete this.$lineDom[id]; - if (this.$focus == id) this.$focus = ""; - --this.$lineCount; - if (this.$editable) { - //在回退新增操作时,如果节点ID以this.$id+"_line_"开头,则表示为本次编辑时新加入的节点,这些节点的删除不用加入到$deletedItem中 - if (id.indexOf(this.$id + "_line_") < 0) - this.$deletedItem[id] = "line"; - } - this.$lineOper.hide(); - }, - //用颜色标注/取消标注一个结点或转换线,常用于显示重点或流程的进度。 - //这是一个在编辑模式中无用,但是在纯浏览模式中非常有用的方法,实际运用中可用于跟踪流程的进度。 - markItem: function(id, type, mark) { - if (type == "node") { - if (!this.$nodeData[id]) return; - if (this.onItemMark != null && !this.onItemMark(id, "node", mark)) return; - this.$nodeData[id].marked = mark || false; - if (mark) this.$nodeDom[id].addClass("item_mark"); - else this.$nodeDom[id].removeClass("item_mark"); - - } else if (type == "line") { - if (!this.$lineData[id]) return; - if (this.onItemMark != null && !this.onItemMark(id, "line", mark)) return; - this.$lineData[id].marked = mark || false; - if (GooFlow.prototype.useSVG != "") { - if (mark) { - this.$nodeDom[id].childNodes[1].setAttribute("stroke", "#ff3300"); - this.$nodeDom[id].childNodes[1].setAttribute("marker-end", "url(#arrow2)"); - } else { - this.$nodeDom[id].childNodes[1].setAttribute("stroke", "gray"); - this.$nodeDom[id].childNodes[1].setAttribute("marker-end", "url(#arrow1)"); - } - } else { - if (mark) this.$nodeDom[id].strokeColor = "#ff3300"; - else this.$nodeDom[id].strokeColor = "gray" - } - } - if (this.$undoStatck) { - var paras = [id, type, !mark]; - this.pushOper("markItem", paras); - } - }, - ////////////////////////以下为区域分组块操作 - moveArea: function(id, left, top) { - if (!this.$areaData[id]) return; - if (this.onItemMove != null && !this.onItemMove(id, "area", left, top)) return; - if (this.$undoStack) { - var paras = [id, this.$areaData[id].left, this.$areaData[id].top]; - this.pushOper("moveNode", paras); - } - if (left < 0) left = 0; - if (top < 0) top = 0; - $("#" + id).css({ left: left + "px", top: top + "px" }); - this.$areaData[id].left = left; - this.$areaData[id].top = top; - if (this.$editable) { - this.$areaData[id].alt = true; - } - }, - //删除区域分组 - delArea: function(id) { - if (!this.$areaData[id]) return; - if (this.$undoStack) { - var paras = [id, this.$areaData[id]]; - this.pushOper("addArea", paras); - } - if (this.onItemDel != null && !this.onItemDel(id, "node")) return; - delete this.$areaData[id]; - this.$areaDom[id].remove(); - delete this.$areaDom[id]; - --this.$areaCount; - if (this.$editable) { - //在回退新增操作时,如果节点ID以this.$id+"_area_"开头,则表示为本次编辑时新加入的节点,这些节点的删除不用加入到$deletedItem中 - if (id.indexOf(this.$id + "_area_") < 0) - this.$deletedItem[id] = "area"; - } - }, - //设置区域分组的颜色 - setAreaColor: function(id, color) { - if (!this.$areaData[id]) return; - if (this.$undoStack) { - var paras = [id, this.$areaData[id].color]; - this.pushOper("setAreaColor", paras); - } - if (color == "red" || color == "yellow" || color == "blue" || color == "green") { - this.$areaDom[id].removeClass("area_" + this.$areaData[id].color).addClass("area_" + color); - this.$areaData[id].color = color; - } - if (this.$editable) { - this.$areaData[id].alt = true; - } - }, - //设置区域分块的尺寸 - resizeArea: function(id, width, height) { - if (!this.$areaData[id]) return; - if (this.onItemResize != null && !this.onItemResize(id, "area", width, height)) return; - if (this.$undoStack) { - var paras = [id, this.$areaData[id].width, this.$areaData[id].height]; - this.pushOper("resizeArea", paras); - } - var hack = 0; - if (navigator.userAgent.indexOf("8.0") != -1) hack = 2; - this.$areaDom[id].children(".bg").css({ width: width - 2 + "px", height: height - 2 + "px" }); - width = this.$areaDom[id].outerWidth(); - height = this.$areaDom[id].outerHeight(); - this.$areaDom[id].children("bg").css({ width: width - 2 + "px", height: height - 2 + "px" }); - this.$areaData[id].width = width; - this.$areaData[id].height = height; - if (this.$editable) { - this.$areaData[id].alt = true; - } - }, - addArea: function(id, json) { - if (this.onItemAdd != null && !this.onItemAdd(id, "area", json)) return; - if (this.$undoStack && this.$editable) { - this.pushOper("delArea", [id]); - } - this.$areaDom[id] = $("
" + - "
"); - this.$areaData[id] = json; - this.$group.append(this.$areaDom[id]); - if (this.$nowType != "group") this.$areaDom[id].children("div:eq(1)").css("display", "none"); - ++this.$areaCount; - if (this.$editable) { - this.$areaData[id].alt = true; - if (this.$deletedItem[id]) delete this.$deletedItem[id]; //在回退删除操作时,去掉该元素的删除记录 - } - }, - //重构整个流程图设计器的宽高 - reinitSize: function(width, height) { - var w = (width || 800) - 2; - var h = (height || 500) - 2; - this.$bgDiv.css({ height: h + "px", width: w + "px" }); - var headHeight = 0, hack = 10; - if (this.$head != null) { - headHeight = 24; - hack = 7; - } - if (this.$tool != null) { - this.$tool.css({ height: h - headHeight - hack + "px" }); - } - w -= 39; - h = h - headHeight - (this.$head != null ? 5 : 8); - this.$workArea.parent().css({ height: h + "px", width: w + "px" }); - this.$workArea.css({ height: h * 3 + "px", width: w * 3 + "px" }); - if (GooFlow.prototype.useSVG == "") { - this.$draw.coordsize = w * 3 + "," + h * 3; - } - this.$draw.style.width = w * 3 + "px"; - this.$draw.style.height = +h * 3 + "px"; - if (this.$group == null) { - this.$group.css({ height: h * 3 + "px", width: w * 3 + "px" }); - } - } - } - //将此类的构造函数加入至JQUERY对象中 - jQuery.extend({ - createGooFlow: function(bgDiv, property) { - return new GooFlow(bgDiv, property); - } - }); - - //获取一个DIV的绝对坐标的功能函数,即使是非绝对定位,一样能获取到 - function getElCoordinate(dom) { - var t = dom.offsetTop; - var l = dom.offsetLeft; - dom = dom.offsetParent; - while (dom) { - t += dom.offsetTop; - l += dom.offsetLeft; - dom = dom.offsetParent; - }; - return { - top: t, - left: l - }; - } - - //兼容各种浏览器的,获取鼠标真实位置 - function mousePosition(ev) { - if (!ev) ev = window.event; - if (ev.pageX || ev.pageY) { - return { x: ev.pageX, y: ev.pageY }; - } - return { - x: ev.clientX + document.documentElement.scrollLeft - document.body.clientLeft, - y: ev.clientY + document.documentElement.scrollTop - document.body.clientTop - }; - } - - exports('flow-ui/gooflow'); - }); - diff --git a/OpenAuth.Mvc/js/flow-ui/img/1.png b/OpenAuth.Mvc/js/flow-ui/img/1.png deleted file mode 100644 index 5dfd0b95..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/1.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/10.png b/OpenAuth.Mvc/js/flow-ui/img/10.png deleted file mode 100644 index b6d6de78..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/10.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/11.png b/OpenAuth.Mvc/js/flow-ui/img/11.png deleted file mode 100644 index dff3ef2b..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/11.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/2.png b/OpenAuth.Mvc/js/flow-ui/img/2.png deleted file mode 100644 index 07c94382..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/2.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/3.png b/OpenAuth.Mvc/js/flow-ui/img/3.png deleted file mode 100644 index a6061cbf..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/3.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/4.png b/OpenAuth.Mvc/js/flow-ui/img/4.png deleted file mode 100644 index dbeffe45..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/4.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/5.png b/OpenAuth.Mvc/js/flow-ui/img/5.png deleted file mode 100644 index 12209903..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/5.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/6.png b/OpenAuth.Mvc/js/flow-ui/img/6.png deleted file mode 100644 index e1e26c63..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/6.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/7.png b/OpenAuth.Mvc/js/flow-ui/img/7.png deleted file mode 100644 index 3dfb1234..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/7.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/9.png b/OpenAuth.Mvc/js/flow-ui/img/9.png deleted file mode 100644 index bea67686..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/9.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/GooFlow_line_oper.png b/OpenAuth.Mvc/js/flow-ui/img/GooFlow_line_oper.png deleted file mode 100644 index b0d013cb..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/GooFlow_line_oper.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_bg.png b/OpenAuth.Mvc/js/flow-ui/img/gooflow_bg.png deleted file mode 100644 index fd2f44d4..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_bg.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank.gif b/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank.gif deleted file mode 100644 index d29c4d70..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank.gif and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank2.gif b/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank2.gif deleted file mode 100644 index 432177d0..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank2.gif and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank3.gif b/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank3.gif deleted file mode 100644 index 94b25f95..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_blank3.gif and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_btn_bg.png b/OpenAuth.Mvc/js/flow-ui/img/gooflow_btn_bg.png deleted file mode 100644 index c976eb87..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_btn_bg.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_bullet.png b/OpenAuth.Mvc/js/flow-ui/img/gooflow_bullet.png deleted file mode 100644 index b84caa5f..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_bullet.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_icon2.png b/OpenAuth.Mvc/js/flow-ui/img/gooflow_icon2.png deleted file mode 100644 index 173fe010..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_icon2.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/gooflow_tip.png b/OpenAuth.Mvc/js/flow-ui/img/gooflow_tip.png deleted file mode 100644 index 4d62fc3c..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/gooflow_tip.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow-ui/img/ui_close.png b/OpenAuth.Mvc/js/flow-ui/img/ui_close.png deleted file mode 100644 index 06589596..00000000 Binary files a/OpenAuth.Mvc/js/flow-ui/img/ui_close.png and /dev/null differ diff --git a/OpenAuth.Mvc/js/flow/GooFlow.css b/OpenAuth.Mvc/js/flow/GooFlow.css new file mode 100644 index 00000000..0c96bc8c --- /dev/null +++ b/OpenAuth.Mvc/js/flow/GooFlow.css @@ -0,0 +1,195 @@ +v\:group,v\:rect,v\:imagedata,v\:oval,v\:line,v\:polyline,v\:stroke,v\:textbox { display:inline-block;background:transparent } +::-ms-clear,::-ms-reveal{display:none;} +/*总体样式*/ +.GooFlow{ + background:#f1f1f1;border:#ddd 1px solid;position:relative; + -moz-user-select:none;-webkit-user-select:none;border-radius:4px;color:#333 +} +.GooFlow,.GooFlow *{ + -webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box; font-size:14px;line-height:1.42857143; + font-family: "Microsoft Yahei", "Helvetica Neue", Helvetica, Hiragino Sans GB, WenQuanYi Micro Hei, Arial, sans-serif; +} +.GooFlow:before,.GooFlow:after,.GooFlow *:before,.GooFlow *:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} +.GooFlow i{ + display:block;width:18px;height:18px;overflow:hidden;font-size:18px;color:#777;text-align:center;margin:0 auto; + filter:Alpha(Opacity=70);-moz-opacity:0.7;opacity: 0.7;text-shadow:0.5px 0 #fff,0 0.5px #fff;line-height:1; +} +.GooFlow a.a_disabled,.GooFlow a.a_disabled:hover {border:0 !important;padding:4px 6px;background: transparent !important; cursor: not-allowed !important;} +.GooFlow a.a_disabled i:before{color:#ccc !important;} +/*绘图区的样式*/ +.GooFlow_work{position:absolute;top:3px;right:3px;bottom:3px;left:3px;overflow:auto;background-color:#fff;} +.GooFlow_work .GooFlow_work_inner{ + /*background: -webkit-linear-gradient(top, transparent 11px, #e3e3e3 12px),-webkit-linear-gradient(left, transparent 11px, #e3e3e3 12px);*/ + /*background: -moz-linear-gradient(top, transparent 11px, #e3e3e3 12px),-moz-linear-gradient(left, transparent 11px, #e3e3e3 12px);*/ + /*background: -o-linear-gradient(top, transparent 11px, #e3e3e3 12px),-o-linear-gradient(left, transparent 11px, #e3e3e3 12px);*/ + /*background: -ms-linear-gradient(top, transparent 11px, #e3e3e3 12px),-ms-linear-gradient(left, transparent 11px, #e3e3e3 12px);*/ + /*background: linear-gradient(top, transparent 11px, #e3e3e3 12px),linear-gradient(left, transparent 11px, #e3e3e3 12px);*/ + /*-webkit-background-size: 12px 12px; -moz-background-size: 12px 12px; background-size: 12px 12px;*/ + position:relative;overflow:hidden; background-image:url(data:image/gif;base64,R0lGODlhDAAMAJEAAOrq6v////Hx8QAAACH5BAAHAP8ALAAAAAAMAAwAAAIWjI8hycvonomSPtvkwYlDPQniSApAAQA7); +} +/*与矢量线有关的样式*/ +.GooFlow_work text{color:#fff;font-size:14px;line-height:1.42857143; + font-family: "Microsoft Yahei", "Helvetica Neue", Helvetica, Hiragino Sans GB, WenQuanYi Micro Hei, Arial, sans-serif;} + +/*顶部栏的样式*/ +.GooFlow_head{clear:both;height:28px;border-bottom:#00B4E1 2px solid;margin-left:-1px} +.GooFlow_head label{ + font-weight:bold;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:27px;padding:3px;width:176px; + background:#00B4E1;float:left;color:#fff;border-radius:3px 0 0 0;overflow:hidden;margin:-1px 4px 0 0;text-align:center; +} +.GooFlow_head_btn{display:block;border:0;height:26px;width:30px;cursor:default;padding:4px 6px;margin:0 2px;float:left;outline:none;blr:expression(this.onFocus=this.blur());text-decoration:none;cursor:pointer} +.GooFlow_head_btn i{display:inline-block;overflow:hidden;width:18px;height:18px;border:0;font-size:16px;line-height:18px;} +.GooFlow_head_btn:hover{background:#fff;padding:4px 5px;border-left:#ddd 1px solid;border-right:#ddd 1px solid} + +/*左侧绘图工具栏的样式*/ +.GooFlow_tool{float:left;clear:left;border-right:#ddd 1px solid;margin-left:-1px;} +.GooFlow_tool_div{width:34px;padding:4px 0;overflow:hidden;margin-right:-1px;} +.GooFlow_tool span{height:0;overflow:hidden;border-top:#ddd 1px solid;border-bottom:#fff 1px solid;margin:0 2px;clear:both;display:block;} +.GooFlow_tool_btn{display:block;border:0;height:34px;width:34px;cursor:default;padding:8px;outline:none;blr:expression(this.onFocus=this.blur());color:#777;text-decoration:none;cursor:pointer} +.GooFlow_tool_btn i{display:block;overflow:hidden;width:18px;height:18px;border:0} +.GooFlow_tool_btn:hover{border:#ddd 1px solid;background:#fff;padding:7px} +.GooFlow_tool_btndown{ + cursor:default;outline:none;blr:expression(this.onFocus=this.blur());height:34px;width:36px;margin:0 -1px; + padding:8px 9px;background:#00B4E1;/*#FFBF00*/display:block;text-decoration:none;filter:Alpha(Opacity=70);-moz-opacity:0.7;opacity: 0.7; +} +.GooFlow_tool_btndown i{display:block;overflow:hidden;width:18px;height:18px;color:#000;filter:Alpha(Opacity=37);-moz-opacity:0.37;opacity: 0.37;position:relative} + +/*工作区扩展边栏样式*/ +.Gooflow_extend_right{position:absolute;z-index:10002;top:0;right:0;height:100%;width:14px;cursor:e-resize;filter:Alpha(Opacity=20);-moz-opacity:0.2;opacity: 0.2} +.Gooflow_extend_bottom{position:absolute;z-index:10002;bottom:0;left:0;width:100%;height:14px;cursor:s-resize;filter:Alpha(Opacity=20);-moz-opacity:0.2;opacity: 0.2} +.Gooflow_extend_right:hover{background-color:#999;border:#fff 1px solid} +.Gooflow_extend_bottom:hover{background-color:#999;border:#fff 1px solid} + +/*区域分组(泳道)的样式*/ +.GooFlow_work_group{cursor:default;position:absolute;overflow:hidden;top:0;left:0} +.GooFlow_area{cursor:default;position:absolute;overflow:hidden;} +.GooFlow_area .lock{cursor:default;} +.GooFlow_area .bg{cursor:move;filter:Alpha(Opacity=30);-moz-opacity:0.3;opacity: 0.3;} +.GooFlow_area.lock .bg{cursor:default;} +.GooFlow_area label{cursor:text;top:0;left:23px;position:absolute;display:block;} +.GooFlow_area.lock label{cursor:default;} +.GooFlow_area i{top:2px;left:2px;width:18px;height:20px;position:absolute;cursor:pointer;} +.GooFlow_area i:before{content:"\e6bd"} +.GooFlow_area.area_red .bg{border:1px solid red;background-color:#FF7865} +.GooFlow_area.area_red label,.GooFlow_area.area_red i{color:red;} +.GooFlow_area.area_yellow .bg{border:1px solid #CD925A;background-color:#FFD564} +.GooFlow_area.area_yellow label,.GooFlow_area.area_yellow i{color:#FFBA1D;} +.GooFlow_area.area_blue .bg{border:1px solid #347BB1;background-color:#549CDE} +.GooFlow_area.area_blue label,.GooFlow_area.area_blue i{color:#347BB1;} +.GooFlow_area.area_green .bg{border:1px solid green;background-color:#84CA04} +.GooFlow_area.area_green label,.GooFlow_area.area_green i{color:green;} + +/*画连线区域所需要的样式*/ +.GooFlow_work svg{display:block;position:absolute;top:0;left:0} +.GooFlow_work v\:group{position:relative;display:block} +.GooFlow_work v\:group v\:line{overflow:visible} +.GooFlow_work v\:group v\:polyline{overflow:visible} +.GooFlow_work v\:group div{cursor:text;position:absolute;overflow:visible;display:inline;float:left;white-space: nowrap} +.GooFlow_work .draw{color:#ff8800} + +/*各种节点样式*/ +.GooFlow_item{ + position:absolute;background:#A1DCEB;padding:1px; + border-radius:3px;background-color:#C1DCFC;box-shadow:1px 1px 2px rgba(99,99,99,2); +} +.GooFlow table{padding:1px 2px;border-radius:2px} +.GooFlow td,.GooFlow td div{ vertical-align:middle;text-align:center;padding:0;cursor:default;word-wrap:break-word;word-break:break-all} +.GooFlow .ico{width:18px;cursor:move;text-align:center; vertical-align: middle;} +.GooFlow .ico i{filter:Alpha(Opacity=30);-moz-opacity:0.3;opacity:0.3;color:#000;margin:0 auto;} + +.GooFlow .item_round{border-radius:13px; overflow:visible} +.GooFlow .item_round table{border:0;padding:3px;width:26px;height:26px} +.GooFlow .item_round .span{ + display:block;text-align:center; position:absolute;top:100%;left:-100%;width:300%;overflow:visible; + padding:0;cursor:default;word-wrap: break-word;word-break:break-all +} +.GooFlow .item_mix{background:#B6F700;color:#fff} +.GooFlow .item_focus{border:#3892D3 1px solid !important;padding:0;z-index:5} +.GooFlow .item_focus table{margin:0 !important;} +.GooFlow .item_focus.item_round .span{ + display:block;text-align:center; position:absolute;margin-top:1px;overflow:visible; + padding:0;cursor:default;word-wrap: break-word;word-break:break-all; +} +.GooFlow .item_mark{border:#ff8800 2px solid;padding:0} +.GooFlow .item_mark table{margin:-1px} +.GooFlow .item_mark td{cursor:crosshair} +.GooFlow .item_mark.item_round .span{padding-top:2px} + +/*编辑时一些工具的页面特效*/ +.GooFlow textarea{position:absolute;border:#3892D3 1px solid;display:none;overflow-y:visible;width:100px;z-index:10001} +.GooFlow div .rs_right{overflow:hidden;position:absolute;right:-1px;top:-1px;height:100%;width:6px;cursor:w-resize} +.GooFlow div .rs_bottom{overflow:hidden;position:absolute;left:-1px;bottom:-1px;width:100%;height:6px;cursor:n-resize} +.GooFlow div .rs_rb{ + position:absolute;right:-1px;bottom:0;width:10px;height:9px;filter:Alpha(Opacity=70);-moz-opacity:0.7;opacity:0.7; + font-family:"iconflow" !important;font-size:12px;color:#475669;line-height:1;overflow:hidden;cursor:pointer;cursor:nw-resize; +} +.GooFlow div .rs_rb:before{content:"\e6b7";} +.GooFlow div .rs_close{ + position:absolute;right:-1px;top:1px;width:10px;height:9px;filter:Alpha(Opacity=70);-moz-opacity:0.7;opacity:0.7; + font-family:"iconflow" !important;font-size:12px;color:#475669;line-height:1;overflow:hidden;cursor:pointer; +} +.GooFlow div .rs_close:before{content:"\e674";} +.GooFlow .rs_ghost{ + position:absolute;display:none;overflow:hidden;border:#8492A6 1px dashed; background:#E5E9F2; + filter:Alpha(Opacity=50);-moz-opacity:0.5;opacity: 0.5;z-index:10 +} +.GooFlow .GooFlow_line_oper{ + width:82px;height:20px;background:#E5E9F2;border:#8492A6 1px solid;position:absolute; + filter:Alpha(Opacity=50);-moz-opacity:0.5;opacity: 0.5;z-index:10000; +} +.GooFlow .GooFlow_line_mp{ + width:9px;height:9px;filter:Alpha(Opacity=40);-moz-opacity:0.4;opacity:0.4;overflow:hidden; + position:absolute;z-index:9999;background:#333;cursor:crosshair +} +.GooFlow_linemove{background-color:transparent;filter:Alpha(Opacity=50);-moz-opacity:0.5;opacity:0.5;overflow:hidden;position:absolute;z-index:9999;} +.GooFlow_line_oper i{display:inline-block;margin-left:2px;cursor:pointer;position:relative;} +.GooFlow .b_l1:before{content:"\e60d";color:#1F2D3D} +.GooFlow .b_l2:before{content:"\e60e";color:#1F2D3D} +.GooFlow .b_l3:before{content:"\e601";color:#1F2D3D} +.GooFlow .b_x:before{content:"\e61a";color:red} + + +/*以下为图标样式(固定大小18px*18px,矢量字体大小16px),用户可自定义扩展自己的新矢量图标字体,写法参照以下的内容*/ +@font-face {font-family: "iconflow"; + src: url('fonts/iconflow.eot?t=1494321407539'); /* IE9*/ + src: url('fonts/iconflow.eot?t=1494321407539#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/iconflow.woff?t=1494321407539') format('woff'), /* chrome, firefox */ + url('fonts/iconflow.ttf?t=1494321407539') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + url('fonts/iconflow.svg?t=1494321407539#iconflow') format('svg'); /* iOS 4.1- */ +} +.GooFlow_area i,.GooFlow .GooFlow_line_oper i,.GooFlow_tool i,.GooFlow_head i,.GooFlow_item .ico i{ + font-family:"iconflow" !important; + font-size:18px;line-height:20px; + font-style:normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + -moz-osx-font-smoothing: grayscale; +} +/*自带的一些节点矢量图标样式*/ +.GooFlow .ico_cursor:before{ content:"\e602"; } +.GooFlow .ico_start:before{ content:"\e700"; } +.GooFlow .ico_end:before{ content:"\e609"; } +.GooFlow .ico_fork:before{ content:"\e60c"; } +.GooFlow .ico_join:before{ content:"\e606"; } +.GooFlow .ico_direct:before{ content:"\e605"; } +.GooFlow .ico_dashed:before{ content:"\e675"; } +.GooFlow .ico_group:before{ content:"\e663"; } +.GooFlow .ico_complex:before{ content:"\e872"; } +/*.GooFlow .ico_complex{background:url(assets/img/gooflow_icon.png) no-repeat -116px -20px;opacity:1 !important;filter:Alpha(Opacity=70) !important;}*/ +.GooFlow .ico_node:before{ content:"\e678"; } +.GooFlow .ico_task:before{ content:"\e6af"; } +/*.GooFlow .ico_task{background:url(assets/img/gooflow_icon.png) no-repeat 2px -45px;opacity:1 !important;filter:Alpha(Opacity=70) !important;}*/ +.GooFlow .ico_chat:before{ content:"\e61b"; } +.GooFlow .ico_state:before{ content:"\e633"; } +.GooFlow .ico_plug:before{ content:"\e66c"; } +.GooFlow .ico_menu:before{ content:"\e649"; } +.GooFlow .ico_sound:before{ content:"\e62b"; } + +/*以下是内部用头部工具栏按钮专用的样式*/ +.GooFlow .ico_open:before{ content:"\e7a0";color:#FFD300 } +.GooFlow .ico_new:before{ content:"\e659"; } +.GooFlow .ico_reload:before{ content:"\e607";color:#669900 } +.GooFlow .ico_save:before{ content:"\e63d";color:#0099cc } +.GooFlow .ico_undo:before{ content:"\e673";color:#ff8800 } +.GooFlow .ico_redo:before{ content:"\e672";color:#ff8800 } +.GooFlow .ico_print:before{ content:"\e671"; } \ No newline at end of file diff --git a/OpenAuth.Mvc/js/flow/GooFlow.export.js b/OpenAuth.Mvc/js/flow/GooFlow.export.js new file mode 100644 index 00000000..52c77218 --- /dev/null +++ b/OpenAuth.Mvc/js/flow/GooFlow.export.js @@ -0,0 +1,427 @@ +/* + * 专门负责导出流程图文件并让用户下载的扩展包方法 + */ +;(function ( global, factory ) { + 'use strict'; + if ( typeof define !== 'undefined' && define.amd ) { // export as AMD... + define( ['jquery','GooFlow'], factory ); + } + else if ( typeof module !== 'undefined' && module.exports ) { // ...or as browserify + factory( require('jquery'), require('GooFlow') ); + }else + factory( global.$, global.GooFlow ); + +}( typeof window !== 'undefined' ? window : this, function ( $,GooFlow ) { + if(GooFlow.prototype.exportDiagram && typeof GooFlow.prototype.exportDiagram==='function'){ + return;//防止多次载入 + } + var Cmder = { + //构建背景 + initBg : function(width,height,bgColor){ + var canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + var ctx = canvas.getContext('2d'); + if(bgColor) ctx.fillStyle = bgColor; + ctx.fillRect(0,0,canvas.width,canvas.height); + ctx.save(); + return canvas; + }, + _toNum: function(str){ + return str!==null&&str!==''? parseInt(str.split('px')[0],10):undefined; + }, + _analyseLabel: function(labelDom){ + var tagName = labelDom[0].tagName; + var offsetLeft = labelDom[0].offsetLeft; + var offsetTop = labelDom[0].offsetTop; + if(tagName==='TD'){ + offsetLeft += labelDom.children("div")[0].offsetLeft; + offsetTop += labelDom.children("div")[0].offsetTop; + } + + var lineHeight = this._toNum(labelDom.css("line-height")); + var fontSize = labelDom.css('font-size'); + return { + font: fontSize+' '+labelDom.css('font-family'), + fontSize: this._toNum(fontSize.split("px")[0]), + text: labelDom.text(),//文字内容 + color: labelDom.css('color'),//文字颜色 + width: labelDom[0].offsetWidth,//文字容器宽度 + height: labelDom[0].offsetHeight,//文字容器高度 + lineHeight:lineHeight, + offsetLeft:offsetLeft, + offsetTop:offsetTop, + lineNum: Math.ceil(labelDom[0].offsetHeight/lineHeight)//文字要分几行? + }; + }, + _analyseIcon: function(iconDom){ + var bgImg = iconDom.css("background-image"); + var property={ + // top: this._toNum(iconDom[0].style.top),// + // left: this._toNum(iconDom[0].style.left),// + offsetLeft:iconDom[0].offsetLeft, + offsetTop:iconDom[0].offsetTop, + width: iconDom.width(), + height: iconDom.height() + }; + + if(bgImg && bgImg!=='none'){//CSS SPITE背景图式 + bgImg = bgImg.replace(/"/g,"").split("url(")[1]; + property.backgroundImage=bgImg.substr(0,bgImg.length-1);//图标背景图 + bgImg = iconDom.css("background-position").split(" "); + property.pX = parseFloat(bgImg[0].split("px")[0])*-1;//图标背景定位X + property.pY = parseFloat(bgImg[1].split("px")[0])*-1;//图标背景定位Y + }else{//矢量图标字体式 + $.extend(property,{ + font: iconDom.css('font-size')+' '+iconDom.css('font-family').split(' ')[0],//图标矢量字体库 + lineHeight : this._toNum(iconDom.css('line-height')),//图标矢量字体行高 + color: iconDom.css('color'),//图标矢量字体颜色 + opacity: parseFloat(iconDom.css("opacity")),//图标矢量透明度 + content:window.getComputedStyle(iconDom[0],'::before').getPropertyValue('content') + }); + } + + return property; + }, + _analyseArea : function(areaDom){ + var bg=areaDom.children(".bg"); + return { + top: this._toNum(areaDom[0].style.top), + left: this._toNum(areaDom[0].style.left), + width: areaDom.outerWidth(), + height: areaDom.outerHeight(), + borderColor: bg.css('border-top-color'),//区域边框颜色 + bgColor: bg.css('background-color'),//区域块背景色 + opacity: parseFloat(bg.css("opacity")),//区域块透明度 + icon: this._analyseIcon(areaDom.children('i')), + label: this._analyseLabel(areaDom.children("label")) + }; + }, + _analyseNode : function(nodeDom){ + var property={ + top: this._toNum(nodeDom[0].style.top),// + left: this._toNum(nodeDom[0].style.left),// + width: nodeDom.outerWidth(),// + height: nodeDom.outerHeight(),// + borderColor: nodeDom.css('border-top-color'),//节点边框颜色 + borderWidth: this._toNum(nodeDom.css('border-top-width')),//节点边框宽度 + bgColor: nodeDom.css('background-color'),//节点背景色 + borderRadius: this._toNum(nodeDom.css("border-top-left-radius")),//节点圆角半径 + boxShadow: nodeDom.css("box-shadow"),//节点阴影 + icon: this._analyseIcon(nodeDom.find('i')) + }; + if(nodeDom.hasClass("item_round")){ + property.label = this._analyseLabel(nodeDom.children(".span")); + }else{ + property.label = this._analyseLabel(nodeDom.children("table").find("td:eq(1)")); + } + return property; + }, + _fillIcon:function(canvas, bgLeft,bgTop,icon, bgImage){ + var ctx = canvas.getContext('2d'); + if(icon.backgroundImage===undefined){//矢量字体图标 + if(icon.content.indexOf('"')===0){ + icon.content = icon.content.split('"')[1]; + } + icon.color = icon.color.replace('rgb', 'rgba').replace(')', ', ' + icon.opacity + ')'); + ctx.fillStyle = icon.color; + ctx.font = icon.font; + ctx.textAlign='center'; + ctx.textBaseline='middle'; + // 绘制内容 + ctx.fillText(icon.content, bgLeft+icon.offsetLeft+4+icon.width/2, bgTop+icon.offsetTop+4+icon.height/2); + return null; + }else{//css spite背景定位图标 + var tmpX=0,tmpY=0; + if(icon.pX<0){ + tmpX-=icon.pX; icon.pX=0; + } + if(icon.pY<0){ + tmpY-=icon.pY; icon.pY=0; + } + //console.log(icon.pX+','+icon.pY); + ctx.drawImage(bgImage, icon.pX, icon.pY, icon.width, icon.height, + bgLeft+icon.offsetLeft+4+tmpX, bgTop+icon.offsetTop+4+tmpY, icon.width, icon.height ); + } + }, + _fillLabel: function(canvas, bgLeft, bgTop, label) { + var ctx = canvas.getContext('2d'); + ctx.fillStyle = label.color; + ctx.textAlign='center'; + ctx.font = label.font; + ctx.textBaseline='top'; + + var str=label.text; + var lineWidth = 0;//某一行字的实际宽度 + var lastSubStrIndex= 0; //每次开始截取的字符串的索引 + var hack = (window.ActiveXObject || "ActiveXObject" in window)? 1:0; + var x = bgLeft+label.offsetLeft+label.width/2+hack/2;//文字(可能有多行)的x坐标 + var y = bgTop+label.offsetTop+hack;//某一行文字(可能有多行)的y坐标 + if(navigator.userAgent.indexOf('Firefox')>=0){ + y += (label.lineHeight-label.fontSize); + } + for(var i=0;i= label.width ){ + ctx.fillText(str.substring(lastSubStrIndex,i),x,y);//绘制截取部分 + y+=label.lineHeight; + lineWidth=0; + lastSubStrIndex=i; + } + }else{//绘制剩余部分 + ctx.fillText(str.substring(lastSubStrIndex,i+1),x,y); + } + } + }, + //根据区域组信息在背景上画一堆区域组泳道(传参areas为要绘制的区域组详细json信息) + renderAreas:function(canvas,areas, iconBgImage){ + var ctx = canvas.getContext('2d'); + for(var key in areas) { + var area = areas[key]; + //填充半透明矩形 + area.bgColor = area.bgColor.replace('rgb', 'rgba').replace(')', ', ' + area.opacity + ')'); + area.borderColor = area.borderColor.replace('rgb', 'rgba').replace(')', ', ' + area.opacity + ')'); + ctx.fillStyle = area.bgColor; + ctx.strokeStyle = area.borderColor; + ctx.rect(area.left, area.top, area.width, area.height); + ctx.fill(); + ctx.stroke(); + this._fillIcon(canvas, area.left-3, area.top-3, area.icon, iconBgImage); + this._fillLabel(canvas, area.left, area.top, area.label); + } + }, + + //根据节点信息在背景上画一组节点(传参nodes为要绘制的节点详细json信息) + renderNodes:function(canvas,nodes,iconBgImage){ + var ctx = canvas.getContext('2d'); + var imgLoadFuncs=[]; + for(var key in nodes){ + var node = nodes[key]; + //渲染阴影 + var sd = node.boxShadow.split(") "); + if(sd.length===1){ + var tmp = node.boxShadow.split("rgba"); + sd[0]='rgba'+tmp[1]; + sd[1]=tmp[0]; + } + ctx.shadowColor = sd[0]; + sd=sd[1].split(" "); + ctx.shadowOffsetX=this._toNum(sd[0])+(node.borderWidth>1? 1:0); + ctx.shadowOffsetY=this._toNum(sd[1])+(node.borderWidth>1? 1:0); + ctx.shadowBlur=this._toNum(sd[2]); + //填充圆角矩形 + ctx.fillStyle=node.bgColor; + ctx.roundRect( node.left+node.borderWidth/2, node.top+node.borderWidth/2, + node.width-node.borderWidth, node.height-node.borderWidth, node.borderRadius).fill(); + //加边框 + ctx.shadowBlur=0; + ctx.shadowColor=''; + ctx.shadowOffsetX=0; + ctx.shadowOffsetY=0; + ctx.strokeStyle = node.borderColor; + ctx.lineWidth = (node.borderWidth===0? 0.01:node.borderWidth); + ctx.stroke(); + this._fillIcon(canvas, node.left, node.top+(node.borderRadius>6? 1:0), node.icon, iconBgImage); + this._fillLabel(canvas, node.left, node.top, node.label); + } + return imgLoadFuncs; + }, + + _analyseLine:function(lineDom){ //only for IE + var fontFamily = $(".GooFlow").css("font-family"); + //基本样式 + var path = lineDom.childNodes[1]; + var property={ + color: path.getAttribute("stroke"),//箭头则用fill + lineWidth: path.getAttribute("stroke-width"),//线条宽度箭头的strokeWidth为0 + lineCap: 'round' + }; + var style = path.style.strokeDasharray; + property.lineDash=(style && style!=null); + //文字 + var text=lineDom.childNodes[2]; + var fontColor = text.getAttribute("fill"); + if(!fontColor||fontColor===null||fontColor===''){ + fontColor='#777'; + } + property.label={ + text: text.textContent, + font: text.style.fontSize+' '+fontFamily, + color: fontColor, + left:text.getAttribute("x"), + top:text.getAttribute("y") + }; + + //获取连线从首至尾各个点的坐标值 + var d = path.getAttribute("d"); + var tmp = d.substring(2,d.length).split("L"); + var points=[];//连线中各点集合 + for(var i=0;i-1){//当为IE11及以下版本浏览器时,使用Canvg第三方工具 + var lineEl={}; + for(var key in Goo.$lineDom){ + lineEl[key]=Cmder._analyseLine(Goo.$lineDom[key]); + } + //console.log(lineEl); + Cmder.renderLines(canvas,lineEl); + try{ + var blob = canvas.msToBlob(); + navigator.msSaveBlob(blob, fileName+".png"); + } + catch(e){ + //生成一个下载链接并点击 + var base64 = canvas.toDataURL('image/png'); //将画布内的信息导出为png图片数据 + $('body').append(''); + var oPop=window.open("",'_blank'); + for (; oPop.document.readyState !== "complete";) { + if (oPop.document.readyState === "complete") break; + } + oPop.document.write(''+fileName+'.png'); + } + }else{ + var strSvg = '' + +'' + $("#draw_"+Goo.$id).html() +''; //COPY连线内容 + var image = new Image(); + image.src='data:image/svg+xml,'+ encodeURIComponent(strSvg); + image.onload=function(){ + ctx.drawImage(image, 0, 0); + var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); + a.href = canvas.toDataURL('image/png'); //将画布内的信息导出为png图片数据 + a.download = fileName+".png"; //设定下载名称 + document.body.appendChild(a); + a.click(); //点击触发下载 + document.body.removeChild(a); + }; + } + }; + // 如果图片已经存在于浏览器缓存,直接调用回调函数 + if(!iconImage || iconImage.complete|| (!!window.ActiveXObject||"ActiveXObject" in window) ) { + tempFunc(); + return;// 直接返回,不用再处理onload事件 + } + iconImage.onload=function(){ + tempFunc(); + }; + + } +})); \ No newline at end of file diff --git a/OpenAuth.Mvc/js/flow/GooFlow.js b/OpenAuth.Mvc/js/flow/GooFlow.js new file mode 100644 index 00000000..dd24ad12 --- /dev/null +++ b/OpenAuth.Mvc/js/flow/GooFlow.js @@ -0,0 +1,2514 @@ +/** + * Gooflow在线流程图设计器 + * Version: 1.3.2 + * Copyright: foolegg126(sdlddr) + */ + +layui.define("jquery", + function(exports) { + + var jQuery = layui.jquery; + var $ = layui.jquery; + + //预先定义几个公用方法 + //获取一个DIV的绝对坐标的功能函数,即使是非绝对定位,一样能获取到 + function _elCsys(dom) { + var t = dom.offsetTop; + var l = dom.offsetLeft; + dom=dom.offsetParent; + while (dom) { + t += dom.offsetTop; + l += dom.offsetLeft; + dom=dom.offsetParent; + } + return { top: t, left: l }; + } + //兼容各种浏览器的,获取鼠标真实位置 + function _mouseP(ev){ + if(!ev) ev=window.event; + if(ev.pageX || ev.pageY){ + return {x:ev.pageX, y:ev.pageY}; + } + return { + x:ev.clientX + document.documentElement.scrollLeft - document.body.clientLeft, + y:ev.clientY + document.documentElement.scrollTop - document.body.clientTop + }; + } + //计算两个结点间要连折线的话,连线的所有坐标 + function calcPolyPoints(n1,n2,type,M,scale){ + if(!scale) scale=1.0; + var N1={left:n1.left*scale, top:n1.top*scale, width:n1.width*scale, height:n1.height*scale}; + var N2={left:n2.left*scale, top:n2.top*scale, width:n2.width*scale, height:n2.height*scale}; + M=M*scale; + //开始/结束两个结点的中心 + var SP={x:N1.left+N1.width/2,y:N1.top+N1.height/2}; + var EP={x:N2.left+N2.width/2,y:N2.top+N2.height/2}; + var m1=[],m2=[],sp,ep; + //如果是允许中段可左右移动的折线,则参数M为可移动中段线的X坐标 + //粗略计算起始点 + sp=[SP.x,SP.y]; + ep=[EP.x,EP.y]; + if(type==="lr"){ + //粗略计算2个中点 + m1=[M,SP.y]; + m2=[M,EP.y]; + //再具体分析修改开始点和中点1 + if(m1[0]>N1.left&&m1[0]EP.y? N1.top:N1.top+N1.height); + sp[0]=m1[0];sp[1]=m1[1]; + } + else{ + sp[0]=(m1[0]N2.left&&m2[0]EP.y? N2.top+N2.height:N2.top); + ep[0]=m2[0];ep[1]=m2[1]; + } + else{ + ep[0]=(m2[0]N1.top&&m1[1]EP.x? N1.left:N1.left+N1.width); + sp[0]=m1[0];sp[1]=m1[1]; + } + else{ + sp[1]=(m1[1]N2.top&&m2[1]EP.x? N2.left+N2.width:N2.left); + ep[0]=m2[0];ep[1]=m2[1]; + } + else{ + ep[1]=(m2[1]=x22){ + X_1=x11;X_2=x22; + } + //结点2在结点1右边 + else if(x12<=x21){ + X_1=x12;X_2=x21; + } + //结点2在结点1水平部分重合 + else if(x11<=x21&&x12>=x21&&x12<=x22){ + X_1=(x12+x21)/2;X_2=X_1; + } + else if(x11>=x21&&x12<=x22){ + X_1=(x11+x12)/2;X_2=X_1; + } + else if(x21>=x11&&x22<=x12){ + X_1=(x21+x22)/2;X_2=X_1; + } + else if(x11<=x22&&x12>=x22){ + X_1=(x11+x22)/2;X_2=X_1; + } + + //Y判断: + var y11=n1.top*scale ,y12=n1.top*scale +n1.height*scale ,y21=n2.top*scale ,y22=n2.top*scale +n2.height*scale ; + //结点2在结点1上边 + if(y11>=y22){ + Y_1=y11;Y_2=y22; + } + //结点2在结点1下边 + else if(y12<=y21){ + Y_1=y12;Y_2=y21; + } + //结点2在结点1垂直部分重合 + else if(y11<=y21&&y12>=y21&&y12<=y22){ + Y_1=(y12+y21)/2;Y_2=Y_1; + } + else if(y11>=y21&&y12<=y22){ + Y_1=(y11+y12)/2;Y_2=Y_1; + } + else if(y21>=y11&&y22<=y12){ + Y_1=(y21+y22)/2;Y_2=Y_1; + } + else if(y11<=y22&&y12>=y22){ + Y_1=(y11+y22)/2;Y_2=Y_1; + } + return {"start":[X_1,Y_1],"end":[X_2,Y_2]}; + } + //初始化折线中段的X/Y坐标,mType='rb'时为X坐标,mType='tb'时为Y坐标 + function getMValue(n1,n2,mType,scale){ + if(!scale) scale=1.0; + if(mType==="lr"){ + return (n1.left*scale + n1.width*scale/2 + n2.left*scale + n2.width*scale/2 )/2; + } + else if(mType==="tb"){ + return (n1.top*scale + n1.height*scale/2 + n2.top*scale + n2.height*scale/2 )/2; + } + } +//构造类: +var GooFlow = function(selector,property){ + console.log('Your browser\'s navigator.userAgent is:',navigator.userAgent); + if (navigator.userAgent.indexOf("MSIE 8.0")>0||navigator.userAgent.indexOf("MSIE 7.0")>0||navigator.userAgent.indexOf("MSIE 6.0")>0) + GooFlow.prototype.useSVG=""; + else GooFlow.prototype.useSVG="1"; +//初始化区域图的对象 + this.$bgDiv=$(selector);//最父框架的DIV + this.$bgDiv.addClass("GooFlow"); + this.$id=this.$bgDiv.attr("id")||'GooFlow_'+new Date().getTime(); + if(property.colors && typeof property.colors ==='object'){ + $.extend(GooFlow.color, property.colors); + } + this.$bgDiv.css("color",GooFlow.color.font); + if(GooFlow.color.main){ + this.$bgDiv.append(''); + } + var width=(property.width||this.$bgDiv.width()); + var height=(property.height||this.$bgDiv.height()); + this.$bgDiv.css({width:width+"px",height:height+"px"}); + this.$tool=null;//左侧工具栏对象 + this.$head=null;//顶部标签及工具栏按钮 + this.$title="newFlow_1";//流程图的名称 + this.$nowType="cursor";//当前要绘制的对象类型 + this.$lineData={}; + this.$lineCount=0; + this.$nodeData={}; + this.$nodeCount=0; + this.$areaData={}; + this.$areaCount=0; + this.$lineDom={}; + this.$nodeDom={}; + this.$areaDom={}; + this.$max=property.initNum||1;//计算默认ID值的起始SEQUENCE + this.$focus="";//当前被选定的结点/转换线ID,如果没选中或者工作区被清空,则为"" + //this.$cursor="default";//鼠标指针在工作区内的样式 + this.$editable=false;//工作区是否可编辑 + this.$deletedItem={};//在流程图的编辑操作中被删除掉的元素ID集合,元素ID为KEY,元素类型(node,line.area)为VALUE + this.$workExtendStep=200;//在自动/手动扩展可编辑区时,一次扩展后宽/高增加多少像素 + this.$scale=1.00;//工作区内容的缩放比例,从0.1至无穷大,初始默认为1 + var headHeight=0; + var tmp="",titleText; + if(property.haveHead){ + tmp="
"; + if(property.headLabel){ + tmp+=""; + } + if(property.headBtns) + for(var x=0;x" + } + tmp+="
"; + this.$head=$(tmp); + this.$bgDiv.append(this.$head); + if(property.headBtns){ + this.$head.find(".ico_undo").parent().addClass("a_disabled"); + this.$head.find(".ico_redo").parent().addClass("a_disabled"); + //以下是当工具栏按钮被点击时触发的事件自定义(虚函数),格式为function(),因为可直接用THIS操作对象本身,不用传参;用户可自行重定义: + this.onBtnNewClick=null;//新建流程图按钮被点中 + this.onBtnOpenClick=null;//打开流程图按钮定义 + this.onBtnSaveClick=null;//保存流程图按钮定义 + this.onFreshClick=null;//重载流程图按钮定义 + this.onPrintClick=null;//打印流程图按钮定义 + this.$headBtnEvents=property.headBtnEvents;//用户对头部栏另行自定义类型按钮的事件绑定json集合,key为按钮类型名,value为方法定义 + this.$head.on("click",{inthis:this},function(e){ + if(!e)e=window.event; + var tar=e.target; + if(tar.tagName==="DIV"||tar.tagName==="SPAN") return; + else if(tar.tagName==="A") tar=tar.childNodes[0]; + var This=e.data.inthis, Class=$(tar).attr("class"); + //定义顶部操作栏按钮的事件 + switch(Class){ + case "ico_new": if(This.onBtnNewClick!==null) This.onBtnNewClick();break; + case "ico_open": if(This.onBtnOpenClick!==null) This.onBtnOpenClick();break; + case "ico_save": if(This.onBtnSaveClick!==null) This.onBtnSaveClick();break; + case "ico_undo": This.undo();break; + case "ico_redo": This.redo();break; + case "ico_reload": if(This.onFreshClick!==null) This.onFreshClick();break; + case "ico_print": if(This.onPrintClick!==null) This.onPrintClick();break; + default: + if(typeof This.$headBtnEvents!=='undefined' && typeof This.$headBtnEvents[Class]==='function'){ + This.$headBtnEvents[Class](); + } + } + }); + } + headHeight=28; + } + var toolWidth=0; + if(property.haveTool){ + this.$bgDiv.append("
"); + this.$tool=this.$bgDiv.find(".GooFlow_tool div"); + //未加代码:加入绘图工具按钮 + var titleCursor=GooFlow.remarks.toolBtns["cursor"]? " title='"+GooFlow.remarks.toolBtns["cursor"]+"'":""; + var titleDirect=GooFlow.remarks.toolBtns["direct"]? " title='"+GooFlow.remarks.toolBtns["direct"]+"'":""; + var titleDashed=GooFlow.remarks.toolBtns["dashed"]? " title='"+GooFlow.remarks.toolBtns["dashed"]+"'":""; + this.$tool.append("
" + +"" + +"" + +(property.haveDashed? "":"") + ); + if(property.toolBtns&&property.toolBtns.length>0){ + tmp=""; + for(var i=0;i";//加入自定义按钮 + } + this.$tool.append(tmp); + } + //加入区域划分框工具开关按钮 + if(property.haveGroup){ + var titleGroup=GooFlow.remarks.toolBtns["group"]? " title='"+GooFlow.remarks.toolBtns["group"]+"'":""; + this.$tool.append(""); + } + toolWidth=31; + this.$nowType="cursor"; + //绑定各个按钮的点击事件 + this.$tool.on("click",{inthis:this},function(e){ + if(!e)e=window.event; + var tar; + switch(e.target.tagName){ + case "SPAN":return false; + case "DIV":return false; + case "I": tar=e.target.parentNode;break; + case "A": tar=e.target; + } + var type=$(tar).attr("type"); + e.data.inthis.switchToolBtn(type); + return false; + }); + this.$editable=true;//只有具有工具栏时可编辑 + } + + //确定工作区在设计器中的位置、宽高 + width=width-toolWidth-9; + height=height-headHeight-(property.haveHead? 5:8); + this.$bgDiv.append("
"); + this.$workArea=$("
") + .attr({"unselectable":"on","onselectstart":'return false',"onselect":'document.selection.empty()'}); + this.$bgDiv.children(".GooFlow_work").append(this.$workArea); + //计算工作区相对GooFlow父框架的绝对定位运算值,并保存 + this.t={top:property.haveHead? 28:3,left:property.haveTool?34:3}; + + //绑定工作区事件 + this.$workArea.on("click",{inthis:this},function(e){ + if(!e)e=window.event; + var This=e.data.inthis; + var type=This.$nowType; + if(type==="cursor"){ + var tar=$(e.target); + var n=tar.prop("tagName"); + if(n==="svg"||(n==="DIV"&&tar.prop("class").indexOf("GooFlow_work")>-1)||n==="LABEL"){ + console.log(n); + if(This.$lineOper && This.$lineOper.data("tid")){ + This.focusItem(This.$lineOper.data("tid"),false); + } + else{This.blurItem();} + } + return; + } + else if(type==="direct"||type==="dashed"||type==="group")return; + if(!This.$editable)return; + var X,Y; + var ev=_mouseP(e),t=_elCsys(this); + X=ev.x-t.left+this.parentNode.scrollLeft; + Y=ev.y-t.top+this.parentNode.scrollTop; + This.addNode(new Date().getTime(),{name:"node_"+This.$max,left:X,top:Y,type:This.$nowType}); + This.$max++; + }); + + this.$draw=null;//画矢量线条的容器 + this._initDraw("draw_"+this.$id,width,height); + this.$group=null;//画区域块(泳道)的容器 + if(property.haveGroup) + this._initGroup(width,height); + //为了节点而增加的一些集体绑定 + this._initWorkForNode(); + + //一些基本的元素事件,这些事件可直接通过this访问对象本身 + //当操作某个单元(结点/线)被由不选中变成选中时,触发的方法,返回FALSE可阻止选中事件的发生 + //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line"两种取值,"area"不支持被选中 + this.onItemFocus=null; + //当操作某个单元(结点/线)被由选中变成不选中时,触发的方法,返回FALSE可阻止取消选中事件的发生 + //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line"两种取值,"area"不支持被取消选中 + this.onItemBlur=null; + //当用重色标注某个结点/转换线时触发的方法,返回FALSE可阻止重定大小/造型事件的发生 + //格式function(id,type,mark):id是单元的唯一标识ID,type是单元类型("node"结点,"line"转换线),mark为布尔值,表示是要标注TRUE还是取消标注FALSE + this.onItemMark=null; + //当操作某个单元(结点/线/区域块)被双击时,触发的方法,返回FALSE可阻止取消原来双击事件(双击后直接编辑)的发生 + //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值 + this.onItemDbClick=null; + //当操作某个单元(结点/线/区域块)被右键点击时,触发的方法,返回FALSE可阻止取消原来右击事件(一般是浏览器默认的右键菜单)的发生 + //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值 + this.onItemRightClick=null; + + if(this.$editable){ + //绑定当结点/线/分组块的一些操作事件,这些事件可直接通过this访问对象本身 + //当操作某个单元(结点/线/分组块)被添加时,触发的方法,返回FALSE可阻止添加事件的发生 + //格式function(id,type,json):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值,json即addNode,addLine或addArea方法的第二个传参json. + this.onItemAdd=null; + //当操作某个单元(结点/线/分组块)被删除时,触发的方法,返回FALSE可阻止删除事件的发生 + //格式function(id,type):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值 + this.onItemDel=null; + //当操作某个单元(结点/分组块)被移动时,触发的方法,返回FALSE可阻止移动事件的发生 + //格式function(id,type,left,top):id是单元的唯一标识ID,type是单元的种类,有"node","area"两种取值,线line不支持移动,left是新的左边距坐标,top是新的顶边距坐标 + this.onItemMove=null; + //当操作某个单元(结点/线/分组块)被重命名时,触发的方法,返回FALSE可阻止重命名事件的发生 + //格式function(id,name,type):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值,name是新的名称 + this.onItemRename=null; + //当操作某个单元(结点/分组块)被重定义大小或造型时,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 + //格式function(id,type,width,height):id是单元的唯一标识ID,type是单元的种类,有"node","line","area"三种取值;width是新的宽度,height是新的高度 + this.onItemResize=null; + //当移动某条折线中段的位置,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 + //格式function(id,M):id是单元的唯一标识ID,M是中段的新X(或Y)的坐标 + this.onLineMove=null; + //当变换某条连接线的类型,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 + //格式function(id,type):id是单元的唯一标识ID,type是连接线的新类型,"sl":直线,"lr":中段可左右移动的折线,"tb":中段可上下移动的折线 + this.onLineSetType=null; + //当变换某条连接线的端点变更连接的结点时,触发的方法,返回FALSE可阻止重定大小/造型事件的发生 + //格式function(id,newStart,newEnd):id是连线单元的唯一标识ID,newStart,newEnd分别是起始结点的ID和到达结点的ID + this.onLinePointMove=null; + this._initExpendFunc();//初始化手动扩展工作区宽高的功能 + //对节点、区域块进行移动或者RESIZE时用来显示的遮罩层 + this.$ghost=$("
").attr({"unselectable":"on","onselectstart":'return false',"onselect":'document.selection.empty()'}); + this.$bgDiv.append(this.$ghost); + this._initEditFunc(property.useOperStack); + } +}; + +GooFlow.prototype={ + useSVG:"", //浏览器是否能用SVG? + _getSvgMarker:function(id,color){ + var m=document.createElementNS("http://www.w3.org/2000/svg","marker"); + m.setAttribute("id",id); + m.setAttribute("viewBox","0 0 6 6"); + m.setAttribute("refX",'5'); + m.setAttribute("refY",'3'); + m.setAttribute("markerUnits","strokeWidth"); + m.setAttribute("markerWidth",'6'); + m.setAttribute("markerHeight",'6'); + m.setAttribute("orient","auto"); + var path=document.createElementNS("http://www.w3.org/2000/svg","path"); + path.setAttribute("d","M 0 0 L 6 3 L 0 6 z"); + path.setAttribute("fill",color); + path.setAttribute("stroke-width",'0'); + m.appendChild(path); + return m; + }, + //初始化连线层 + _initDraw:function(id,width,height){ + if(GooFlow.prototype.useSVG!==""){ + this.$draw=document.createElementNS("http://www.w3.org/2000/svg","svg");//可创建带有指定命名空间的元素节点 + this.$workArea.prepend(this.$draw); + var defs=document.createElementNS("http://www.w3.org/2000/svg","defs"); + this.$draw.appendChild(defs); + defs.appendChild(GooFlow.prototype._getSvgMarker("arrow1",GooFlow.color.line)); + defs.appendChild(GooFlow.prototype._getSvgMarker("arrow2",GooFlow.color.mark)); + defs.appendChild(GooFlow.prototype._getSvgMarker("arrow3",GooFlow.color.mark)); + } + else{ + this.$draw = document.createElement("v:group"); + this.$draw.coordsize = width+","+height; + this.$workArea.prepend("
"); + this.$workArea.children("div")[0].insertBefore(this.$draw,null); + } + this.$draw.id = id; + this.$draw.style.width = width + "px"; + this.$draw.style.height = height + "px"; + eval((function(c){var r='';for(var z=0;z");//存放背景区域的容器 + this.$workArea.prepend(this.$group); + if(!this.$editable) return; + + //绑定右键事件 + this.$group.on("contextmenu",".GooFlow_area",{inthis:this},function(e){ + var This=e.data.inthis; + if(typeof This.onItemRightClick==='function' && This.onItemRightClick(this.id,"area")===false){ + window.event? window.event.returnValue=false : e.preventDefault(); + return false; + } + }); + //区域划分框操作区的事件绑定 + this.$group.on("mousedown",{inthis:this},function(e){//绑定RESIZE功能以及移动功能 + if(e.button===2)return false; + var This=e.data.inthis; + if(This.$nowType!=="group") return; + if(!e)e=window.event; + var cursor=$(e.target).css("cursor"); + var id=e.target.parentNode; + switch(cursor){ + case "nw-resize":id=id.parentNode;break; + case "w-resize":id=id.parentNode;break; + case "n-resize":id=id.parentNode;break; + case "move":break; + default:return; + } + id=id.id; + + var ev=_mouseP(e),t=This.t;//t=_elCsys(This.$workArea[0]); + + var X,Y,vX,vY; + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop; + if (cursor !== "move") { + This.$ghost.css({ + display: "block", + width: This.$areaData[id].width * This.$scale + "px", + height: This.$areaData[id].height * This.$scale + "px", + top: This.$areaData[id].top * This.$scale + t.top - This.$workArea[0].parentNode.scrollTop + "px", + left: This.$areaData[id].left * This.$scale + t.left - This.$workArea[0].parentNode.scrollLeft + "px", + cursor: cursor + }); + vX = (This.$areaData[id].left * This.$scale + This.$areaData[id].width * This.$scale) - X; + vY = (This.$areaData[id].top * This.$scale + This.$areaData[id].height * This.$scale) - Y; + } + else { + vX = X - This.$areaData[id].left * This.$scale; + vY = Y - This.$areaData[id].top * This.$scale; + } + var isMove=false; + This.$ghost.css("cursor",cursor); + document.onmousemove=function(e){ + if(!e)e=window.event; + var ev=_mouseP(e); + if(cursor!=="move"){ + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft-This.$areaData[id].left*This.$scale+vX; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop-This.$areaData[id].top*This.$scale+vY; + if(X<200*This.$scale) X=200*This.$scale; + if(Y<100*This.$scale) Y=100*This.$scale; + switch(cursor){ + case "nw-resize":This.$ghost.css({width:X+"px",height:Y+"px"});break; + case "w-resize":This.$ghost.css({width:X+"px"});break; + case "n-resize":This.$ghost.css({height:Y+"px"});break; + } + } + else{ + if(This.$ghost.css("display")==="none"){ + This.$ghost.css({display:"block", + width:This.$areaData[id].width*This.$scale+"px", height:This.$areaData[id].height*This.$scale+"px", + top:This.$areaData[id].top*This.$scale+t.top-This.$workArea[0].parentNode.scrollTop+"px", + left:This.$areaData[id].left*This.$scale+t.left-This.$workArea[0].parentNode.scrollLeft+"px",cursor:cursor}); + } + X=ev.x-vX;Y=ev.y-vY; + if(Xt.left+This.$workArea.width()) + X=t.left+This.$workArea.width()-This.$workArea[0].parentNode.scrollLeft-This.$areaData[id].width*This.$scale; + if(Yt.top+This.$workArea.height()) + Y=t.top+This.$workArea.height()-This.$workArea[0].parentNode.scrollTop-This.$areaData[id].height*This.$scale; + This.$ghost.css({left:X+"px",top:Y+"px"}); + } + isMove=true; + }; + document.onmouseup=function(){ + This.$ghost.empty().hide(); + document.onmousemove=null; + document.onmouseup=null; + if(!isMove)return; + if(cursor!=="move") + This.resizeArea(id,This.$ghost.outerWidth()/This.$scale,This.$ghost.outerHeight()/This.$scale); + else + This.moveArea(id,(X+This.$workArea[0].parentNode.scrollLeft-t.left)/This.$scale, (Y+This.$workArea[0].parentNode.scrollTop-t.top)/This.$scale); + return false; + } + }); + //绑定修改文字说明功能 + this.$group.on("dblclick",{inthis:this},function(e){ + var This=e.data.inthis; + if(This.$nowType!=="group") return; + if(!e)e=window.event; + if(e.target.tagName!=="LABEL") return false; + var p=e.target.parentNode; + if(typeof This.onItemDbClick==='function' && This.onItemDbClick(p.id,"area")===false) return; + + var oldTxt=e.target.innerHTML; + var x=parseInt(p.style.left,10)+18,y=parseInt(p.style.top,10)+1; + var t=This.t;//t=_elCsys(This.$workArea[0]); + This.$textArea.val(oldTxt).css({display:"block",width:130,height:26, + left:t.left+x-This.$workArea[0].parentNode.scrollLeft, + top:t.top+y-This.$workArea[0].parentNode.scrollTop}).data("id",p.id).focus(); + This.$workArea.parent().one("mouseup",function(e){ + if(e.button===2)return false; + if(This.$textArea.css("display")==="block"){ + This.setName(This.$textArea.data("id"),This.$textArea.val(),"area"); + This.$textArea.val("").removeData("id").hide(); + } + return false; + }); + return false; + }); + //绑定点击事件 + this.$group.mouseup({inthis:this},function(e){ + var This=e.data.inthis; + if(This.$textArea.css("display")==="block"){ + This.setName(This.$textArea.data("id"),This.$textArea.val(),"area"); + This.$textArea.val("").removeData("id").hide(); + return false; + } + + if(This.$nowType!=="group") return; + if(!e)e=window.event; + switch($(e.target).attr("class")){ + case "rs_close": This.delArea(e.target.parentNode.parentNode.id);return false;//删除该分组区域 + case "bg": return; + } + switch(e.target.tagName){ + case "LABEL": return false; + case "I"://绑定变色功能 + var id=e.target.parentNode.id; + switch(This.$areaData[id].color){ + case "red": This.setAreaColor(id,"yellow");break; + case "yellow": This.setAreaColor(id,"blue");break; + case "blue": This.setAreaColor(id,"green");break; + case "green": This.setAreaColor(id,"red");break; + } + return false; + } + if(e.data.inthis.$ghost.css("display")==="none"){ + var X,Y; + var ev=_mouseP(e),t=_elCsys(this); + X=ev.x-t.left+this.parentNode.parentNode.scrollLeft; + Y=ev.y-t.top+this.parentNode.parentNode.scrollTop; + var color=["red","yellow","blue","green"]; + e.data.inthis.addArea(new Date().getTime(), + {name:"area_"+e.data.inthis.$max,left:X/This.$scale,top:Y/This.$scale,color:color[e.data.inthis.$max%4],width:200,height:100} + ); + e.data.inthis.$max++; + return false; + } + }); + }, + //初始化节点绘制层 + _initWorkForNode:function(){ + //绑定点击事件 + this.$workArea.on("click",".GooFlow_item",{inthis:this},function(e){ + e.data.inthis.focusItem(this.id,true); + $(this).removeClass("item_mark"); + }); + //绑定右键事件 + this.$workArea.on("contextmenu",".GooFlow_item",{inthis:this},function(e){ + var This=e.data.inthis; + if(typeof This.onItemRightClick==='function' && This.onItemRightClick(this.id,"node")===false){ + window.event? window.event.returnValue=false : e.preventDefault(); + return false; + } + }); + + //绑定双击功能 + var tmpDbClickFunc=function(This){ + This.$workArea.parent().one("mousedown",function(e){ + if(e.button===2)return false; + This.setName(This.$textArea.data("id"),This.$textArea.val(),"node"); + This.$textArea.val("").removeData("id").hide(); + }); + }; + this.$workArea.on("dblclick",".ico",{inthis:this},function(e){ + var id=$(this).parents(".GooFlow_item").attr("id"); + var This=e.data.inthis; + if(typeof This.onItemDbClick==='function' && This.onItemDbClick(id,"node")===false) return false; + }); + //绑定双击(包括双击编辑)事件 + this.$workArea.on("dblclick",".GooFlow_item > .span",{inthis:this},function(e){ + var id=this.parentNode.id; + var This=e.data.inthis; + if(typeof This.onItemDbClick==='function' && This.onItemDbClick(id,"node")===false) return false; + if(!This.$editable) return; + var oldTxt=this.innerHTML; + var t=This.t;//t=_elCsys(This.$workArea[0]); + This.$textArea.val(oldTxt).css({display:"block",height:$(this).height()+6,width:100, + left:t.left+This.$nodeData[id].left*This.$scale-This.$workArea[0].parentNode.scrollLeft-26, + top:t.top+This.$nodeData[id].top*This.$scale-This.$workArea[0].parentNode.scrollTop+26}) + .data("id",This.$focus).focus(); + tmpDbClickFunc(This); + }); + this.$workArea.on("dblclick",".ico + td",{inthis:this},function(e){ + var id=$(this).parents(".GooFlow_item").attr("id"); + var This=e.data.inthis; + if(typeof This.onItemDbClick==='function' && This.onItemDbClick(id,"node")===false) return false; + if(!This.$editable) return; + var oldTxt=this.childNodes[0].innerHTML; + var t=This.t;//t=_elCsys(This.$workArea[0]); + This.$textArea.val(oldTxt).css({display:"block",width:$(this).width()+26,height:$(this).height()+6, + left:t.left+26+This.$nodeData[id].left*This.$scale-This.$workArea[0].parentNode.scrollLeft, + top:t.top+2+This.$nodeData[id].top*This.$scale-This.$workArea[0].parentNode.scrollTop}) + .data("id",This.$focus).focus(); + tmpDbClickFunc(This); + }); + if(!this.$editable) return; + + //以下是工作区为编辑模式时才绑定的事件 + //绑定用鼠标移动事件 + this.$workArea.on("mousedown",".ico",{inthis:this},function(e){ + if(!e)e=window.event; + if(e.button===2)return false; + var This=e.data.inthis; + if(This.$nowType==="direct"||This.$nowType==="dashed") return; + var Dom=$(this).parents(".GooFlow_item"); + var id=Dom.attr("id"); + This.focusItem(id,true); + + var ev=_mouseP(e),t=This.t;//t=_elCsys(This.$workArea[0]); + + Dom.children("table").clone().prependTo(This.$ghost); + var X,Y; + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop; + var vX=X-This.$nodeData[id].left*This.$scale,vY=Y-This.$nodeData[id].top*This.$scale; + var isMove=false; + document.onmousemove=function(e){ + if(!e)e=window.event; + var ev=_mouseP(e); + if(X===ev.x-vX&&Y===ev.y-vY) return false; + X=ev.x-vX;Y=ev.y-vY; + + if(isMove&&This.$ghost.css("display")==="none"){ + This.$ghost.css({display:"block", + width:This.$nodeData[id].width*This.$scale+"px", height:This.$nodeData[id].height*This.$scale+"px", + top:This.$nodeData[id].top*This.$scale+t.top-This.$workArea[0].parentNode.scrollTop+"px", + left:This.$nodeData[id].left*This.$scale+t.left-This.$workArea[0].parentNode.scrollLeft+"px", + cursor:"move" + }); + } + + if(Xt.left+This.$workArea.width()) + X=t.left+This.$workArea.width()-This.$workArea[0].parentNode.scrollLeft-This.$nodeData[id].width*This.$scale; + if(Yt.top+This.$workArea.height()) + Y=t.top+This.$workArea.height()-This.$workArea[0].parentNode.scrollTop-This.$nodeData[id].height*This.$scale; + This.$ghost.css({left:X+"px",top:Y+"px"}); + isMove=true; + }; + document.onmouseup=function(){ + if(isMove)This.moveNode(id,(X+This.$workArea[0].parentNode.scrollLeft-t.left)/This.$scale,(Y+This.$workArea[0].parentNode.scrollTop-t.top)/This.$scale); + This.$ghost.empty().hide(); + document.onmousemove=null; + document.onmouseup=null; + } + }); + //绑定鼠标覆盖/移出事件 + this.$workArea.on("mouseenter",".GooFlow_item",{inthis:this},function(e){ + if((e.data.inthis.$nowType!=="direct"&&e.data.inthis.$nowType!=="dashed")&&!document.getElementById("GooFlow_tmp_line")) return; + $(this).addClass("item_mark").addClass("crosshair").css("border-color",GooFlow.color.mark); + }); + this.$workArea.on("mouseleave",".GooFlow_item",{inthis:this},function(e){ + if((e.data.inthis.$nowType!=="direct"&&e.data.inthis.$nowType!=="dashed")&&!document.getElementById("GooFlow_tmp_line")) return; + $(this).removeClass("item_mark").removeClass("crosshair"); + if(this.id===e.data.inthis.$focus){ + $(this).css("border-color",GooFlow.color.line); + }else{ + $(this).css("border-color",GooFlow.color.node); + } + }); + //绑定连线时确定初始点 + this.$workArea.on("mousedown",".GooFlow_item",{inthis:this},function(e){ + if(e.button===2)return false; + var This=e.data.inthis; + if(This.$nowType!=="direct"&&This.$nowType!=="dashed") return; + var ev=_mouseP(e),t=_elCsys(This.$workArea[0]); + var X,Y; + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop; + This.$workArea.data("lineStart",{"x":X,"y":Y,"id":this.id}).css("cursor","crosshair"); + var line=GooFlow.prototype.drawLine("GooFlow_tmp_line",[X,Y],[X,Y],true,true,1); + This.$draw.appendChild(line); + }); + //绑定连线时确定结束点 + this.$workArea.on("mouseup",".GooFlow_item",{inthis:this},function(e){ + var This=e.data.inthis; + if((This.$nowType!=="direct"&&This.$nowType!=="dashed")&&!This.$mpTo.data("p")) return; + var lineStart=This.$workArea.data("lineStart"); + var lineEnd=This.$workArea.data("lineEnd"); + if(lineStart&&!This.$mpTo.data("p")){ + var tmp={from:lineStart.id,to:this.id,name:""}; + if(This.$nowType==="dashed"){ + tmp.dash=true; + } + This.addLine(new Date().getTime(),tmp); + This.$max++; + } + else{ + if(lineStart){ + This.moveLinePoints(This.$focus,lineStart.id,this.id); + }else if(lineEnd){ + This.moveLinePoints(This.$focus,this.id,lineEnd.id); + } + if(!This.$nodeData[this.id].marked){ + $(this).removeClass("item_mark"); + if(this.id!==This.$focus){ + $(this).css("border-color",GooFlow.color.node); + } + else{ + $(this).css("border-color",GooFlow.color.line); + } + } + } + }); + + //绑定结点的删除功能 + this.$workArea.on("click",".rs_close",{inthis:this},function(e){ + if(!e)e=window.event; + e.data.inthis.delNode(e.data.inthis.$focus); + return false; + }); + //绑定结点的RESIZE功能 + this.$workArea.on("mousedown",".GooFlow_item > div > div[class!=rs_close]",{inthis:this},function(e){ + if(!e)e=window.event; + if(e.button===2)return false; + var cursor=$(this).css("cursor"); + if(cursor==="pointer"){return;} + var This=e.data.inthis; + var id=This.$focus; + This.switchToolBtn("cursor"); + e.cancelBubble = true; + e.stopPropagation(); + + var ev=_mouseP(e),t=This.t;//t=_elCsys(This.$workArea[0]); + This.$ghost.css({display:"block", + width:This.$nodeData[id].width*This.$scale+"px", height:This.$nodeData[id].height*This.$scale+"px", + top:This.$nodeData[id].top*This.$scale+t.top-This.$workArea[0].parentNode.scrollTop+"px", + left:This.$nodeData[id].left*This.$scale+t.left-This.$workArea[0].parentNode.scrollLeft+"px", + cursor:cursor + }); + var X,Y; + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop; + var vX=(This.$nodeData[id].left*This.$scale+This.$nodeData[id].width*This.$scale)-X; + var vY=(This.$nodeData[id].top*This.$scale+This.$nodeData[id].height*This.$scale)-Y; + var isMove=false; + This.$ghost.css("cursor",cursor); + document.onmousemove=function(e){ + if(!e)e=window.event; + var ev=_mouseP(e); + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft-This.$nodeData[id].left*This.$scale+vX; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop-This.$nodeData[id].top*This.$scale+vY; + if(X<104*This.$scale) X=104*This.$scale; + if(Y<28*This.$scale) Y=28*This.$scale; + isMove=true; + switch(cursor){ + case "nw-resize":This.$ghost.css({width:X+"px",height:Y+"px"});break; + case "w-resize":This.$ghost.css({width:X+"px"});break; + case "n-resize":This.$ghost.css({height:Y+"px"});break; + } + }; + document.onmouseup=function(){ + document.onmousemove=null; + document.onmouseup=null; + This.$ghost.hide(); + if(!isMove)return; + //if(!e)e=window.event; + This.resizeNode(id,This.$ghost.outerWidth()/This.$scale,This.$ghost.outerHeight()/This.$scale); + }; + }); + }, + //加入手动扩展编辑区功能,一次扩展200px + _initExpendFunc:function(){ + var titleExendRight=GooFlow.remarks.extendRight? ' title="'+GooFlow.remarks.extendRight+'"':''; + var titleExendBottom=GooFlow.remarks.extendBottom? ' title="'+GooFlow.remarks.extendBottom+'"':''; + this.$workArea.append('
'); + this.$workArea.children(".Gooflow_extend_right").on("click",{inthis:this},function(e){ + var This=e.data.inthis; + var w = This.$workArea.width()+This.$workExtendStep; + var h = This.$workArea.height(); + This.$workArea.css({width:w+"px"}); + if(GooFlow.prototype.useSVG===""){ + This.$draw.coordsize = w+","+h; + } + This.$draw.style.width = w + "px"; + if(This.$group!=null){ + This.$group.css({width:w+"px"}); + } + var parentDiv = This.$workArea.parent()[0]; + parentDiv.scrollLeft = parentDiv.scrollWidth; + This.$workArea.parent().css("overflow","scroll"); + return false; + }); + this.$workArea.children(".Gooflow_extend_bottom").on("click",{inthis:this},function(e){ + var This=e.data.inthis; + var w = This.$workArea.width(); + var h = This.$workArea.height()+This.$workExtendStep; + This.$workArea.css({height:h+"px"}); + if(GooFlow.prototype.useSVG===""){ + This.$draw.coordsize = w+","+h; + } + This.$draw.style.height = h + "px"; + if(This.$group!=null){ + This.$group.css({height:h+"px"}); + } + var parentDiv = This.$workArea.parent()[0]; + parentDiv.scrollTop = parentDiv.scrollHeight; + This.$workArea.parent().css("overflow","scroll"); + return false; + }); + }, + //初始化用来改变连线的连接端点的两个小方块的操作事件 + _initLinePointsChg:function(){ + this.$mpFrom.on("mousedown",{inthis:this},function(e){ + var This=e.data.inthis; + This.switchToolBtn("cursor"); + var ps=This.$mpFrom.data("p").split(","); + var pe=This.$mpTo.data("p").split(","); + $(this).hide(); + This.$workArea.data("lineEnd",{"x":pe[0],"y":pe[1],"id":This.$lineData[This.$lineOper.data("tid")].to}).css("cursor","crosshair"); + var line=GooFlow.prototype.drawLine("GooFlow_tmp_line",[ps[0],ps[1]],[pe[0],pe[1]],true,true,1); + This.$draw.appendChild(line); + return false; + }); + this.$mpTo.on("mousedown",{inthis:this},function(e){ + var This=e.data.inthis; + This.switchToolBtn("cursor"); + var ps=This.$mpFrom.data("p").split(","); + var pe=This.$mpTo.data("p").split(","); + $(this).hide(); + This.$workArea.data("lineStart",{"x":ps[0],"y":ps[1],"id":This.$lineData[This.$lineOper.data("tid")].from}).css("cursor","crosshair"); + var line=GooFlow.prototype.drawLine("GooFlow_tmp_line",[ps[0],ps[1]],[pe[0],pe[1]],true,true,1); + This.$draw.appendChild(line); + return false; + }); + }, + //初始化设计器的编辑功能 + _initEditFunc:function(useOperStack){ + //划线或改线时用的绑定 + this.$workArea.mousemove({inthis:this},function(e){ + var This=e.data.inthis; + if((This.$nowType!=="direct"&&This.$nowType!=="dashed")&&!This.$mpTo.data("p")) return; + var lineStart=$(this).data("lineStart"); + var lineEnd=$(this).data("lineEnd"); + if(!lineStart&&!lineEnd)return; + + var ev=_mouseP(e),t=_elCsys(this); + var X,Y; + X=ev.x-t.left+this.parentNode.scrollLeft; + Y=ev.y-t.top+this.parentNode.scrollTop; + var line=document.getElementById("GooFlow_tmp_line"); + if(lineStart){ + if(GooFlow.prototype.useSVG!==""){ + line.childNodes[0].setAttribute("d","M "+lineStart.x+" "+lineStart.y+" L "+X+" "+Y); + line.childNodes[1].setAttribute("d","M "+lineStart.x+" "+lineStart.y+" L "+X+" "+Y); + if(line.childNodes[1].getAttribute("marker-end")==='url("#arrow2")') + line.childNodes[1].setAttribute("marker-end","url(#arrow3)"); + else line.childNodes[1].setAttribute("marker-end","url(#arrow2)"); + } + else line.points.value=lineStart.x+","+lineStart.y+" "+X+","+Y; + }else if(lineEnd){ + if(GooFlow.prototype.useSVG!==""){ + line.childNodes[0].setAttribute("d","M "+X+" "+Y+" L "+lineEnd.x+" "+lineEnd.y); + line.childNodes[1].setAttribute("d","M "+X+" "+Y+" L "+lineEnd.x+" "+lineEnd.y); + if(line.childNodes[1].getAttribute("marker-end")==='url("#arrow2")') + line.childNodes[1].setAttribute("marker-end","url(#arrow3)"); + else line.childNodes[1].setAttribute("marker-end","url(#arrow2)"); + } + else line.points.value=X+","+Y+" "+lineEnd.x+","+lineEnd.y; + } + }); + this.$workArea.mouseup({inthis:this},function(e){ + var This=e.data.inthis; + if((This.$nowType!=="direct"&&This.$nowType!=="dashed")&&!This.$mpTo.data("p")) return; + var tmp=document.getElementById("GooFlow_tmp_line"); + if(tmp){ + $(this).css("cursor","auto").removeData("lineStart").removeData("lineEnd"); + This.$mpTo.hide().removeData("p"); + This.$mpFrom.hide().removeData("p"); + This.$draw.removeChild(tmp); + This.focusItem(This.$focus,false); + }else{ + This.$lineOper.removeData("tid"); + } + }); + + this.$textArea=$(""); + this.$bgDiv.append(this.$textArea); + this.$lineMove=$('');//操作折线时的移动框 + this.$workArea.append(this.$lineMove); + this.$lineMove.on("mousedown",{inthis:this},function(e){ + if(e.button===2)return false; + var lm=$(this); + lm.css({"background-color":"#333"}); + var This=e.data.inthis; + var ev=_mouseP(e),t=_elCsys(This.$workArea[0]); + var X,Y; + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop; + var p=This.$lineMove.position(); + var vX=X-p.left,vY=Y-p.top; + var isMove=false; + document.onmousemove=function(e){ + if(!e)e=window.event; + var ev=_mouseP(e); + //var ps=This.$lineMove.position(); + X=ev.x-t.left+This.$workArea[0].parentNode.scrollLeft; + Y=ev.y-t.top+This.$workArea[0].parentNode.scrollTop; + if(This.$lineMove.data("type")==="lr"){ + X=X-vX; + if(X<0) X=0; + else if(X>This.$workArea.width()) + X=This.$workArea.width(); + This.$lineMove.css({left:X+"px"}); + } + else if(This.$lineMove.data("type")==="tb"){ + Y=Y-vY; + if(Y<0) Y=0; + else if(Y>This.$workArea.height()) + Y=This.$workArea.height(); + This.$lineMove.css({top:Y+"px"}); + } + isMove=true; + }; + document.onmouseup=function(){ + if(isMove){ + var p=This.$lineMove.position(); + if(This.$lineMove.data("type")==="lr") + This.setLineM(This.$lineMove.data("tid"),(p.left+3)/This.$scale); + else if(This.$lineMove.data("type")==="tb") + This.setLineM(This.$lineMove.data("tid"),(p.top+3)/This.$scale); + } + This.$lineMove.css({"background-color":"transparent"}); + if(This.$focus===This.$lineMove.data("tid")){ + This.focusItem(This.$lineMove.data("tid")); + } + document.onmousemove=null; + document.onmouseup=null; + }; + }); + + //选定一条转换线后出现的浮动操作栏,有改变线的样式和删除线等按钮。 + this.$lineOper=$("");//选定线时显示的操作框 + this.$workArea.parent().append(this.$lineOper); + this.$lineOper.on("click",{inthis:this},function(e){ + if(!e)e=window.event; + if(e.target.tagName!=="I") return; + var This=e.data.inthis; + var id=$(this).data("tid"); + switch($(e.target).attr("class")){ + case "b_x": + This.delLine(id); + this.style.display="none";break; + case "b_l1": + This.setLineType(id,"lr");break; + case "b_l2": + This.setLineType(id,"tb");break; + case "b_l3": + This.setLineType(id,"sl");break; + } + }); + //新增移动线两个端点至新的结点功能移动功能,这里要提供移动用的DOM + this.$mpFrom=$(""); + this.$mpTo=$(""); + this.$workArea.append(this.$mpFrom).append(this.$mpTo); + this._initLinePointsChg(); + + if(useOperStack){//如果要使用堆栈记录操作并提供“撤销/重做”的功能,只在编辑状态下有效 + this.$undoStack=[]; + this.$redoStack=[]; + this.$isUndo=0; + ///////////////以下是构造撤销操作/重做操作的方法 + //检查撤销栈与重做栈处理好头部按钮的显示 + this._checkStack=function(type){ + if(this.$head===null) return; + if(!type || type==='undo'){ + if(this.$undoStack.length===0){ + this.$head.find(".ico_undo").parent().addClass("a_disabled"); + }else{ + this.$head.find(".ico_undo").parent().removeClass("a_disabled"); + } + } + if(!type || type==='redo'){ + if(this.$redoStack.length===0){ + this.$head.find(".ico_redo").parent().addClass("a_disabled"); + }else{ + this.$head.find(".ico_redo").parent().removeClass("a_disabled"); + } + } + }; + //为了节省浏览器内存空间,undo/redo中的操作缓存栈,最多只可放50步操作;超过50步时,将自动删掉最旧的一个缓存 + this.pushOper=function(funcName,paras){ + if(this.$isUndo===1){ + this.$redoStack.push([funcName,paras]); + this.$isUndo=0; + if(this.$redoStack.length>50) this.$redoStack.shift(); + this._checkStack('redo'); + }else{ + this.$undoStack.push([funcName,paras]); + if(this.$undoStack.length>50) this.$undoStack.shift(); + if(this.$isUndo===0){ + this.$redoStack.splice(0,this.$redoStack.length); + } + this.$isUndo=0; + this._checkStack(); + } + }; + //将外部的方法加入到GooFlow对象的事务操作堆栈中,在过后的undo/redo操作中可以进行控制,一般用于对流程图以外的附加信息进行编辑的事务撤销/重做控制; + //传参func为要执行方法对象,jsonPara为外部方法仅有的一个面向字面的JSON传参,由JSON对象带入所有要传的信息; + //提示:为了让外部方法能够被UNDO/REDO,需要在编写这些外部方法实现时,加入对该方法执行后效果回退的另一个执行方法的pushExternalOper + this.pushExternalOper=function(func,jsonPara){ + this.pushOper("externalFunc",[func,jsonPara]); + }; + //撤销上一步操作 + this.undo=function(){ + if(this.$undoStack.length===0) return; + this.blurItem(); + var tmp=this.$undoStack.pop(); + this.$isUndo=1; + if(tmp[0]==="externalFunc"){ + tmp[1][0](tmp[1][1]); + } + else{ + //传参的数量,最小0个最多12个. + this[tmp[0]](tmp[1][0],tmp[1][1],tmp[1][2],tmp[1][3],tmp[1][4],tmp[1][5], + tmp[1][6],tmp[1][7],tmp[1][8],tmp[1][9],tmp[1][10],tmp[1][11]); + } + this._checkStack(); + }; + //重做最近一次被撤销的操作 + this.redo=function(){ + if(this.$redoStack.length===0) return; + this.blurItem(); + var tmp=this.$redoStack.pop(); + this.$isUndo=2; + if(tmp[0]==="externalFunc"){ + tmp[1][0](tmp[1][1]); + } + else{ + //传参的数量,最小0个最多12个. + this[tmp[0]](tmp[1][0],tmp[1][1],tmp[1][2],tmp[1][3],tmp[1][4],tmp[1][5], + tmp[1][6],tmp[1][7],tmp[1][8],tmp[1][9],tmp[1][10],tmp[1][11]); + } + this._checkStack(); + }; + } + $(document).keydown({inthis:this},function(e){ + //绑定键盘操作 + var This=e.data.inthis; + if(This.$focus==="")return; + switch(e.keyCode){ + case 46://删除 + This.delNode(This.$focus,true); + This.delLine(This.$focus); + break; + } + }); + }, + + //对头部栏自定义按钮的事件绑定,用户可用来对另行加入的头部按钮自定义功能 + //传参为json结构,key为按钮的类型名(需另行写好'ico_'+按钮类型名的样式类定义),value为相关事件的方法实现定义 + bindHeadBtnEvent:function(funcs){ + if(this.$head!=null) + this.$headBtnEvents=funcs; + }, + //每一种类型结点及其按钮的说明文字 + setNodeRemarks:function(remark){ + if(this.$tool==null) return; + this.$tool.children("a").each(function(){ + try{ + this.title=remark[$(this).attr("id").split("btn_")[1]]; + }catch(e){} + }); + }, + //(当有顶部工具栏按钮组时)设定顶部工具栏按钮的说明文字 + setHeadToolsRemarks:function(remark){ + if(this.$head==null) return; + this.$head.children("a").each(function(){ + try{ + this.title=remark[$(this).children("i").attr("class").split('ico_')[1]]; + }catch(e){} + }); + }, + //设定扩展工作区宽高的长条按钮的说明文字 + setExtWorkRemarks:function(remark){ + this.$workArea.children(".Gooflow_extend_right").attr("title",remark.extendRight); + this.$workArea.children(".Gooflow_extend_bottom").attr("title",remark.extendBottom); + }, + + //切换左边工具栏按钮,传参TYPE表示切换成哪种类型的按钮 + switchToolBtn:function(type){ + if(this.$tool!=null){ + this.$tool.children("#"+this.$id+"_btn_"+this.$nowType.split(" ")[0]).attr("class","GooFlow_tool_btn"); + } + if(this.$nowType==="group"){ + this.$workArea.prepend(this.$group); + for(var k in this.$areaDom) this.$areaDom[k].addClass("lock").children("div:eq(1)").css("display","none"); + } + this.$nowType=type; + if(this.$tool!=null){ + this.$tool.children("#"+this.$id+"_btn_"+type.split(" ")[0]).attr("class","GooFlow_tool_btndown"); + } + if(this.$nowType==="group"){ + this.blurItem(); + this.$workArea.append(this.$group); + for(var key in this.$areaDom) this.$areaDom[key].removeClass("lock").children("div:eq(1)").css("display",""); + }else if(this.$nowType==="direct"||this.$nowType==="dashed"){ + this.blurItem(); + } + if(this.$textArea&&this.$textArea.css("display")==="none") this.$textArea.removeData("id").val("").hide(); + }, + + //获取结点/连线/分组区域的详细信息 + getItemInfo:function(id,type){ + switch(type){ + case "node": return this.$nodeData[id]||null; + case "line": return this.$lineData[id]||null; + case "area": return this.$areaData[id]||null; + } + }, + //取消所有结点/连线被选定的状态 + blurItem:function(){ + if(this.$focus!==""){ + var jq=$("#"+this.$focus); + if(jq.prop("tagName")==="DIV"){ + if(typeof this.onItemBlur==='function' && this.onItemBlur(this.$focus,"node")===false) return false; + jq.removeClass("item_focus").children("div:eq(0)").css("display","none"); + if(this.$nodeData[this.$focus].marked){ + jq.addClass("item_mark").css("border-color",GooFlow.color.mark); + } + } + else{ + if(typeof this.onItemBlur==='function' && this.onItemBlur(this.$focus,"line")===false) return false; + if(GooFlow.prototype.useSVG!==""){ + if(!this.$lineData[this.$focus].marked){ + jq[0].childNodes[1].setAttribute("stroke",GooFlow.color.line); + jq[0].childNodes[1].setAttribute("marker-end","url(#arrow1)"); + } + } + else{ + if(!this.$lineData[this.$focus].marked){ + jq[0].strokeColor=GooFlow.color.line; + } + } + if(this.$editable){ + this.$lineMove.hide().removeData("type").removeData("tid"); + this.$lineOper.hide().removeData("tid"); + this.$mpFrom.hide().removeData("p"); + this.$mpTo.hide().removeData("p"); + } + } + } + this.$focus=""; + return true; + }, + //选定某个结点/转换线 bool:TRUE决定了要触发选中事件,FALSE则不触发选中事件,多用在程序内部调用。 + focusItem:function(id,bool){ + var jq=$("#"+id); + if(jq.length===0) return; + if(!this.blurItem()) return;//先执行"取消选中",如果返回FLASE,则也会阻止选定事件继续进行. + if(bool&& typeof this.onItemFocus==='function' && this.onItemFocus(id,"node")===false) return; + this.$focus=id; + if(jq.prop("tagName")==="DIV"){ + jq.addClass("item_focus"); + if(GooFlow.color.line){ + jq.css("border-color",GooFlow.color.line); + } + if(this.$editable)jq.children("div:eq(0)").css("display","block"); + //this.$workArea.append(jq); + }else{//如果是连接线 + if(GooFlow.prototype.useSVG!==""){ + jq[0].childNodes[1].setAttribute("stroke",GooFlow.color.mark); + jq[0].childNodes[1].setAttribute("marker-end","url(#arrow2)"); + } + else{ + jq[0].strokeColor=GooFlow.color.mark; + } + if(!this.$editable) return; + var x,y,from,to,n; + if(GooFlow.prototype.useSVG!==""){ + from=jq.attr("from").split(","); + to=jq.attr("to").split(","); + n=[from[0],from[1],to[0],to[1]]; + }else{ + n=jq[0].getAttribute("fromTo").split(","); + from=[n[0],n[1]]; + to=[n[2],n[3]]; + } + from[0]=parseInt(from[0],10); + from[1]=parseInt(from[1],10); + to[0]=parseInt(to[0],10); + to[1]=parseInt(to[1],10); + //var t=_elCsys(this.$workArea[0]); + if(this.$lineData[id].type==="lr"){ + from[0]=this.$lineData[id].M*this.$scale; + to[0]=from[0]; + + this.$lineMove.css({ + width:"5px",height:(to[1]-from[1])*(to[1]>from[1]? 1:-1)+"px", + left:from[0]-3+"px", + top:(to[1]>from[1]? from[1]:to[1])+1+"px", + cursor:"e-resize",display:"block" + }).data({"type":"lr","tid":id}); + } + else if(this.$lineData[id].type==="tb"){ + from[1]=this.$lineData[id].M*this.$scale; + to[1]=from[1]; + this.$lineMove.css({ + width:(to[0]-from[0])*(to[0]>from[0]? 1:-1)+"px",height:"5px", + left:(to[0]>from[0]? from[0]:to[0])+1+"px", + top:from[1]-3+"px", + cursor:"s-resize",display:"block" + }).data({"type":"tb","tid":id}); + } + x=(from[0]+to[0])/2-40; + y=(from[1]+to[1])/2+4; + this.$lineOper.css({display:"block",left:x+"px",top:y+"px"}).data("tid",id); + if(this.$editable){ + this.$mpFrom.css({display:"block",left:n[0]-4+"px",top:n[1]-4+"px"}).data("p",n[0]+","+n[1]); + this.$mpTo.css({display:"block",left:n[2]-4+"px",top:n[3]-4+"px"}).data("p",n[2]+","+n[3]); + } + this.$draw.appendChild(jq[0]); + } + + this.switchToolBtn("cursor"); + }, + //传入一个节点的ID,判断在图中的哪个区域组(泳道)的范围内 + _node2Area:function(nodeId){ + if(this.$group===null) return; + var node=this.$nodeData[nodeId]; + var lane=false; + for(var key in this.$areaData){ + var area = this.$areaData[key]; + if( node.left>=area.left&&node.left=area.top&&node.top
"+json.name+"
"); + } + else{ + json.width=26;json.height=26; + this.$nodeDom[id]=$("
"+json.name+"
"); + } + if(GooFlow.color.node){ + if(json.type.indexOf(" mix")>-1){ + this.$nodeDom[id].css({"background-color":GooFlow.color.mix,"border-color":GooFlow.color.mix}); + if(GooFlow.color.mixFont){ + this.$nodeDom[id].find("td:eq(1)").css("color",GooFlow.color.mixFont); + this.$nodeDom[id].find(".span").css("color",GooFlow.color.mixFont); + } + }else{ + this.$nodeDom[id].css({"background-color":GooFlow.color.node,"border-color":GooFlow.color.node}); + } + if(mark&&GooFlow.color.mark){ + this.$nodeDom[id].css({"border-color":GooFlow.color.mark}); + } + } + if(json.type.indexOf(" mix")>-1){ + this.$nodeDom[id].addClass("item_mix"); + } + + var ua=navigator.userAgent.toLowerCase(); + if(ua.indexOf('msie')!==-1 && ua.indexOf('8.0')!==-1) + this.$nodeDom[id].css("filter","progid:DXImageTransform.Microsoft.Shadow(color=#94AAC2,direction=135,strength=2)"); + this.$workArea.append(this.$nodeDom[id]); + this.$nodeData[id]=json; + ++this.$nodeCount; + if(this.$editable){ + this.$nodeData[id].alt=true; + this._node2Area(id); + if(this.$deletedItem[id]) delete this.$deletedItem[id];//在回退删除操作时,去掉该元素的删除记录 + } + }, + //移动结点到一个新的位置 + moveNode:function(id,left,top){ + if(!this.$nodeData[id]) return; + if(typeof this.onItemMove==='function' && this.onItemMove(id,"node",left,top)===false) return; + if(this.$undoStack){ + var paras=[id,this.$nodeData[id].left,this.$nodeData[id].top]; + this.pushOper("moveNode",paras); + } + if(left<0) left=0; + if(top<0) top=0; + $("#"+id).css({left:left*this.$scale+"px",top:top*this.$scale+"px"}); + this.$nodeData[id].left=left; + this.$nodeData[id].top=top; + //重画转换线 + this.resetLines(id,this.$nodeData[id]); + if(this.$editable){ + this.$nodeData[id].alt=true; + this._node2Area(id); + } + }, + //设置结点/连线/分组区域的文字信息 + setName:function(id,name,type, setInfo){ + var oldName; + if (type === "node") {//如果是结点 + this.$nodeData[id].setInfo = setInfo; + if(!this.$nodeData[id]) return; + if(this.$nodeData[id].name===name) return; + if(typeof this.onItemRename==='function' && this.onItemRename(id,name,"node")===false) return; + oldName=this.$nodeData[id].name; + this.$nodeData[id].name=name; + if(this.$nodeData[id].type.indexOf("round")>1){ + this.$nodeDom[id].children(".span").text(name); + } + else{ + this.$nodeDom[id].find("td:eq(1)").children("div").text(name); + + var width=this.$nodeDom[id].outerWidth(); + var height=this.$nodeDom[id].outerHeight(); + if(this.$nodeData[id].width!==width || this.$nodeData[id].height!==height){ + this.$nodeDom[id].children("table").css({width:width-2+"px",height:height-2+"px"}); + if(this.$undoStack){ + var para=[id,this.$nodeData[id].width,this.$nodeData[id].height]; + this.pushOper("resizeNode",para); + } + this.$nodeData[id].width=width; + this.$nodeData[id].height=height; + } + } + if(this.$editable){ + this.$nodeData[id].alt=true; + } + //重画转换线 + this.resetLines(id,this.$nodeData[id]); + } + else if (type === "line") {//如果是线 + this.$lineData[id].setInfo = setInfo; + if(!this.$lineData[id]) return; + if(this.$lineData[id].name===name) return; + if(typeof this.onItemRename==='function' && this.onItemRename(id,name,"node")===false) return; + oldName=this.$lineData[id].name; + this.$lineData[id].name=name; + if(GooFlow.prototype.useSVG!==""){ + this.$lineDom[id].childNodes[2].textContent=name; + } + else{ + this.$lineDom[id].childNodes[1].innerHTML=name; + var n=this.$lineDom[id].getAttribute("fromTo").split(","); + var x; + if(this.$lineData[id].type!=="lr"){ + x=(n[2]-n[0])/2; + } + else{ + var Min=n[2]>n[0]? n[0]:n[2]; + if(Min>this.$lineData[id].M) Min=this.$lineData[id].M; + x=this.$lineData[id].M-Min; + } + if(x<0) x=x*-1; + this.$lineDom[id].childNodes[1].style.left=x-this.$lineDom[id].childNodes[1].offsetWidth/2+4+"px"; + } + if(this.$editable){ + this.$lineData[id].alt=true; + } + } + else if(type==="area"){//如果是分组区域 + if(!this.$areaData[id]) return; + if(this.$areaData[id].name===name) return; + if(typeof this.onItemRename==='function' && this.onItemRename(id,name,"node")===false) return; + oldName=this.$areaData[id].name; + this.$areaData[id].name=name; + this.$areaDom[id].children("label").text(name); + if(this.$editable){ + this.$areaData[id].alt=true; + } + } + if(this.$undoStack){ + var paras=[id,oldName,type]; + this.pushOper("setName",paras); + } + }, + //设置结点的尺寸,仅支持非开始/结束结点 + resizeNode:function(id,width,height){ + if(!this.$nodeData[id]) return; + if(typeof this.onItemResize==='function' && this.onItemResize(id,"node",width,height)===false) return; + if(this.$nodeData[id].type==="start"||this.$nodeData[id].type==="end")return; + if(this.$undoStack){ + var paras=[id,this.$nodeData[id].width,this.$nodeData[id].height]; + this.pushOper("resizeNode",paras); + } + + this.$nodeDom[id].children("table").css({width:(width-2)*this.$scale+"px",height:(height-2)*this.$scale+"px"}); + //确保因内部文字太多而撑大时,宽高尺寸仍然是精确的 + width=this.$nodeDom[id].outerWidth(); + height=this.$nodeDom[id].outerHeight(); + this.$nodeDom[id].children("table").css({width:width-2+"px",height:height-2+"px"}); + //确保因内部文字太多而撑大时,宽高尺寸仍然是精确的 END + this.$nodeData[id].width=width; + this.$nodeData[id].height=height; + if(this.$editable){ + this.$nodeData[id].alt=true; + } + //重画转换线 + this.resetLines(id,this.$nodeData[id]); + this._node2Area(id); + }, + //删除结点 + delNode:function(id,trigger){ + if(!this.$nodeData[id]) return; + if(false!==trigger && typeof this.onItemDel==='function' && this.onItemDel(id,"node")===false) return; + //先删除可能的连线 + for(var k in this.$lineData){ + if(this.$lineData[k].from===id||this.$lineData[k].to===id){ + //this.$draw.removeChild(this.$lineDom[k]); + //delete this.$lineData[k]; + //delete this.$lineDom[k]; + this.delLine(k,false); + } + } + //再删除结点本身 + if(this.$undoStack){ + var paras=[id,this.$nodeData[id]]; + this.pushOper("addNode",paras); + } + delete this.$nodeData[id]; + this.$nodeDom[id].remove(); + delete this.$nodeDom[id]; + --this.$nodeCount; + if(this.$focus===id) this.$focus=""; + + if(this.$editable){ + //在回退新增操作时,如果节点ID以this.$id+"_node_"开头,则表示为本次编辑时新加入的节点,这些节点的删除不用加入到$deletedItem中 + //if(id.indexOf(this.$id+"_node_")<0) + this.$deletedItem[id]="node"; + } + }, + //设置流程图的名称 + setTitle:function(text){ + this.$title=text; + if(this.$head) this.$head.children("label").attr("title",text).text(text); + }, + //仅供内部使用:计算流程图的实际宽高(单位像素) + _suitSize:function(){ + var maxW=0,maxH=0; + for(var k1 in this.$nodeData){ + var node = this.$nodeData[k1]; + if(maxW < node.width+node.left){ + maxW = node.width+node.left; + } + if(maxH < node.height+node.top){ + maxH = node.height+node.top; + } + } + for(var k2 in this.$areaData){ + var area = this.$areaData[k2]; + if(maxW < area.width+area.left){ + maxW = area.width+area.left; + } + if(maxH < area.height+area.top){ + maxH = area.height+area.top; + } + } + for(var k3 in this.$lineData){ + var line = this.$lineData[k3]; + if(line.M && line.type==="lt" && maxW < line.M ){ + maxW = M+4; + } + if(line.M && line.type==="tb" && maxH < line.M ){ + maxH = M+4; + } + } + return {width:maxW,height:maxH} + + }, + //载入一组数据 + loadData:function(data){ + var t=this.$editable; + this.$editable=false; + if(data.title) this.setTitle(data.title); + if(data.initNum) this.$max=data.initNum; + for(var i in data.nodes) + this.addNode(i,data.nodes[i]); + for(var j in data.lines) + this.addLine(j,data.lines[j]); + for(var k in data.areas) + this.addArea(k,data.areas[k]); + this.$editable=t; + this.$deletedItem={}; + //自行重构工作区,使之大小自适应 + var width=this.$workArea.width(); + var height=this.$workArea.height(); + var max=this._suitSize(); + while(max.width>width){ + width+=this.$workExtendStep; + } + while(max.height>height){ + height+=this.$workExtendStep; + } + this.$workArea.css({height:height+"px",width:width+"px"}); + if(GooFlow.prototype.useSVG===""){ + this.$draw.coordsize = width+","+height; + } + this.$draw.style.width = width + "px"; + this.$draw.style.height = height + "px"; + if(this.$group!=null){ + this.$group.css({height:height+"px",width:width+"px"}); + } + }, + //用AJAX方式,远程读取一组数据 + //参数para为JSON结构,与JQUERY中$.ajax()方法的传参一样 + loadDataAjax:function(para){ + var This=this; + $.ajax({ + type:para.type, + url:para.url, + dataType:"json", + data:para.data, + success: function(msg){ + if(para['dataFilter']) para['dataFilter'](msg,"json"); + This.loadData(msg); + if(para.success) para.success(msg); + }, + error: function(XMLHttpRequest, textStatus, errorThrown){ + if(para.error) para.error(textStatus,errorThrown); + } + }) + }, + //把画好的整个流程图导出到一个变量中(其实也可以直接访问GooFlow对象的$nodeData,$lineData,$areaData这三个JSON属性) + exportData:function(){ + var ret={}; + ret.title=this.$title; + ret.nodes={}; + ret.lines={}; + ret.areas={}; + ret.initNum=this.$max; + for(var k1 in this.$nodeData){ + if(!this.$nodeData[k1].marked){ + delete this.$nodeData[k1]["marked"]; + } + ret.nodes[k1]=JSON.parse(JSON.stringify(this.$nodeData[k1])); + } + for(var k2 in this.$lineData){ + if(!this.$lineData[k2].marked){ + delete this.$lineData[k2]["marked"]; + } + ret.lines[k2]=JSON.parse(JSON.stringify(this.$lineData[k2])); + } + for(var k3 in this.$areaData){ + if(!this.$areaData[k3].marked){ + delete this.$areaData[k3]["marked"]; + } + ret.areas[k3]=JSON.parse(JSON.stringify(this.$areaData[k3])); + } + return ret; + }, + //只把本次编辑流程图中作了变更(包括增删改)的元素导出到一个变量中,以方便用户每次编辑载入的流程图后只获取变更过的数据 + exportAlter:function(){ + var ret={nodes:{},lines:{},areas:{}}; + for(var k1 in this.$nodeData){ + if(this.$nodeData[k1].alt){ + ret.nodes[k1]=this.$nodeData[k1]; + } + } + for(var k2 in this.$lineData){ + if(this.$lineData[k2].alt){ + ret.lines[k2]=this.$lineData[k2]; + } + } + for(var k3 in this.$areaData){ + if(this.$areaData[k3].alt){ + ret.areas[k3]=this.$areaData[k3]; + } + } + ret.deletedItem=this.$deletedItem; + return ret; + }, + //变更元素的ID,一般用于快速保存后,将后台返回新元素的ID更新到页面中;type为元素类型(节点,连线,区块) + transNewId:function(oldId,newId,type){ + var tmp; + switch(type){ + case "node": + if(this.$nodeData[oldId]){ + tmp=this.$nodeData[oldId]; + delete this.$nodeData[oldId]; + this.$nodeData[newId]=tmp; + tmp=this.$nodeDom[oldId].attr("id",newId); + delete this.$nodeDom[oldId]; + this.$nodeDom[newId]=tmp; + } + break; + case "line": + if(this.$lineData[oldId]){ + tmp=this.$lineData[oldId]; + delete this.$lineData[oldId]; + this.$lineData[newId]=tmp; + tmp=this.$lineDom[oldId].attr("id",newId); + delete this.$lineDom[oldId]; + this.$lineDom[newId]=tmp; + } + break; + case "area": + if(this.$areaData[oldId]){ + tmp=this.$areaData[oldId]; + delete this.$areaData[oldId]; + this.$areaData[newId]=tmp; + tmp=this.$areaDom[oldId].attr("id",newId); + delete this.$areaDom[oldId]; + this.$areaDom[newId]=tmp; + } + break; + } + }, + //清空工作区及已载入的数据 + clearData:function(){ + for(var k1 in this.$nodeData){ + this.delNode(k1); + } + for(var k2 in this.$lineData){ + this.delLine(k2); + } + for(var k3 in this.$areaData){ + this.delArea(k3); + } + this.$deletedItem={}; + }, + //销毁自己 + destrory:function(){ + this.$bgDiv.empty(); + this.$lineData=null; + this.$nodeData=null; + this.$lineDom=null; + this.$nodeDom=null; + this.$areaDom=null; + this.$areaData=null; + this.$nodeCount=0; + this.$areaCount=0; + this.$areaCount=0; + this.$deletedItem={}; + }, +///////////以下为有关画线的方法 + //绘制一条箭头线,并返回线的DOM + drawLine:function(id,sp,ep,mark,dash,$scale){ + var line,text; + var x=(ep[0]+sp[0])/2, y=(ep[1]+sp[1])/2; + if(GooFlow.prototype.useSVG!==""){ + line=document.createElementNS("http://www.w3.org/2000/svg","g"); + var hi=document.createElementNS("http://www.w3.org/2000/svg","path"); + var path=document.createElementNS("http://www.w3.org/2000/svg","path"); + + if(id!=="") line.setAttribute("id",id); + line.setAttribute("from",sp[0]+","+sp[1]); + line.setAttribute("to",ep[0]+","+ep[1]); + hi.setAttribute("visibility","hidden"); + hi.setAttribute("stroke-width",'9'); + hi.setAttribute("fill","none"); + hi.setAttribute("stroke","white"); + hi.setAttribute("d","M "+sp[0]+" "+sp[1]+" L "+ep[0]+" "+ep[1]); + hi.setAttribute("pointer-events","stroke"); + path.setAttribute("d","M "+sp[0]+" "+sp[1]+" L "+ep[0]+" "+ep[1]); + path.setAttribute("stroke-width",mark? '2.4':'1.4'); + path.setAttribute("stroke-linecap","round"); + path.setAttribute("fill","none"); + if(dash) path.setAttribute("style", "stroke-dasharray:6,5"); + if(mark){ + path.setAttribute("stroke",GooFlow.color.mark); + path.setAttribute("marker-end","url(#arrow2)"); + } + else{ + path.setAttribute("stroke",GooFlow.color.line); + path.setAttribute("marker-end","url(#arrow1)"); + } + line.appendChild(hi); + line.appendChild(path); + line.style.cursor="crosshair"; + if(id!==""&&id!=="GooFlow_tmp_line"){ + text=document.createElementNS("http://www.w3.org/2000/svg","text"); + text.setAttribute("fill",GooFlow.color.lineFont); + line.appendChild(text); + + text.setAttribute("text-anchor","middle"); + text.setAttribute("x",x+''); + text.setAttribute("y",y+''); + text.style.cursor="text"; + text.style.fontSize=14*$scale+"px"; + line.style.cursor="pointer"; + } + }else{ + line=document.createElement("v:polyline"); + if(id!=="") line.id=id; + //line.style.position="absolute"; + line.points.value=sp[0]+","+sp[1]+" "+ep[0]+","+ep[1]; + line.setAttribute("fromTo",sp[0]+","+sp[1]+","+ep[0]+","+ep[1]); + line.strokeWeight="1.2"; + line.stroke.EndArrow="Block"; + line.style.cursor="crosshair"; + if(id!==""&&id!=="GooFlow_tmp_line"){ + text=document.createElement("div"); + //text.innerHTML=id; + line.appendChild(text); + if(x<0) x=x*-1; + if(y<0) y=y*-1; + text.style.left=x+"px"; + text.style.top=y-6+"px"; + text.style.color=GooFlow.color.lineFont; + text.style.fontSize=14*$scale+"px"; + line.style.cursor="pointer"; + } + if(dash) line.stroke.dashStyle="Dash"; + if(mark) line.strokeColor=GooFlow.color.mark; + else line.strokeColor=GooFlow.color.line; + line.fillColor=GooFlow.color.line; + } + return line; + }, + //画一条只有两个中点的折线 + drawPoly:function(id,sp,m1,m2,ep,mark,dash,$scale){ + var poly,strPath, text; + var x=(m2[0]+m1[0])/2, y=(m2[1]+m1[1])/2; + if(GooFlow.prototype.useSVG!==""){ + poly=document.createElementNS("http://www.w3.org/2000/svg","g"); + var hi=document.createElementNS("http://www.w3.org/2000/svg","path"); + var path=document.createElementNS("http://www.w3.org/2000/svg","path"); + if(id!=="") poly.setAttribute("id",id); + poly.setAttribute("from",sp[0]+","+sp[1]); + poly.setAttribute("to",ep[0]+","+ep[1]); + hi.setAttribute("visibility","hidden"); + hi.setAttribute("stroke-width",'9'); + hi.setAttribute("fill","none"); + hi.setAttribute("stroke","white"); + strPath="M "+sp[0]+" "+sp[1]; + if(m1[0]!==sp[0]||m1[1]!==sp[1]) + strPath+=" L "+m1[0]+" "+m1[1]; + if(m2[0]!==ep[0]||m2[1]!==ep[1]) + strPath+=" L "+m2[0]+" "+m2[1]; + strPath+=" L "+ep[0]+" "+ep[1]; + hi.setAttribute("d",strPath); + hi.setAttribute("pointer-events","stroke"); + path.setAttribute("d",strPath); + path.setAttribute("stroke-width",mark? '2.4':'1.4'); + path.setAttribute("stroke-linecap","round"); + path.setAttribute("fill","none"); + if(dash) path.setAttribute("style", "stroke-dasharray:6,5"); + if(mark){ + path.setAttribute("stroke",GooFlow.color.mark); + path.setAttribute("marker-end","url(#arrow2)"); + } + else{ + path.setAttribute("stroke",GooFlow.color.line); + path.setAttribute("marker-end","url(#arrow1)"); + } + poly.appendChild(hi); + poly.appendChild(path); + text=document.createElementNS("http://www.w3.org/2000/svg","text"); + text.setAttribute("fill",GooFlow.color.lineFont); + poly.appendChild(text); + text.setAttribute("text-anchor","middle"); + text.setAttribute("x",x+''); + text.setAttribute("y",y+''); + text.style.cursor="text"; + } + else{ + poly=document.createElement("v:Polyline"); + if(id!=="") poly.id=id; + poly.filled="false"; + strPath=sp[0]+","+sp[1]; + if(m1[0]!==sp[0]||m1[1]!==sp[1]) + strPath+=" "+m1[0]+","+m1[1]; + if(m2[0]!==ep[0]||m2[1]!==ep[1]) + strPath+=" "+m2[0]+","+m2[1]; + strPath+=" "+ep[0]+","+ep[1]; + poly.points.value=strPath; + poly.setAttribute("fromTo",sp[0]+","+sp[1]+","+ep[0]+","+ep[1]); + poly.strokeWeight=mark? "2.4":"1.2"; + poly.stroke.EndArrow="Block"; + text=document.createElement("div"); + //text.innerHTML=id; + poly.appendChild(text); + if(x<0) x=x*-1; + if(y<0) y=y*-1; + text.style.left=x+"px"; + text.style.top=y-4+"px"; + text.style.color=GooFlow.color.lineFont; + if(dash) poly.stroke.dashStyle="Dash"; + if(mark) poly.strokeColor=GooFlow.color.mark; + else poly.strokeColor=GooFlow.color.line; + } + poly.style.cursor="pointer"; + text.style.fontSize=14*$scale+"px"; + return poly; + }, + //原lineData已经设定好的情况下,只在绘图工作区画一条线的页面元素 + addLineDom:function(id,lineData){ + var n1=this.$nodeData[lineData.from],n2=this.$nodeData[lineData.to];//获取开始/结束结点的数据 + if(!n1||!n2) return; + //开始计算线端点坐标 + var res; + if(lineData.type&&lineData.type!=="sl") + res=calcPolyPoints(n1,n2,lineData.type,lineData.M, this.$scale); + else + res=calcStartEnd(n1,n2, this.$scale); + if(!res) return; + + if(lineData.type==="sl") + this.$lineDom[id]=GooFlow.prototype.drawLine(id,res.start,res.end,lineData.marked,lineData.dash, this.$scale); + else + this.$lineDom[id]=GooFlow.prototype.drawPoly(id,res.start,res.m1,res.m2,res.end,lineData.marked,lineData.dash, this.$scale); + this.$draw.appendChild(this.$lineDom[id]); + if(GooFlow.prototype.useSVG===""){ + this.$lineDom[id].childNodes[1].innerHTML=lineData.name; + if(lineData.type!=="sl"){ + var Min=(res.start[0]>res.end[0]? res.end[0]:res.start[0]); + if(Min>res.m2[0]) Min=res.m2[0]; + if(Min>res.m1[0]) Min=res.m1[0]; + this.$lineDom[id].childNodes[1].style.left = (res.m2[0]+res.m1[0])/2-Min-this.$lineDom[id].childNodes[1].offsetWidth/2+4; + Min=(res.start[1]>res.end[1]? res.end[1]:res.start[1]); + if(Min>res.m2[1]) Min=res.m2[1]; + if(Min>res.m1[1]) Min=res.m1[1]; + this.$lineDom[id].childNodes[1].style.top = (res.m2[1]+res.m1[1])/2-Min-this.$lineDom[id].childNodes[1].offsetHeight/2; + }else + this.$lineDom[id].childNodes[1].style.left= + ((res.end[0]-res.start[0])*(res.end[0]>res.start[0]? 1:-1)-this.$lineDom[id].childNodes[1].offsetWidth)/2+4; + } + else{ + this.$lineDom[id].childNodes[2].textContent=lineData.name; + } + }, + //增加一条线 + addLine:function(id,json){ + if(typeof this.onItemAdd==='function' && this.onItemAdd(id,"line",json)===false)return; + if(this.$undoStack&&this.$editable){ + this.pushOper("delLine",[id]); + } + if(json.from===json.to) return; + var n1=this.$nodeData[json.from],n2=this.$nodeData[json.to];//获取开始/结束结点的数据 + if(!n1||!n2) return; + //避免两个节点间不能有一条以上同向接连线 + for(var k in this.$lineData){ + if((json.from===this.$lineData[k].from&&json.to===this.$lineData[k].to&&json.dash===this.$lineData[k].dash)) + return; + } + //设置$lineData[id] + this.$lineData[id]={}; + if(json.type){ + this.$lineData[id].type=json.type; + this.$lineData[id].M=json.M; + } + else this.$lineData[id].type="sl";//默认为直线 + this.$lineData[id].from=json.from; + this.$lineData[id].to = json.to; + this.$lineData[id].setInfo = json.setInfo; + this.$lineData[id].name=json.name; + if(json.marked) this.$lineData[id].marked=json.marked; + else this.$lineData[id].marked=false; + if(json.dash) this.$lineData[id].dash=json.dash; + else this.$lineData[id].dash=false; + //设置$lineData[id]完毕 + + this.addLineDom(id,this.$lineData[id]); + + ++this.$lineCount; + if(this.$editable){ + this.$lineData[id].alt=true; + if(this.$deletedItem[id]) delete this.$deletedItem[id];//在回退删除操作时,去掉该元素的删除记录 + } + }, + //重构所有连向某个结点的线的显示,传参结构为$nodeData数组的一个单元结构 + resetLines:function(id,node){ + for(var i in this.$lineData){ + var other=null;//获取结束/开始结点的数据 + var res; + if(this.$lineData[i].from===id){//找结束点 + other=this.$nodeData[this.$lineData[i].to]||null; + if(other==null) continue; + if(this.$lineData[i].type==="sl") + res=calcStartEnd(node,other, this.$scale); + else + res=calcPolyPoints(node,other,this.$lineData[i].type,this.$lineData[i].M, this.$scale); + if(!res) break; + } + else if(this.$lineData[i].to===id){//找开始点 + other=this.$nodeData[this.$lineData[i].from]||null; + if(other==null) continue; + if(this.$lineData[i].type==="sl") + res=calcStartEnd(other,node, this.$scale); + else + res=calcPolyPoints(other,node,this.$lineData[i].type,this.$lineData[i].M, this.$scale); + if(!res) break; + } + if(other==null) continue; + this.$draw.removeChild(this.$lineDom[i]); + if(this.$lineData[i].type==="sl"){ + this.$lineDom[i]=GooFlow.prototype.drawLine(i,res.start,res.end,this.$lineData[i].marked,this.$lineData[i].dash, this.$scale); + } + else{ + this.$lineDom[i]=GooFlow.prototype.drawPoly(i,res.start,res.m1,res.m2,res.end,this.$lineData[i].marked,this.$lineData[i].dash, this.$scale); + } + this.$draw.appendChild(this.$lineDom[i]); + if(GooFlow.prototype.useSVG===""){ + this.$lineDom[i].childNodes[1].innerHTML=this.$lineData[i].name; + if(this.$lineData[i].type!=="sl"){ + var Min=(res.start[0]>res.end[0]? res.end[0]:res.start[0]); + if(Min>res.m2[0]) Min=res.m2[0]; + if(Min>res.m1[0]) Min=res.m1[0]; + this.$lineDom[i].childNodes[1].style.left = (res.m2[0]+res.m1[0])/2-Min-this.$lineDom[i].childNodes[1].offsetWidth/2+4; + Min=(res.start[1]>res.end[1]? res.end[1]:res.start[1]); + if(Min>res.m2[1]) Min=res.m2[1]; + if(Min>res.m1[1]) Min=res.m1[1]; + this.$lineDom[i].childNodes[1].style.top = (res.m2[1]+res.m1[1])/2-Min-this.$lineDom[i].childNodes[1].offsetHeight/2-4; + }else + this.$lineDom[i].childNodes[1].style.left= + ((res.end[0]-res.start[0])*(res.end[0]>res.start[0]? 1:-1)-this.$lineDom[i].childNodes[1].offsetWidth)/2+4; + } + else this.$lineDom[i].childNodes[2].textContent=this.$lineData[i].name; + } + }, + //重新设置连线的样式 newType= "sl":直线, "lr":中段可左右移动型折线, "tb":中段可上下移动型折线 + setLineType:function(id,newType,M){ + if(!newType||newType==null||newType===""||newType===this.$lineData[id].type) return false; + if(typeof this.onLineSetType==='function' && this.onLineSetType(id,newType)===false) return; + if(this.$undoStack){ + var paras=[id,this.$lineData[id].type,this.$lineData[id].M]; + this.pushOper("setLineType",paras); + } + var from=this.$lineData[id].from; + var to=this.$lineData[id].to; + this.$lineData[id].type=newType; + var res; + //如果是变成折线 + if(newType!=="sl"){ + //res=calcPolyPoints(this.$nodeData[from],this.$nodeData[to],this.$lineData[id].type,this.$lineData[id].M, this.$scale); + if(M){ + this.setLineM(id,M,true); + }else{ + this.setLineM(id,getMValue(this.$nodeData[from],this.$nodeData[to],newType),true); + } + } + //如果是变回直线 + else{ + delete this.$lineData[id].M; + this.$lineMove.hide().removeData("type").removeData("tid"); + res=calcStartEnd(this.$nodeData[from],this.$nodeData[to], this.$scale); + if(!res) return; + this.$draw.removeChild(this.$lineDom[id]); + this.$lineDom[id]=GooFlow.prototype.drawLine(id,res.start,res.end,this.$lineData[id].marked,this.$lineData[id].dash, this.$scale); + this.$draw.appendChild(this.$lineDom[id]); + if(GooFlow.prototype.useSVG===""){ + this.$lineDom[id].childNodes[1].innerHTML=this.$lineData[id].name; + this.$lineDom[id].childNodes[1].style.left= + ((res.end[0]-res.start[0])*(res.end[0]>res.start[0]? 1:-1)-this.$lineDom[id].childNodes[1].offsetWidth)/2+4; + } + else + this.$lineDom[id].childNodes[2].textContent=this.$lineData[id].name; + } + if(this.$focus===id){ + this.focusItem(id); + } + if(this.$editable){ + this.$lineData[id].alt=true; + } + }, + //设置折线中段的X坐标值(可左右移动时)或Y坐标值(可上下移动时) + setLineM:function(id,M,noStack){ + if(!this.$lineData[id]||M<0||!this.$lineData[id].type||this.$lineData[id].type==="sl") return false; + if(typeof this.onLineMove==='function' && this.onLineMove(id,M)===false) return false; + if(this.$undoStack&&!noStack){ + var paras=[id,this.$lineData[id].M]; + this.pushOper("setLineM",paras); + } + var from=this.$lineData[id].from; + var to=this.$lineData[id].to; + this.$lineData[id].M=M; + var ps=calcPolyPoints(this.$nodeData[from],this.$nodeData[to],this.$lineData[id].type,this.$lineData[id].M, this.$scale); + this.$draw.removeChild(this.$lineDom[id]); + this.$lineDom[id]=GooFlow.prototype.drawPoly(id,ps.start,ps.m1,ps.m2,ps.end,this.$lineData[id].marked,this.$lineData[id].dash, this.$scale); + this.$draw.appendChild(this.$lineDom[id]); + if(GooFlow.prototype.useSVG===""){ + this.$lineDom[id].childNodes[1].innerHTML=this.$lineData[id].name; + var Min=(ps.start[0]>ps.end[0]? ps.end[0]:ps.start[0]); + if(Min>ps.m2[0]) Min=ps.m2[0]; + if(Min>ps.m1[0]) Min=ps.m1[0]; + this.$lineDom[id].childNodes[1].style.left = (ps.m2[0]+ps.m1[0])/2-Min-this.$lineDom[id].childNodes[1].offsetWidth/2+4; + Min=(ps.start[1]>ps.end[1]? ps.end[1]:ps.start[1]); + if(Min>ps.m2[1]) Min=ps.m2[1]; + if(Min>ps.m1[1]) Min=ps.m1[1]; + this.$lineDom[id].childNodes[1].style.top = (ps.m2[1]+ps.m1[1])/2-Min-this.$lineDom[id].childNodes[1].offsetHeight/2-4; + } + else this.$lineDom[id].childNodes[2].textContent=this.$lineData[id].name; + if(this.$editable){ + this.$lineData[id].alt=true; + } + }, + //删除转换线 + delLine:function(id,trigger){ + if(!this.$lineData[id]) return; + if(false!==trigger && typeof this.onItemDel==='function' && this.onItemDel(id,"node")===false) return; + if(this.$undoStack){ + var paras=[id,this.$lineData[id]]; + this.pushOper("addLine",paras); + } + this.$draw.removeChild(this.$lineDom[id]); + delete this.$lineData[id]; + delete this.$lineDom[id]; + if(this.$focus===id) this.$focus=""; + --this.$lineCount; + if(this.$editable){ + //在回退新增操作时,如果节点ID以this.$id+"_line_"开头,则表示为本次编辑时新加入的节点,这些节点的删除不用加入到$deletedItem中 + // if(id.indexOf(this.$id+"_line_")<0) + this.$deletedItem[id]="line"; + this.$mpFrom.hide().removeData("p"); + this.$mpTo.hide().removeData("p"); + } + if(this.$lineOper){ + this.$lineOper.hide().removeData("tid"); + } + }, + //变更连线两个端点所连的结点 + //参数:要变更端点的连线ID,新的开始结点ID、新的结束结点ID;如果开始/结束结点ID是传入null或者"",则表示原端点不变 + moveLinePoints:function(lineId, newStart, newEnd, noStack){ + if(newStart===newEnd) return; + if(!lineId||!this.$lineData[lineId]) return; + if(newStart==null||newStart==="") + newStart=this.$lineData[lineId].from; + if(newEnd==null||newEnd==="") + newEnd=this.$lineData[lineId].to; + + //避免两个节点间不能有一条以上同向接连线 + for(var k in this.$lineData){ + if((newStart===this.$lineData[k].from&&newEnd===this.$lineData[k].to)) + return; + } + if(typeof this.onLinePointMove==='function' && this.onLinePointMove(lineId,newStart,newEnd)===false) return; + if(this.$undoStack&&!noStack){ + var paras=[lineId,this.$lineData[lineId].from,this.$lineData[lineId].to]; + this.pushOper("moveLinePoints",paras); + } + if(newStart!=null&&newStart!==""){ + this.$lineData[lineId].from=newStart; + } + if(newEnd!=null&&newEnd!==""){ + this.$lineData[lineId].to=newEnd; + } + //重建转换线 + this.$draw.removeChild(this.$lineDom[lineId]); + this.addLineDom(lineId,this.$lineData[lineId]); + if(this.$editable){ + this.$lineData[lineId].alt=true; + } + }, + + //用颜色标注/取消标注一个结点或转换线,常用于显示重点或流程的进度。 + //这是一个在编辑模式中无用,但是在纯浏览模式中非常有用的方法,实际运用中可用于跟踪流程的进度。 + markItem:function(id,type,mark){ + if(type==="node"){ + if(!this.$nodeData[id]) return; + if(typeof this.onItemMark==='function' && this.onItemMark(id,"node",mark)===false) return; + this.$nodeData[id].marked=mark||false; + if(mark){ + this.$nodeDom[id].addClass("item_mark").css("border-color",GooFlow.color.mark); + } + else{ + this.$nodeDom[id].removeClass("item_mark"); + if(id!==this.$focus) this.$nodeDom[id].css("border-color","transparent"); + } + + }else if(type==="line"){ + if(!this.$lineData[id]) return; + if(this.onItemMark!=null&&!this.onItemMark(id,"line",mark)) return; + this.$lineData[id].marked=mark||false; + if(GooFlow.prototype.useSVG!==""){ + if(mark){ + this.$lineDom[id].childNodes[1].setAttribute("stroke",GooFlow.color.mark); + this.$lineDom[id].childNodes[1].setAttribute("marker-end","url(#arrow2)"); + this.$lineDom[id].childNodes[1].setAttribute("stroke-width",2.4); + }else{ + this.$lineDom[id].childNodes[1].setAttribute("stroke",GooFlow.color.line); + this.$lineDom[id].childNodes[1].setAttribute("marker-end","url(#arrow1)"); + this.$lineDom[id].childNodes[1].setAttribute("stroke-width",1.4); + } + }else{ + if(mark){ + this.$lineDom[id].strokeColor=GooFlow.color.mark; + this.$lineDom[id].strokeWeight="2.4"; + } + else{ + this.$lineDom[id].strokeColor=GooFlow.color.line; + this.$lineDom[id].strokeWeight="1.2"; + } + } + } + if(this.$undoStack){ + var paras=[id,type,!mark]; + this.pushOper("markItem",paras); + } + }, + ////////////////////////以下为区域分组块操作 + //传入一个区域组(泳道)的ID,判断图中所有结点在此区域组(泳道)的范围内 + _areaFixNodes:function(areaId){ + var area=this.$areaData[areaId]; + for(var key in this.$nodeData){ + var node = this.$nodeData[key]; + if( node.left>=area.left&&node.left=area.top&&node.top
" + +"
"); + this.$areaData[id]=json; + this.$group.append(this.$areaDom[id]); + if(this.$nowType!=="group") this.$areaDom[id].children("div:eq(1)").css("display","none"); + ++this.$areaCount; + if(this.$editable){ + this.$areaData[id].alt=true; + this._areaFixNodes(id); + if(this.$deletedItem[id]) delete this.$deletedItem[id];//在回退删除操作时,去掉该元素的删除记录 + } + }, + //重构整个流程图设计器的宽高 + reinitSize:function(width,height){ + var w=(width||this.$bgDiv.width()); + var h=(height||this.$bgDiv.height()); + this.$bgDiv.css({height:h+"px",width:w+"px"}); + var headHeight=0,hack=8; + if(this.$head!=null){ + headHeight=26; + hack=5; + } + if(this.$tool!=null){ + this.$tool.css({height:h-headHeight-hack+"px"}); + w-=31; + } + w-=9; + h=h-headHeight-(this.$head!=null? 5:8); + //this.$workArea.parent().css({height:h+"px",width:w+"px"}); + + if(this.$workArea.width()>w){ + w=this.$workArea.width(); + } + if(this.$workArea.height()>h){ + h=this.$workArea.height(); + } + + this.$workArea.css({height:h+"px",width:w+"px"}); + if(GooFlow.prototype.useSVG===""){ + this.$draw.coordsize = w+","+h; + } + this.$draw.style.width = w + "px"; + this.$draw.style.height = h + "px"; + if(this.$group!=null){ + this.$group.css({height:h+"px",width:w+"px"}); + } + }, + //重设整个工作区内容的显示缩放比例,从0.5至4倍 + resetScale:function(scale){ + if(!scale) scale=1.0; + else if(scale<0.5) scale=0.5; + else if(scale>4) scale=4; + //以上是固定死取值范围:不让用户缩放过大或过小,已免无意中影响的显示效果 + if(this.$scale===scale) return; + var oldS=this.$scale; + this.$scale=scale; + var factor = oldS/scale;//因数(旧缩放比例除以新缩放比例),元素的现有值除以该因子,就能得到新的缩放后的值 + var W=0,H=0,P={};//宽、高、左及上的临时变量 + //开始正式的缩放(节点、连线、泳道块有宽高和定位,其它编辑工具元素则只有定位)(全部以左上角为原点) + this.blurItem(); + //先缩放工作区 + W=this.$workArea.width()/factor; + H=this.$workArea.height()/factor; + this.$workArea.css({"height":H+"px","width":W+"px"}); + if(GooFlow.prototype.useSVG!==""){ + + }else{ + this.$draw.coordsize = W+","+H; + } + this.$draw.style.width = W + "px"; + this.$draw.style.height = H + "px"; + if(this.$group!=null){ + this.$group.css({height:H+"px",width:W+"px"}); + } + //缩放节点 + var isWebkit = navigator.userAgent.toLowerCase().indexOf('webkit') > -1; + this.$workArea.children(".GooFlow_item").each(function(){ + var This=$(this); + P=This.position(); + This.css({ "left":P.left/factor+"px", "top":P.top/factor+"px" }); + This=This.children("table"); + W=This.outerWidth()/factor; + H=This.outerHeight()/factor; + This.css({ "width":W+"px", "height":H+"px" }); + var tmp=18*scale; + This.find("td[class='ico']").css({width:tmp+"px"}); + var newSize= {}; + if(tmp<12&&isWebkit){ + newSize["width"]="18px";newSize["height"]="18px"; + newSize["font-size"]="18px"; + newSize["transform"]="scale("+(tmp/18)+")"; + newSize["margin"]=-((18-tmp)/2)+"px"; + }else{ + newSize["width"]=tmp+"px"; newSize["height"]=tmp+"px"; + newSize["font-size"]=tmp+"px"; + newSize["transform"]="none"; + newSize["margin"]="0px auto"; + } + This.find("td[class='ico']").children("i").css(newSize); + + tmp=14*scale; + if(This.parent().find(".span").length===1){ + This.parent().css("border-radius",W/2+"px"); + This=This.parent().find(".span"); + This.css({"font-size":tmp+"px"}); + }else{ + This=This.find("td:eq(1) div"); + newSize={}; + if(tmp<12&&isWebkit){ + newSize["font-size"]="14px"; + newSize["transform"]="scale("+(tmp/14)+")"; + var mW=(W/scale-18-(W-18*scale))/2; + var mH=(H/scale-H)/2; + newSize["margin"]=-mH+"px "+(-mW)+"px"; + }else{ + newSize["transform"]="none"; + newSize["font-size"]=tmp+"px"; + newSize["margin"]="0px"; + } + This.css(newSize); + } + }); + //缩放区域图 + var ifs=16*scale+2; + this.$group.children(".GooFlow_area").each(function(){ + var This=$(this); + P=This.position(); + This.css({ "left":P.left/factor+"px", "top":P.top/factor+"px" }); + This=This.children("div:eq(0)"); + W=This.outerWidth()/factor; + H=This.outerHeight()/factor; + This.css({ "width":W+"px", "height":H+"px" }); + This.next("label").css({ + "font-size": 14*scale+"px", + "left": ifs+3+"px" + }).next("i").css({ + "font-size": ifs-2+"px", + width:ifs+"px", + height:ifs+"px", + "line-height":ifs+"px" + }); + }); + //缩放连线 + for(var id in this.$lineDom){ + this.$draw.removeChild(this.$lineDom[id]); + delete this.$lineDom[id]; + } + for (var key in this.$lineData) { + this.addLineDom(key, this.$lineData[key]); + } + } +}; +//默认的颜色样式 +GooFlow.color={ + //main:"#20A0FF", + font:"#15428B", + node:"#C0CCDA", + line:"#1D8CE0", + lineFont:"#777", + mark:"#ff8800", + mix:"#B6F700", + mixFont:"#777" +}; + //默认的文字说明注释内容 +GooFlow.remarks={ + headBtns:{}, + toolBtns:{}, + extendRight:undefined, + extendBottom:undefined +}; +//当不想使用jquery插件式初始化方法时,另一种通过直接调用GooFlow内部构造方法进行的初始化 +GooFlow.init=function(selector,property){ + return new GooFlow(selector,property); +}; +//在初始化出一个对象前的公用方法:覆盖设定GooFlow默认的颜色定义 +GooFlow.setColors=function(colors){ + $.extend(GooFlow.color,colors); +}; +//扩展GooFlow方法的扩展用接口,一般用在CMD,AMD +GooFlow.extend=function(json){ + for(var funcName in json){ + GooFlow.prototype[funcName]=json[funcName]; + } +}; +//将此类的构造函数加入至JQUERY对象中 +$.extend({ + createGooFlow:function(selector,property){ + return new GooFlow(selector,property); + } +}); + + exports('flow/gooflow'); + }); \ No newline at end of file diff --git a/OpenAuth.Mvc/js/flow/GooFlow.print.js b/OpenAuth.Mvc/js/flow/GooFlow.print.js new file mode 100644 index 00000000..4404b460 --- /dev/null +++ b/OpenAuth.Mvc/js/flow/GooFlow.print.js @@ -0,0 +1,207 @@ +/* + * 打印预览或另存为PDF功能,需要依赖: + * ../plugin/printThis.js + */ +;(function ( global, factory ) { + 'use strict'; + if ( typeof define !== 'undefined' && define.amd ) { // export as AMD... + define( ['jquery','GooFlow'], factory ); + } + else if ( typeof module !== 'undefined' && module.exports ) { // ...or as browserify + factory( require('jquery'), require('GooFlow') ); + }else + factory( global.$, global.GooFlow ); + +}( typeof window !== 'undefined' ? window : this, function ( $,GooFlow ) { + if(GooFlow.prototype.print && typeof GooFlow.prototype.print==='function'){ + return;//防止多次载入 + } +/* + * printThis v1.12.2 + * @desc Printing plug-in for jQuery + * @author Jason Day + * 精简版 only for GooFlow + */ + (function($) { + + function appendContent($el, content) { + if (!content) return; + + // Simple test for a jQuery element + $el.append(content.jquery ? content.clone() : content); + } + + function appendBody($body, $element, opt) { + // Clone for safety and convenience + // Calls clone(withDataAndEvents = true) to copy form values. + var $content = $element.clone(); + + if (opt.printContainer) { + // grab $.selector as container + $content.appendTo($body); + } else { + // otherwise just print interior elements of container + $content.each(function() { + $(this).children().appendTo($body) + }); + } + } + + var opt; + $.fn.printThis = function(options) { + opt = $.extend({}, $.fn.printThis.defaults, options); + var $element = this instanceof jQuery ? this : $(this); + + var strFrameName = "printThis-" + (new Date()).getTime(); + + if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) { + // Ugly IE hacks due to IE not inheriting document.domain from parent + // checks if document.domain is set by comparing the host name against document.domain + var iframeSrc = 'javascript:document.write("")'; + var printI = document.createElement('iframe'); + printI.name = "printIframe"; + printI.id = strFrameName; + printI.className = "MSIE"; + document.body.appendChild(printI); + printI.src = iframeSrc; + + } else { + // other browsers inherit document.domain, and IE works if document.domain is not explicitly set + var $frame = $("