瀏覽代碼

导出数据修改

lee 8 年之前
父節點
當前提交
09f470f086
共有 2 個文件被更改,包括 1251 次插入1205 次删除
  1. 10 0
      src/main/webapp/develop/lib/gooflow/css/GooFlow.css
  2. 1241 1205
      src/main/webapp/develop/lib/gooflow/js/GooFlow.js

+ 10 - 0
src/main/webapp/develop/lib/gooflow/css/GooFlow.css

@ -709,4 +709,14 @@ v\:group,v\:rect,v\:imagedata,v\:oval,v\:line,v\:polyline,v\:stroke,v\:textbox {
}
.line-error{
    stroke:#f00
}
.file-box{position:absolute;top:0;left:50px;
    z-index: 9999;}
.file-box input{
    margin: 20px;
    border: none;
    background: none;
    padding: 5px;
    border-bottom: 1px solid #333;
}

+ 1241 - 1205
src/main/webapp/develop/lib/gooflow/js/GooFlow.js

@ -68,6 +68,8 @@ function GooFlow(bgDiv, property) {
	this.$workAreaWrap = null;                  // 流程图区域容器
	this.$workArea = null;                      // 流程图区域
	this.$draw = null;                          // SVG绘制区
	this.$fileCode = '';                        // 流程图文件唯一标识
	this.$fileName = '';                        // 流程图文件名称
	// *************************************************** 【线条相关】
	this.$lineData = {};                        // 数据
@ -84,6 +86,7 @@ function GooFlow(bgDiv, property) {
	this.$nodeCount = 0;                        // 数量
	this.$nodeDom = {};                         // DOM
	this.$newNodeValue = '';                    // 值
	this.$nodeType = '';                        // 结点类型
	this.$deteNodeId = '';                      // 删除指定ID
	this.$ghost = null;                         // 结点镜像
@ -102,7 +105,7 @@ function GooFlow(bgDiv, property) {
	var URL = "http://localhost:8080",
		getAllEndpointsURL = URL + "/esb/process/getAllEndpoints",
		getAllProcessorsURL = URL + "/esb/process/getAllProcessors";
		dataPost = URL + "/esb/process/json";
		dataPostURL = URL + "/esb/process/json";
	/*
	 * Todo: 初始化布局 【初始化】
@ -234,7 +237,8 @@ function GooFlow(bgDiv, property) {
			htmlStr += "<div class='GooFlow_app_list_tit'>" + list[i].title + "</div>";
			htmlStr += "<div class='GooFlow_app_list_box'><ul>";
			for (var j = 0; j < list[i].list.length; j++) {
				htmlStr += "<li class='GooFlow_app_item' data ='" + list[i].list[j].value +
				htmlStr += "<li class='GooFlow_app_item' data-type='" + list[i].list[j].nodeType +
					"' data-value ='" + list[i].list[j].value +
					"'><div class='app_icon'></div> <div class='app_name'>" + list[i].list[j].name + "</div></li>"
			}
			htmlStr += "</ul></li>";
@ -268,7 +272,8 @@ function GooFlow(bgDiv, property) {
			htmlStr = '';
		htmlStr += "<li class='GooFlow_app_list_item'><div class='GooFlow_app_list_box'><ul>";
		for (var i = 0; i < list.length; i++) {
			htmlStr += "<li class='GooFlow_app_item' data='" + list[i].value +
			htmlStr += "<li class='GooFlow_app_item' data-type='" + list[i].nodeType +
				"' data-value='" + list[i].value +
				"'><div class='app_icon'></div> <div class='app_name'>" + list[i].name + "</div></li>"
		}
		htmlStr += "</ul></li>";
@ -329,7 +334,8 @@ function GooFlow(bgDiv, property) {
			}
			onDrag = true;
			that.$newNodeTxt = $(this).children('.app_name').text();
			that.$newNodeValue = $(this).attr('data');
			that.$newNodeValue = $(this).attr('data-value');
			that.$nodeType = $(this).attr('data-type');
		});
		$(document).mouseup(function () {
			onDrag = false;
@ -500,56 +506,60 @@ function GooFlow(bgDiv, property) {
 * time: 14:59
 * */
GooFlow.prototype = {
	useSVG: true,
    useSVG: true,
	/*
	 * Todo: 初始化画布 【SVG & 箭头 UI相关】
	 * Author: LE
	 * Date: 2017/2/20
	 * time: 9:51
	 * */
	initDraw: function (id) {
		this.$workAreaWrap = $("<div class='GooFlow_work'></div>");
		this.$workArea = $("<div class='GooFlow_work_inner'></div>").attr({
			"unselectable": "on",
			"onselectstart": 'return false',
			"onselect": 'document.selection.empty()'
		});
		this.$workAreaWrap.append(this.$workArea);
		this.$contBox.append(this.$workAreaWrap);
		this.$draw = document.createElementNS("http://www.w3.org/2000/svg", "svg");
		this.$workArea.prepend(this.$draw);
		// 设置画布属性
		this.$draw.id = id;
		this.$draw.style.width = '100%';
		this.$draw.style.height = '100%';
		// 定义可以重复利用的元素
		var defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
		this.$draw.appendChild(defs);
		defs.appendChild(getSvgMarker("arrow1", "#323232"));
		defs.appendChild(getSvgMarker("arrow2", "#00b7ee"));
		defs.appendChild(getSvgMarker("arrow3", "#f00"));
		function getSvgMarker(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", 8);
			m.setAttribute("markerHeight", 8);
			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  L 2 3 z");
			path.setAttribute("fill", color);
			path.setAttribute("stroke-width", 2);
			m.appendChild(path);
			return m;
		}
	},
    initDraw: function (id) {
        this.$workAreaWrap = $("<div class='GooFlow_work'></div>");
        this.$workArea = $("<div class='GooFlow_work_inner'></div>").attr({
            "unselectable": "on",
            "onselectstart": 'return false',
            "onselect": 'document.selection.empty()'
        });
        this.$workAreaWrap.append(this.$workArea);
        this.$contBox.append(this.$workAreaWrap);
        this.$draw = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        this.$workArea.prepend(this.$draw);
        this.$workArea.prepend("<div class='file-box'>Code:<input id='fileCode' value='" + this.$fileCode +
			"'>Name:<input id='fileName' value='" + this.$fileName +
			"'></div>")
        // 设置画布属性
        this.$draw.id = id;
        this.$draw.style.width = '100%';
        this.$draw.style.height = '100%';
        // 定义可以重复利用的元素
        var defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
        this.$draw.appendChild(defs);
        defs.appendChild(getSvgMarker("arrow1", "#323232"));
        defs.appendChild(getSvgMarker("arrow2", "#00b7ee"));
        defs.appendChild(getSvgMarker("arrow3", "#f00"));
        function getSvgMarker(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", 8);
            m.setAttribute("markerHeight", 8);
            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  L 2 3 z");
            path.setAttribute("fill", color);
            path.setAttribute("stroke-width", 2);
            m.appendChild(path);
            return m;
        }
    },
	/*
	 * Todo: ### 初始化事件绑定********************************--开始
@ -557,10 +567,10 @@ GooFlow.prototype = {
	 * Date: 2017/2/15
	 * time: 15:09
	 * */
	initEvents: function () {
		// 防止回调函数里this偏移
		var that = this;
		var timeId = null;
    initEvents: function () {
        // 防止回调函数里this偏移
        var that = this;
        var timeId = null;
		/*
		 * Todo: 空白区域点击事件 【单击事件】
@ -568,13 +578,13 @@ GooFlow.prototype = {
		 * Date: 2017/2/20
		 * time: 10:05
		 * */
		$(this.$draw).on("click", function (e) {
			that.$canDelLine = false;
			var n = $(e.target).prop("tagName");
			if (n == "svg") {
				that.blurItem();
			}
		});
        $(this.$draw).on("click", function (e) {
            that.$canDelLine = false;
            var n = $(e.target).prop("tagName");
            if (n == "svg") {
                that.blurItem();
            }
        });
		/*
		 * Todo: 结点事件绑定 【@@】
@ -582,180 +592,182 @@ GooFlow.prototype = {
		 * Date: 2017/2/20
		 * time: 10:22
		 * */
		this.$workArea.on({
			// 选中
			click:function () {
				clearTimeout(timeId);
				var Dom = $(this);
				var id = Dom.attr("id");
				that.focusItem(id, true);
			},
			// 编辑
			dblclick:function () {
				var id = $(this).attr('id'),
					oldTxt = that.$nodeData[id].param,
					objPosition = $(this).position(),
					objLeft = objPosition.left,
					objTop =  objPosition.top;
				// 编辑的时候禁止delete键删除
				that.$canDelLine = false;
				that.$deteNodeId = '';
				that.$deteLineId = '';
				var thisType = that.$nodeData[id].type;
				if (thisType != 'start' && thisType != 'task') {
					clearTimeout(timeId);
					that.$textArea.val(oldTxt).css({
						display: "block",
						left: objLeft+170,
						top: objTop+50
					}).data("id", that.$focus).focus();
					that.$workArea.parent().one("mousedown", function () {
						that.setName(that.$textArea.data("id"), that.$textArea.val(), "node");
						that.$textArea.val("").removeData("id").hide();
					});
				}
			},
			// 移动
			mousedown:function (e) {
				if (!e) e = window.event;
				var Dom = $(this);
				var id = Dom.attr("id");
				clearTimeout(timeId);
				timeId = setTimeout(function () {
					var ev = GooFunc.mousePosition(e),
						t = GooFunc.getElCoordinate(that.$workArea[0]),
						c = GooFunc.getElCoordinate(that.$MainContener);
					that.$ghost.css({
						display: "block",
						top: that.$nodeData[id].top + 133 - that.$workArea[0].parentNode.scrollTop + "px",
						left: that.$nodeData[id].left + 200 - that.$workArea[0].parentNode.scrollLeft + "px",
						cursor: "move"
					});
					var X, Y;
					X = ev.x - t.left + that.$workArea[0].parentNode.scrollLeft;
					Y = ev.y - t.top + that.$workArea[0].parentNode.scrollTop;
					var vX = X - that.$nodeData[id].left, vY = Y - that.$nodeData[id].top;
					var isMove = false;
					document.onmousemove = function (e) {
						if (!e) {e = window.event;}
						var ev = GooFunc.mousePosition(e);
						X = ev.x - vX - c.left;
						Y = ev.y - vY - c.top;
						if (X < t.left - c.left - that.$workArea[0].parentNode.scrollLeft) {
							X = t.left - c.left - that.$workArea[0].parentNode.scrollLeft;
						}
						else if (X + that.$workArea[0].parentNode.scrollLeft + that.$nodeData[id].width > t.left - c.left + that.$workArea.width()) {
							X = t.left - c.left + that.$workArea.width() - that.$workArea[0].parentNode.scrollLeft - that.$nodeData[id].width;
						}
						if (Y < t.top - c.top - that.$workArea[0].parentNode.scrollTop) {
							Y = t.top - c.top - that.$workArea[0].parentNode.scrollTop;
						}
						else if (Y + that.$workArea[0].parentNode.scrollTop + that.$nodeData[id].height > t.top - c.top + that.$workArea.height()) {
							Y = t.top - c.top + that.$workArea.height() - that.$workArea[0].parentNode.scrollTop - that.$nodeData[id].height;
						}
						that.$ghost.css({left: X - 230 + "px", top: Y - 133 + "px"});
						isMove = true;
					}
					document.onmouseup = function () {
						if (isMove) that.moveNode(id, X + that.$workArea[0].parentNode.scrollLeft - t.left + c.left, Y + that.$workArea[0].parentNode.scrollTop - t.top + c.top);
						{
							that.$ghost.empty().hide();
						}
						document.onmousemove = null;
						document.onmouseup = null;
					}
				}, 150);
			},
			// 显示连线图标
			mouseenter:function () {
				var moving = that.$lineMoveing;
				if (!moving) {
					var w = $(this).width() + 60 + 'px';
					var h = $(this).height() + 30 + 'px';
					$(this).append("<div class='line-begin' style='width:" + w + ";height:" + h + "'><div class='line-begin-icon top'></div><div class='line-begin-icon left'></div><div class='line-begin-icon right'></div><div class='line-begin-icon bottom'></div></div>")
				}
				if (moving) {
					$(this).addClass('item-mark');
				}
			},
			mouseleave:function () {
				$(this).children('.line-begin').remove();
				$(this).removeClass('item-mark');
			},
			// 结束连线
			mouseup:function () {
				clearTimeout(timeId);
				if (that.$lineMoveing) {
					var type = $(this).children('.GooFlow_item_cont').children('.GooFlow_item_txt').attr("id").split("type-")[1]
					var obj = $(this);
					if (that.$nowType != "cursor") {
						return;
					}
					var lineT, lineM;
					var lineType = that.$lineType;
					switch (lineType) {
						case 'top':
						case 'bottom':
							lineT = 'tb';
							break;
						case 'left':
						case 'right':
							lineT = 'lr';
							break;
					}
					var lineStart = that.$workArea.data("lineStart");
					console.log("lineStart" + lineStart);
					var n1 = that.$nodeData[lineStart.id], n2 = that.$nodeData[obj[0].id];
					//To结点中心点位置判断
					var sLeft = n1.left;
					var sRight = sLeft + n1.width;
					var sTop = n1.top;
					var sBottom = sTop + n1.height;
					var EXcenter = n2.left + n2.width / 2;
					var EYcenter = n2.top + n2.height / 2;
					// 当To结点中心点在From结点内时,用直线
					if ((EXcenter >= sLeft && EXcenter <= sRight) || (EYcenter >= sTop && EYcenter <= sBottom)) {
						lineT = 'sl';
						lineM = '';
					}
					var lineM = GooFlow.prototype.getMValue(n1, n2, lineT);
					if (lineStart) {
						that.addLine(that.$id + "_line_" + that.$lineCount, {
							from: lineStart.id,
							to: obj[0].id,
							name: "",
							x: lineStart.x,
							y: lineStart.y,
							typeFrom: lineStart.typeFrom,
							typeTo: type,
							type: lineT,
							M: lineM
						});
					}
				}
			}
		},".GooFlow_item").on({
			// 删除
			mousedown:function () {
				that.delNode(that.$focus);
				return false;
			}
		},".rs_close")
        this.$workArea.on({
            // 选中
            click: function () {
                clearTimeout(timeId);
                var Dom = $(this);
                var id = Dom.attr("id");
                that.focusItem(id, true);
            },
            // 编辑
            dblclick: function () {
                var id = $(this).attr('id'),
                    oldTxt = that.$nodeData[id].param,
                    objPosition = $(this).position(),
                    objLeft = objPosition.left,
                    objTop = objPosition.top;
                // 编辑的时候禁止delete键删除
                that.$canDelLine = false;
                that.$deteNodeId = '';
                that.$deteLineId = '';
                var thisType = that.$nodeData[id].type;
                if (thisType != 'start' && thisType != 'task') {
                    clearTimeout(timeId);
                    that.$textArea.val(oldTxt).css({
                        display: "block",
                        left: objLeft + 170,
                        top: objTop + 50
                    }).data("id", that.$focus).focus();
                    that.$workArea.parent().one("mousedown", function () {
                        that.setName(that.$textArea.data("id"), that.$textArea.val(), "node");
                        that.$textArea.val("").removeData("id").hide();
                    });
                }
            },
            // 移动
            mousedown: function (e) {
                if (!e) e = window.event;
                var Dom = $(this);
                var id = Dom.attr("id");
                clearTimeout(timeId);
                timeId = setTimeout(function () {
                    var ev = GooFunc.mousePosition(e),
                        t = GooFunc.getElCoordinate(that.$workArea[0]),
                        c = GooFunc.getElCoordinate(that.$MainContener);
                    that.$ghost.css({
                        display: "block",
                        top: that.$nodeData[id].top + 133 - that.$workArea[0].parentNode.scrollTop + "px",
                        left: that.$nodeData[id].left + 200 - that.$workArea[0].parentNode.scrollLeft + "px",
                        cursor: "move"
                    });
                    var X, Y;
                    X = ev.x - t.left + that.$workArea[0].parentNode.scrollLeft;
                    Y = ev.y - t.top + that.$workArea[0].parentNode.scrollTop;
                    var vX = X - that.$nodeData[id].left, vY = Y - that.$nodeData[id].top;
                    var isMove = false;
                    document.onmousemove = function (e) {
                        if (!e) {
                            e = window.event;
                        }
                        var ev = GooFunc.mousePosition(e);
                        X = ev.x - vX - c.left;
                        Y = ev.y - vY - c.top;
                        if (X < t.left - c.left - that.$workArea[0].parentNode.scrollLeft) {
                            X = t.left - c.left - that.$workArea[0].parentNode.scrollLeft;
                        }
                        else if (X + that.$workArea[0].parentNode.scrollLeft + that.$nodeData[id].width > t.left - c.left + that.$workArea.width()) {
                            X = t.left - c.left + that.$workArea.width() - that.$workArea[0].parentNode.scrollLeft - that.$nodeData[id].width;
                        }
                        if (Y < t.top - c.top - that.$workArea[0].parentNode.scrollTop) {
                            Y = t.top - c.top - that.$workArea[0].parentNode.scrollTop;
                        }
                        else if (Y + that.$workArea[0].parentNode.scrollTop + that.$nodeData[id].height > t.top - c.top + that.$workArea.height()) {
                            Y = t.top - c.top + that.$workArea.height() - that.$workArea[0].parentNode.scrollTop - that.$nodeData[id].height;
                        }
                        that.$ghost.css({left: X - 230 + "px", top: Y - 133 + "px"});
                        isMove = true;
                    }
                    document.onmouseup = function () {
                        if (isMove) that.moveNode(id, X + that.$workArea[0].parentNode.scrollLeft - t.left + c.left, Y + that.$workArea[0].parentNode.scrollTop - t.top + c.top);
                        {
                            that.$ghost.empty().hide();
                        }
                        document.onmousemove = null;
                        document.onmouseup = null;
                    }
                }, 150);
            },
            // 显示连线图标
            mouseenter: function () {
                var moving = that.$lineMoveing;
                if (!moving) {
                    var w = $(this).width() + 60 + 'px';
                    var h = $(this).height() + 30 + 'px';
                    $(this).append("<div class='line-begin' style='width:" + w + ";height:" + h + "'><div class='line-begin-icon top'></div><div class='line-begin-icon left'></div><div class='line-begin-icon right'></div><div class='line-begin-icon bottom'></div></div>")
                }
                if (moving) {
                    $(this).addClass('item-mark');
                }
            },
            mouseleave: function () {
                $(this).children('.line-begin').remove();
                $(this).removeClass('item-mark');
            },
            // 结束连线
            mouseup: function () {
                clearTimeout(timeId);
                if (that.$lineMoveing) {
                    var type = $(this).children('.GooFlow_item_cont').children('.GooFlow_item_txt').attr("id").split("type-")[1]
                    var obj = $(this);
                    if (that.$nowType != "cursor") {
                        return;
                    }
                    var lineT, lineM;
                    var lineType = that.$lineType;
                    switch (lineType) {
                        case 'top':
                        case 'bottom':
                            lineT = 'tb';
                            break;
                        case 'left':
                        case 'right':
                            lineT = 'lr';
                            break;
                    }
                    var lineStart = that.$workArea.data("lineStart");
                    console.log("lineStart" + lineStart);
                    var n1 = that.$nodeData[lineStart.id], n2 = that.$nodeData[obj[0].id];
                    //To结点中心点位置判断
                    var sLeft = n1.left;
                    var sRight = sLeft + n1.width;
                    var sTop = n1.top;
                    var sBottom = sTop + n1.height;
                    var EXcenter = n2.left + n2.width / 2;
                    var EYcenter = n2.top + n2.height / 2;
                    // 当To结点中心点在From结点内时,用直线
                    if ((EXcenter >= sLeft && EXcenter <= sRight) || (EYcenter >= sTop && EYcenter <= sBottom)) {
                        lineT = 'sl';
                        lineM = '';
                    }
                    var lineM = GooFlow.prototype.getMValue(n1, n2, lineT);
                    if (lineStart) {
                        that.addLine(that.$id + "_line_" + that.$lineCount, {
                            from: lineStart.id,
                            to: obj[0].id,
                            name: "",
                            x: lineStart.x,
                            y: lineStart.y,
                            typeFrom: lineStart.typeFrom,
                            typeTo: type,
                            type: lineT,
                            M: lineM
                        });
                    }
                }
            }
        }, ".GooFlow_item").on({
            // 删除
            mousedown: function () {
                that.delNode(that.$focus);
                return false;
            }
        }, ".rs_close")
		/*
		 * Todo: 连线链接 【 $$$】
@ -763,77 +775,77 @@ GooFlow.prototype = {
		 * Date: 2017/2/20
		 * time: 10:23
		 * */
		this.$workArea.on({
			// 连线开始
			mousedown:function () {
				var cs = $(this).attr("class").split(/\s+/);
				that.$lineMoveing = true;
				that.$lineType = cs[1];
				var obj = $(this).parent().parent();
				that.$nowType = "cursor";
				var type = obj.children('.GooFlow_item_cont').children('.GooFlow_item_txt').attr("id").split("type-")[1]
				// 将划线开始点定为元素中心点
				var X, Y;
				var objPosition = obj.position();
				var objLeft = objPosition.left;
				var objTop = objPosition.top;
				var w = (obj.width()) / 2;
				var h = (obj.height()) / 2;
				X = objLeft + w;
				Y = objTop + h;
				that.$workArea.data("lineStart", {
					"x": X,
					"y": Y,
					"id": obj[0].id,
					"typeFrom": type
				}).css("cursor", "crosshair");
				var line = GooFlow.prototype.drawLine("GooFlow_tmp_line", [X, Y], [X, Y], true, true);
				that.$draw.appendChild(line);
				$(document).mouseup(function () {
					$('.GooFlow_item').removeClass('item-mark');
					that.$lineMoveing = false;
				})
				return false;
			}
		},".GooFlow_item .line-begin > *").on({
			// 连线中
			mousemove:function (e) {
				if (that.$nowType == "cursor") {
					var lineStart = $(this).data("lineStart");
					if (!lineStart)return;
					var ev = GooFunc.mousePosition(e), t = GooFunc.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");
					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)");
					}
				}
			},
			// 连线结束
			mouseup:function () {
				if (that.$nowType != "cursor") {
					return;
				}
				$(this).css("cursor", "auto").removeData("lineStart");
				var HtmlStr = document.getElementById("GooFlow_tmp_line");
				if (HtmlStr) {
					that.$draw.removeChild(HtmlStr);
				}
			}
		})
        this.$workArea.on({
            // 连线开始
            mousedown: function () {
                var cs = $(this).attr("class").split(/\s+/);
                that.$lineMoveing = true;
                that.$lineType = cs[1];
                var obj = $(this).parent().parent();
                that.$nowType = "cursor";
                var type = obj.children('.GooFlow_item_cont').children('.GooFlow_item_txt').attr("id").split("type-")[1]
                // 将划线开始点定为元素中心点
                var X, Y;
                var objPosition = obj.position();
                var objLeft = objPosition.left;
                var objTop = objPosition.top;
                var w = (obj.width()) / 2;
                var h = (obj.height()) / 2;
                X = objLeft + w;
                Y = objTop + h;
                that.$workArea.data("lineStart", {
                    "x": X,
                    "y": Y,
                    "id": obj[0].id,
                    "typeFrom": type
                }).css("cursor", "crosshair");
                var line = GooFlow.prototype.drawLine("GooFlow_tmp_line", [X, Y], [X, Y], true, true);
                that.$draw.appendChild(line);
                $(document).mouseup(function () {
                    $('.GooFlow_item').removeClass('item-mark');
                    that.$lineMoveing = false;
                })
                return false;
            }
        }, ".GooFlow_item .line-begin > *").on({
            // 连线中
            mousemove: function (e) {
                if (that.$nowType == "cursor") {
                    var lineStart = $(this).data("lineStart");
                    if (!lineStart)return;
                    var ev = GooFunc.mousePosition(e), t = GooFunc.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");
                    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)");
                    }
                }
            },
            // 连线结束
            mouseup: function () {
                if (that.$nowType != "cursor") {
                    return;
                }
                $(this).css("cursor", "auto").removeData("lineStart");
                var HtmlStr = document.getElementById("GooFlow_tmp_line");
                if (HtmlStr) {
                    that.$draw.removeChild(HtmlStr);
                }
            }
        })
		/*
		 * Todo: 线条文字编辑 【 $$$】
@ -841,47 +853,47 @@ GooFlow.prototype = {
		 * Date: 2017/2/20
		 * time: 10:23
		 * */
		$(this.$draw).on({
			click:function () {
				that.focusItem(this.id, true);
			},
			dblclick:function () {
				var oldTxt, x, y, from, to;
				// 编辑的时候禁止delete键删除
				that.$canDelLine = false;
				that.$deteNodeId = '';
				that.$deteLineId = '';
				if (GooFlow.prototype.useSVG != "") {
					oldTxt = this.childNodes[2].textContent;
					from = this.getAttribute("from").split(",");
					to = this.getAttribute("to").split(",");
				}
				if (that.$lineData[this.id].type == "lr") {
					from[0] = that.$lineData[this.id].M;
					to[0] = from[0];
				}
				else if (that.$lineData[this.id].type == "tb") {
					from[1] = that.$lineData[this.id].M;
					to[1] = from[1];
				}
				x = (parseInt(from[0], 10) + parseInt(to[0], 10)) / 2 + 230;
				y = (parseInt(from[1], 10) + parseInt(to[1], 10)) / 2 + 60;
				that.$textArea.val(oldTxt).css({
					display: "block",
					left: x,
					top: y
				}).data("id", that.$focus).focus();
				that.$workArea.parent().one("mousedown", function (e) {
					that.setName(that.$textArea.data("id"), that.$textArea.val(), "line");
					that.$textArea.val("").removeData("id").hide();
				});
			}
		}, 'g');
        $(this.$draw).on({
            click: function () {
                that.focusItem(this.id, true);
            },
            dblclick: function () {
                var oldTxt, x, y, from, to;
                // 编辑的时候禁止delete键删除
                that.$canDelLine = false;
                that.$deteNodeId = '';
                that.$deteLineId = '';
                if (GooFlow.prototype.useSVG != "") {
                    oldTxt = this.childNodes[2].textContent;
                    from = this.getAttribute("from").split(",");
                    to = this.getAttribute("to").split(",");
                }
                if (that.$lineData[this.id].type == "lr") {
                    from[0] = that.$lineData[this.id].M;
                    to[0] = from[0];
                }
                else if (that.$lineData[this.id].type == "tb") {
                    from[1] = that.$lineData[this.id].M;
                    to[1] = from[1];
                }
                x = (parseInt(from[0], 10) + parseInt(to[0], 10)) / 2 + 230;
                y = (parseInt(from[1], 10) + parseInt(to[1], 10)) / 2 + 60;
                that.$textArea.val(oldTxt).css({
                    display: "block",
                    left: x,
                    top: y
                }).data("id", that.$focus).focus();
                that.$workArea.parent().one("mousedown", function (e) {
                    that.setName(that.$textArea.data("id"), that.$textArea.val(), "line");
                    that.$textArea.val("").removeData("id").hide();
                });
            }
        }, 'g');
		/*
		 * Todo: 线条移动 【 $$$】
@ -889,77 +901,77 @@ GooFlow.prototype = {
		 * Date: 2017/2/20
		 * time: 10:33
		 * */
		this.$lineMove.on("mousedown", function (e) {
			var lm = $(this);
			lm.css({"background-color": "#333"});
			var ev = GooFunc.mousePosition(e), t = GooFunc.getElCoordinate(that.$workArea[0]);
			var X, Y;
			X = ev.x - t.left + that.$workArea[0].parentNode.scrollLeft;
			Y = ev.y - t.top + that.$workArea[0].parentNode.scrollTop;
			var p = that.$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 = GooFunc.mousePosition(e);
				var ps = that.$lineMove.position();
				X = ev.x - t.left + that.$workArea[0].parentNode.scrollLeft;
				Y = ev.y - t.top + that.$workArea[0].parentNode.scrollTop;
				if (that.$lineMove.data("type") == "lr") {
					X = X - vX;
					if (X < 0) X = 0;
					else if (X > that.$workArea.width())
						X = that.$workArea.width();
					that.$lineMove.css({left: X + "px"});
				}
				else if (that.$lineMove.data("type") == "tb") {
					Y = Y - vY;
					if (Y < 0) Y = 0;
					else if (Y > that.$workArea.height())
						Y = that.$workArea.height();
					that.$lineMove.css({top: Y + "px"});
				}
				isMove = true;
			}
			document.onmouseup = function (e) {
				if (isMove) {
					var p = that.$lineMove.position();
					if (that.$lineMove.data("type") == "lr")
						that.setLineM(that.$lineMove.data("tid"), p.left + 3);
					else if (that.$lineMove.data("type") == "tb")
						that.setLineM(that.$lineMove.data("tid"), p.top + 3);
				}
				that.$lineMove.css({"background-color": "transparent"});
				if (that.$focus == that.$lineMove.data("tid")) {
					that.focusItem(that.$lineMove.data("tid"));
				}
				document.onmousemove = null;
				document.onmouseup = null;
			}
		});
		this.$lineOper.on("click", function (e) {
			if (e.target.tagName != "B")   return;
			var id = $(this).data("tid");
			switch ($(e.target).attr("class")) {
				case "b_x":
					that.delLine(id);
					this.style.display = "none";
					break;
				case "b_l1":
					that.setLineType(id, "lr");
					break;
				case "b_l2":
					that.setLineType(id, "tb");
					break;
				case "b_l3":
					that.setLineType(id, "sl");
					break;
			}
		});
	},
        this.$lineMove.on("mousedown", function (e) {
            var lm = $(this);
            lm.css({"background-color": "#333"});
            var ev = GooFunc.mousePosition(e), t = GooFunc.getElCoordinate(that.$workArea[0]);
            var X, Y;
            X = ev.x - t.left + that.$workArea[0].parentNode.scrollLeft;
            Y = ev.y - t.top + that.$workArea[0].parentNode.scrollTop;
            var p = that.$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 = GooFunc.mousePosition(e);
                var ps = that.$lineMove.position();
                X = ev.x - t.left + that.$workArea[0].parentNode.scrollLeft;
                Y = ev.y - t.top + that.$workArea[0].parentNode.scrollTop;
                if (that.$lineMove.data("type") == "lr") {
                    X = X - vX;
                    if (X < 0) X = 0;
                    else if (X > that.$workArea.width())
                        X = that.$workArea.width();
                    that.$lineMove.css({left: X + "px"});
                }
                else if (that.$lineMove.data("type") == "tb") {
                    Y = Y - vY;
                    if (Y < 0) Y = 0;
                    else if (Y > that.$workArea.height())
                        Y = that.$workArea.height();
                    that.$lineMove.css({top: Y + "px"});
                }
                isMove = true;
            }
            document.onmouseup = function (e) {
                if (isMove) {
                    var p = that.$lineMove.position();
                    if (that.$lineMove.data("type") == "lr")
                        that.setLineM(that.$lineMove.data("tid"), p.left + 3);
                    else if (that.$lineMove.data("type") == "tb")
                        that.setLineM(that.$lineMove.data("tid"), p.top + 3);
                }
                that.$lineMove.css({"background-color": "transparent"});
                if (that.$focus == that.$lineMove.data("tid")) {
                    that.focusItem(that.$lineMove.data("tid"));
                }
                document.onmousemove = null;
                document.onmouseup = null;
            }
        });
        this.$lineOper.on("click", function (e) {
            if (e.target.tagName != "B")   return;
            var id = $(this).data("tid");
            switch ($(e.target).attr("class")) {
                case "b_x":
                    that.delLine(id);
                    this.style.display = "none";
                    break;
                case "b_l1":
                    that.setLineType(id, "lr");
                    break;
                case "b_l2":
                    that.setLineType(id, "tb");
                    break;
                case "b_l3":
                    that.setLineType(id, "sl");
                    break;
            }
        });
    },
	/*
	 * Todo: ### 初始化事件绑定******************************--结束
@ -971,34 +983,34 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:53
	 * */
	blurItem: function () {
		this.$deteLineId = '';
		this.$deteNodeId = '';
		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(".rs-box").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", "#323232");
						jq[0].childNodes[1].setAttribute("marker-end", "url(#arrow1)");
					}
				}
				else {
					if (!this.$lineData[this.$focus].marked) jq[0].strokeColor = "#323232";
				}
				this.$lineMove.hide().removeData("type").removeData("tid");
				if (this.$editable) this.$lineOper.hide().removeData("tid");
			}
		}
		this.$focus = "";
		return true;
	},
    blurItem: function () {
        this.$deteLineId = '';
        this.$deteNodeId = '';
        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(".rs-box").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", "#323232");
                        jq[0].childNodes[1].setAttribute("marker-end", "url(#arrow1)");
                    }
                }
                else {
                    if (!this.$lineData[this.$focus].marked) jq[0].strokeColor = "#323232";
                }
                this.$lineMove.hide().removeData("type").removeData("tid");
                if (this.$editable) this.$lineOper.hide().removeData("tid");
            }
        }
        this.$focus = "";
        return true;
    },
	/*
	 * Todo: 选定状态 【聚焦公共方法】
@ -1006,88 +1018,88 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:53
	 * */
	focusItem: function (id, bool) {
		var jq = $("#" + id);
		var that = this;
		this.$ghost.attr({'class': 'rs_ghost ' + jq.attr('class')});
		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(".rs-box").css("display", "block");
			this.$workArea.append(jq);
			that.$canDelLine = false;
			that.$deteLineId = '';
			that.$deteNodeId = id;
			$(document).keydown(function (e) {
				if (e.keyCode != 8 && that.$deteNodeId) {
					return
				}
				that.delNode(that.$deteNodeId);
			});
		}
		else {//如果是连接线
			if (this.onItemFocus != null && !this.onItemFocus(id, "line"))    return;
			that.$canDelLine = true;
			that.$deteNodeId = '';
			that.$deteLineId = id;
			$(document).keydown(function (e) {
				if (e.keyCode == 8 && that.$deteLineId) {
					that.delLine(that.$deteLineId);
					$('.GooFlow_line_oper').hide();
				}
			})
			if (GooFlow.prototype.useSVG != "") {
				jq[0].childNodes[1].setAttribute("stroke", "#00b7ee");
				jq[0].childNodes[1].setAttribute("marker-end", "url(#arrow2)");
			}
			else    jq[0].strokeColor = "#00b7ee";
			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);
			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.$nowType = "cursor";
	},
    focusItem: function (id, bool) {
        var jq = $("#" + id);
        var that = this;
        this.$ghost.attr({'class': 'rs_ghost ' + jq.attr('class')});
        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(".rs-box").css("display", "block");
            this.$workArea.append(jq);
            that.$canDelLine = false;
            that.$deteLineId = '';
            that.$deteNodeId = id;
            $(document).keydown(function (e) {
                if (e.keyCode != 8 && that.$deteNodeId) {
                    return
                }
                that.delNode(that.$deteNodeId);
            });
        }
        else {//如果是连接线
            if (this.onItemFocus != null && !this.onItemFocus(id, "line"))    return;
            that.$canDelLine = true;
            that.$deteNodeId = '';
            that.$deteLineId = id;
            $(document).keydown(function (e) {
                if (e.keyCode == 8 && that.$deteLineId) {
                    that.delLine(that.$deteLineId);
                    $('.GooFlow_line_oper').hide();
                }
            })
            if (GooFlow.prototype.useSVG != "") {
                jq[0].childNodes[1].setAttribute("stroke", "#00b7ee");
                jq[0].childNodes[1].setAttribute("marker-end", "url(#arrow2)");
            }
            else    jq[0].strokeColor = "#00b7ee";
            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);
            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.$nowType = "cursor";
    },
	/*
	 * Todo: 增加结点 【结点公共方法 @@】
@ -1095,60 +1107,62 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:53
	 * */
	addNode: function (id, json) {
		if (this.onItemAdd != null && !this.onItemAdd(id, "node", json))return;
		if (this.$undoStack) {this.pushOper("delNode", [id]);}
		if (json.type != "start" && json.type != "end") {
			if (json.top < 0) json.top = 0;
			if (json.left < 0) json.left = 0;
			switch (json.type) {
				case "state":
					json.name = '判断';
					json.value = '';
					json.nodeType = 'judgement'
					break;
				case "complex":
					json.name = '循环';
					json.value = '';
					json.nodeType = 'circle'
					break;
				case "join":
					json.name = '聚合';
					json.value = '';
					json.nodeType = 'aggregate'
					break;
				case "fork":
					json.name = '分流';
					json.value = '';
					json.nodeType = 'multicast'
					break;
				case "task":
					json.name = this.$newNodeTxt || json.name;
					json.value = this.$newNodeValue || json.value;
					json.nodeType = 'service'
					break;
				case "plug":
					json.name = this.$newNodeTxt || json.name;
					json.value = this.$newNodeValue || json.value;
					json.nodeType = 'processor'
					break;
			}
			this.$nodeDom[id] = $(" <div class='GooFlow_item node-" + json.type + "' id='" + id + "' style='top:" + json.top + "px;left:" + json.left + "px'> <div class='GooFlow_item_cont'> <i class='fa ico_" + json.type + "'></i>   <span class='GooFlow_item_txt' id='type-" + json.type + "'>" + json.name + "</span></div> <div class='rs-box' style='display:none'> <div class='rs_close'><i class='fa fa-close' aria-hidden='true'></i></div> </div> </div>");
		}
		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]);
		json.width = this.$nodeDom[id].width();
		json.height = this.$nodeDom[id].height();
		this.$nodeData[id] = json;
		++this.$nodeCount;
	},
    addNode: function (id, json) {
        if (this.onItemAdd != null && !this.onItemAdd(id, "node", json))return;
        if (this.$undoStack) {
            this.pushOper("delNode", [id]);
        }
        if (json.type != "start" && json.type != "end") {
            if (json.top < 0) json.top = 0;
            if (json.left < 0) json.left = 0;
            switch (json.type) {
                case "state":
                    json.name = '判断';
                    json.value = '';
                    json.nodeType = 'judgement'
                    break;
                case "complex":
                    json.name = '循环';
                    json.value = '';
                    json.nodeType = 'circle'
                    break;
                case "join":
                    json.name = '聚合';
                    json.value = '';
                    json.nodeType = 'aggregate'
                    break;
                case "fork":
                    json.name = '分流';
                    json.value = '';
                    json.nodeType = 'multicast'
                    break;
                case "task":
                    json.name = this.$newNodeTxt || json.name;
                    json.value = this.$newNodeValue || json.value;
                    json.nodeType = this.$nodeType || json.nodeType;
                    break;
                case "plug":
                    json.name = this.$newNodeTxt || json.name;
                    json.value = this.$newNodeValue || json.value;
                    json.nodeType = this.$nodeType || json.nodeType;
                    break;
            }
            this.$nodeDom[id] = $(" <div class='GooFlow_item node-" + json.type + "' id='" + id + "' style='top:" + json.top + "px;left:" + json.left + "px'> <div class='GooFlow_item_cont'> <i class='fa ico_" + json.type + "'></i>   <span class='GooFlow_item_txt' id='type-" + json.type + "'>" + json.name + "</span></div> <div class='rs-box' style='display:none'> <div class='rs_close'><i class='fa fa-close' aria-hidden='true'></i></div> </div> </div>");
        }
        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]);
        json.width = this.$nodeDom[id].width();
        json.height = this.$nodeDom[id].height();
        this.$nodeData[id] = json;
        ++this.$nodeCount;
    },
	/*
	 * Todo: 删除结点 【结点公共方法 @@】
@ -1156,25 +1170,25 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:55
	 * */
	delNode: function (id) {
		if (!this.$nodeData[id]) return;
		if (this.$undoStack) {
			var paras = [id, this.$nodeData[id]];
			this.pushOper("addNode", paras);
		}
		if (this.onItemDel != null && !this.onItemDel(id, "node"))    return;
		delete this.$nodeData[id];
		this.$nodeDom[id].remove();
		delete this.$nodeDom[id];
		if (this.$focus == id) this.$focus = "";
		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];
			}
		}
	},
    delNode: function (id) {
        if (!this.$nodeData[id]) return;
        if (this.$undoStack) {
            var paras = [id, this.$nodeData[id]];
            this.pushOper("addNode", paras);
        }
        if (this.onItemDel != null && !this.onItemDel(id, "node"))    return;
        delete this.$nodeData[id];
        this.$nodeDom[id].remove();
        delete this.$nodeDom[id];
        if (this.$focus == id) this.$focus = "";
        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];
            }
        }
    },
	/*
	 * Todo: 结点移动 【结点移动方法 @@】
@ -1182,21 +1196,21 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:54
	 * */
	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]);
	},
    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]);
    },
	/*
	 * Todo: 设置结点线等内容 【内容设置公共方法 @@ $$】
@ -1204,43 +1218,43 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:54
	 * */
	setName: function (id, name, type) {
		var oldName;
		if (type == "node") {//如果是结点
			if (!this.$nodeData[id]) return;
			var thisType = this.$nodeData[id].type
			if (thisType == 'plug'){
				this.$nodeData[id].param  = name;
			}else{
				this.$nodeData[id].value  = name;
			}
		}
		else if (type == "line") {//如果是线
			if (!this.$lineData[id]) return;
			if (this.$lineData[id].name == name)   return;
			if (this.onItemRename != null && !this.onItemRename(id, name, "line")) 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";
			}
		}
	},
    setName: function (id, name, type) {
        var oldName;
        if (type == "node") {//如果是结点
            if (!this.$nodeData[id]) return;
            var thisType = this.$nodeData[id].type
            if (thisType == 'plug') {
                this.$nodeData[id].param = name;
            } else {
                this.$nodeData[id].value = name;
            }
        }
        else if (type == "line") {//如果是线
            if (!this.$lineData[id]) return;
            if (this.$lineData[id].name == name)   return;
            if (this.onItemRename != null && !this.onItemRename(id, name, "line")) 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";
            }
        }
    },
	/*
	 * Todo: 增加线条 【$$】
@ -1248,138 +1262,138 @@ GooFlow.prototype = {
	 * Date: 2017/2/15
	 * time: 16:46
	 * */
	addLine: function (id, json, isDataLoad) {
		if (!isDataLoad) {
			if (this.$undoStack) {
				this.pushOper("delLine", [id]);
			}
			if (json.from == json.to) {
				return;
			}
			var typeF = json.typeFrom || json.type;
			var typeT = json.typeTo || json.type;
			for (var k in this.$lineData) {
				// 单出
				var onlyOut = (json.from == this.$lineData[k].from);
				// 单进
				var onlyIn = (json.to == this.$lineData[k].to);
				// 来源等于去向
				var formEto = (json.from == this.$lineData[k].to);
				// 去向等于来源
				var tofrom = (json.to == this.$lineData[k].from);
				// 不能反向
				if (tofrom && formEto) {
					return;
				}
				// 设置除了聚合其余都默认单进
				if (typeT != 'join') {
					if (onlyIn) {
						return;
					}
				}
				switch (typeF) {
					case 'task':
					case 'plug':
						if (onlyOut) {
							return;
						}
						break;
					case 'state':
					case 'complex':
						if (json.from == this.$lineData[k].from) {
							var i = 0;
							for (var j in this.$lineData) {
								if (json.from == this.$lineData[j].from) {
									i++
								}
							}
							if (i >= 2) {
								return;
							}
						}
						break;
				}
			}
		}
		//获取开始/结束结点的数据
		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] = {};
		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].value = 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[i].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;
	},
    addLine: function (id, json, isDataLoad) {
        if (!isDataLoad) {
            if (this.$undoStack) {
                this.pushOper("delLine", [id]);
            }
            if (json.from == json.to) {
                return;
            }
            var typeF = json.typeFrom || json.type;
            var typeT = json.typeTo || json.type;
            for (var k in this.$lineData) {
                // 单出
                var onlyOut = (json.from == this.$lineData[k].from);
                // 单进
                var onlyIn = (json.to == this.$lineData[k].to);
                // 来源等于去向
                var formEto = (json.from == this.$lineData[k].to);
                // 去向等于来源
                var tofrom = (json.to == this.$lineData[k].from);
                // 不能反向
                if (tofrom && formEto) {
                    return;
                }
                // 设置除了聚合其余都默认单进
                if (typeT != 'join') {
                    if (onlyIn) {
                        return;
                    }
                }
                switch (typeF) {
                    case 'task':
                    case 'plug':
                        if (onlyOut) {
                            return;
                        }
                        break;
                    case 'state':
                    case 'complex':
                        if (json.from == this.$lineData[k].from) {
                            var i = 0;
                            for (var j in this.$lineData) {
                                if (json.from == this.$lineData[j].from) {
                                    i++
                                }
                            }
                            if (i >= 2) {
                                return;
                            }
                        }
                        break;
                }
            }
        }
        //获取开始/结束结点的数据
        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] = {};
        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].value = 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[i].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;
    },
	/*
	 * Todo: 线条删除  【$$】
@ -1387,17 +1401,17 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:57
	 * */
	delLine: function (id) {
		if (!this.$lineData[id]) 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 = "";
	},
    delLine: function (id) {
        if (!this.$lineData[id]) 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 = "";
    },
	/*
	 * Todo: 直线生成 【$$】
@ -1405,77 +1419,77 @@ GooFlow.prototype = {
	 * Date: 2017/2/15
	 * time: 14:57
	 * */
	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", 15);
			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", 1.2);
			path.setAttribute("stroke-linecap", "round");
			path.setAttribute("fill", "none");
			if (dash) path.setAttribute("style", "stroke-dasharray:6,5");
			if (mark) {
				path.setAttribute("stroke", "#00b7ee");
				path.setAttribute("marker-end", "url(#arrow2)");
			}
			else {
				path.setAttribute("stroke", "#323232");
				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);
				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 = "#00b7ee";
			else    line.strokeColor = "#323232";
		}
		return line;
	},
    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", 15);
            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", 1.2);
            path.setAttribute("stroke-linecap", "round");
            path.setAttribute("fill", "none");
            if (dash) path.setAttribute("style", "stroke-dasharray:6,5");
            if (mark) {
                path.setAttribute("stroke", "#00b7ee");
                path.setAttribute("marker-end", "url(#arrow2)");
            }
            else {
                path.setAttribute("stroke", "#323232");
                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);
                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 = "#00b7ee";
            else    line.strokeColor = "#323232";
        }
        return line;
    },
	/*
	 * Todo: 折线生成 【$$】
@ -1483,81 +1497,81 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 10:26
	 * */
	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", 15);
			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", 1.2);
			path.setAttribute("stroke-linecap", "round");
			path.setAttribute("fill", "none");
			if (mark) {
				path.setAttribute("stroke", "#00b7ee");
				path.setAttribute("marker-end", "url(#arrow2)");
			}
			else {
				path.setAttribute("stroke", "#323232");
				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);
			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 = "#00b7ee";
			else    poly.strokeColor = "#323232"
		}
		return poly;
	},
    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", 15);
            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", 1.2);
            path.setAttribute("stroke-linecap", "round");
            path.setAttribute("fill", "none");
            if (mark) {
                path.setAttribute("stroke", "#00b7ee");
                path.setAttribute("marker-end", "url(#arrow2)");
            }
            else {
                path.setAttribute("stroke", "#323232");
                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);
            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 = "#00b7ee";
            else    poly.strokeColor = "#323232"
        }
        return poly;
    },
	/*
	 * Todo: 直线坐标计算  【$$】
@ -1565,53 +1579,53 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 10:26
	 * */
	calcStartEnd: function (n1, n2) {
		if (!n1 || !n2) {
			return {"start": [], "end": []};
		}
		var X_1, Y_1, X_2, Y_2;
		//X判断:
		var x11 = n1.left, x12 = n1.left + n1.width / 2, x13 = n1.left + n1.width, x21 = n2.left, x22 = n2.left + n2.width / 2, x23 = n2.left + n2.width;
		//Y判断:
		var y11 = n1.top, y12 = n1.top + n1.height / 2, y13 = n1.top + n1.height, y21 = n2.top, y22 = n2.top + n2.height / 2, y23 = n2.top + n2.height;
		X_1 = x12;
		X_2 = x22;
		// 结点2在结点1左边
		if (x11 >= x23) {
			X_1 = x11;
			Y_1 = y12;
			X_2 = x23;
			Y_2 = y22;
		}
		//结点2在结点1右边
		else if (x21 >= x13) {
			X_1 = x13;
			Y_1 = y12;
			X_2 = x21;
			Y_2 = y22;
		}
		else {
			// 结点2在结点1上边
			if (y11 >= y22) {
				Y_1 = y11;
				Y_2 = y23;
			}
			//结点2在结点1下边
			else if (y12 <= y21) {
				Y_1 = y13;
				Y_2 = y21;
			}
		}
		return {"start": [X_1, Y_1], "end": [X_2, Y_2]};
	},
    calcStartEnd: function (n1, n2) {
        if (!n1 || !n2) {
            return {"start": [], "end": []};
        }
        var X_1, Y_1, X_2, Y_2;
        //X判断:
        var x11 = n1.left, x12 = n1.left + n1.width / 2, x13 = n1.left + n1.width, x21 = n2.left, x22 = n2.left + n2.width / 2, x23 = n2.left + n2.width;
        //Y判断:
        var y11 = n1.top, y12 = n1.top + n1.height / 2, y13 = n1.top + n1.height, y21 = n2.top, y22 = n2.top + n2.height / 2, y23 = n2.top + n2.height;
        X_1 = x12;
        X_2 = x22;
        // 结点2在结点1左边
        if (x11 >= x23) {
            X_1 = x11;
            Y_1 = y12;
            X_2 = x23;
            Y_2 = y22;
        }
        //结点2在结点1右边
        else if (x21 >= x13) {
            X_1 = x13;
            Y_1 = y12;
            X_2 = x21;
            Y_2 = y22;
        }
        else {
            // 结点2在结点1上边
            if (y11 >= y22) {
                Y_1 = y11;
                Y_2 = y23;
            }
            //结点2在结点1下边
            else if (y12 <= y21) {
                Y_1 = y13;
                Y_2 = y21;
            }
        }
        return {"start": [X_1, Y_1], "end": [X_2, Y_2]};
    },
	/*
	 * Todo: 折线坐标计算  【$$】
@ -1619,66 +1633,66 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 10:27
	 * */
	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};
	},
    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};
    },
	/*
	 * Todo: 折线固定中线计算  【$$】
@ -1686,14 +1700,14 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 10:27
	 * */
	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;
		}
	},
    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;
        }
    },
	/*
	 * Todo: 重置线条  【$$】
@ -1701,55 +1715,55 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:56
	 * */
	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;
		}
	},
    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;
        }
    },
	/*
	 * Todo: 重置线条类型  【$$】
@ -1757,46 +1771,46 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:56
	 * */
	setLineType: function (id, newType) {
		if (!newType || newType == null || newType == "" || newType == this.$lineData[id].type)  return false;
		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);
		}
	},
    setLineType: function (id, newType) {
        if (!newType || newType == null || newType == "" || newType == this.$lineData[id].type)  return false;
        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);
        }
    },
	/*
	 * Todo: 重置折线中点  【$$】
@ -1804,32 +1818,33 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:57
	 * */
	setLineM: function (id, M, noStack) {
		if (!this.$lineData[id] || M < 0 || !this.$lineData[id].type || this.$lineData[id].type == "sl")   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;
	},
    setLineM: function (id, M, noStack) {
        if (!this.$lineData[id] || M < 0 || !this.$lineData[id].type || this.$lineData[id].type == "sl")   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;
    },
	/*
	 * Todo: 初始化数据加载 【AJAX相关】
@ -1837,14 +1852,20 @@ GooFlow.prototype = {
	 * Date: 2017/2/15
	 * time: 15:02
	 * */
	loadData: function (data) {
		for (var i in data.nodes) {
			this.addNode(i, data.nodes[i]);
		}
		for (var j in data.lines) {
			this.addLine(j, data.lines[j], true);
		}
	},
    loadData: function (data) {
		this.fileMsg(data.code,data.name);
        for (var i in data.nodes) {
            this.addNode(i, data.nodes[i]);
        }
        for (var j in data.lines) {
            this.addLine(j, data.lines[j], true);
        }
    },
	fileMsg:function (code,name) {
		$('#fileCode').val(code);
		$('#fileName').val(name);
    },
	/*
	 * Todo: 导出数据  【AJAX相关】
@ -1852,14 +1873,15 @@ GooFlow.prototype = {
	 * Date: 2017/2/20
	 * time: 9:58
	 * */
	exportData: function () {
		var data = {
			nodes: {},
			lines: {}
		}
		var nodes = data.nodes;
		var lines = data.lines;
    exportData: function () {
        this.$fileCode = $('#fileCode').val();
        this.$fileName = $('#fileName').val();
        var data = {
            nodes: {},
            lines: {}
        }
        var nodes = data.nodes;
        var lines = data.lines;
		function keyJson(obj, target, args) {
			for (var k in obj) {
@ -1869,12 +1891,28 @@ GooFlow.prototype = {
			}
		}
		keyJson(this.$nodeData, nodes, ['name', 'value', 'nodeType','param']);
		keyJson(this.$nodeData, nodes, ['name', 'value', 'nodeType', 'param']);
		keyJson(this.$lineData, lines, ['from', 'to', 'value']);
        var positionData = {
            nodes: this.$nodeData,
            lines: this.$lineData
        }
        postData = {
            code: this.$fileCode,
            name: this.$fileName,
            positionJson: JSON.stringify(positionData),
            flowJson: JSON.stringify(data)
        }
		var nodeArr = [];
		var specialArr = [];
		var fromArr = [];
		var toArr = [];
		var noError = true;
		// 存储所有结点名,并将判断和循环结点单独存储
		for (var i in nodes) {
			nodeArr.push(i);
			if (nodes[i].nodeType === 'judgement' || nodes[i].nodeType === 'circle') {
@ -1882,17 +1920,13 @@ GooFlow.prototype = {
			}
		}
		var fromArr = [];
		var toArr = [];
		// 存储所有的线条的开始结点和结束结点
		for (var j in lines) {
			fromArr.push(lines[j].from);
			toArr.push(lines[j].to);
		}
		// 如果存在没有连线的结点则报错
		var noError = true;
		nodeArr.forEach(function (elem) {
			var nodeWithoutLines = (fromArr.indexOf(elem) === -1) && (toArr.indexOf(elem) === -1)
			if (nodeWithoutLines) {
@ -1930,8 +1964,10 @@ GooFlow.prototype = {
			}
		})
		console.log(postData);
		// 如果没有错误则弹出保存菜单
		if (noError) {
			saveConfirm(data);
			saveConfirm();
		} else {
			$.ligerDialog.alert('<p style="padding: 10px;">您还有未编排完成的对象,无法保存。</p>')
		}
@ -1943,16 +1979,14 @@ GooFlow.prototype = {
		 * Date: 2017/2/22
		 * time: 18:59
		 * */
		function saveConfirm(data) {
			var callback = function (yes,data) {
				if (yes){
		function saveConfirm() {
			var callback = function (yes) {
				if (yes) {
					$.ajax({
						type: "POST",
						url: dataPost,
						data: "name=John&location=Boston",
						success: function(msg){
							alert( "Data Saved: " + msg );
						url: dataPostURL,
						data: postData,
						success: function () {
						}
					});
				}
@ -1979,7 +2013,10 @@ GooFlow.prototype = {
							type: 'ok',
							cls: 'l-dialog-btn-ok'
						}, {
							text: $.ligerDefaults.DialogString.no, onclick: btnclick, type: 'no', cls: 'l-dialog-btn-no'
							text: $.ligerDefaults.DialogString.no,
							onclick: btnclick,
							type: 'no',
							cls: 'l-dialog-btn-no'
						}
					]
				};
@ -1998,10 +2035,9 @@ GooFlow.prototype = {
			$('.l-dialog-content').css({"padding": "0 40px 20px 40px"});
		}
    }
	}
}
};
/*
 * Todo:  ## 注册JQ插件 ****************************************************************************