";
} else {
var str = "
" + _that.getText() + "
";
}
if (_that.completeState == 1) {
str += "
已办理
";
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
$.each(_that.content.activityUsers, function (i, el) {
str += "
办理人员" + el.name + "办理时间" + el.time + "
办理意见" + el.advice + "
";
})
}
} else if (_that.completeState == 2) {
if (_that.content.waitActivityUsers && _that.content.waitActivityUsers.length > 0) {
str += "
正在办理
";
$.each(_that.content.waitActivityUsers, function (i, el) {
str += "
办理人员" + el.name + "开始时间" + el.time + "
";
})
}
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
str += "
已办理
";
$.each(_that.content.activityUsers, function (i, el) {
str += "
办理人员" + el.name + "办理时间" + el.time + "
办理意见" + el.advice + "
";
})
}
}
str += "
";
$("#" + _that.flow._DEFALUTS_.id).append(str);
} else {
if (e.pageY <= wheight2) {
$("#" + name).css({"left": (e.pageX + 0), "top": (e.pageY + 0), "bottom": "auto"}).show();
$("#" + name).find(".con").css({"maxHeight": wheight2});
} else {
$("#" + name).css({
"left": (e.pageX + 0),
"bottom": (wheight - e.pageY + 0),
"top": "auto"
}).show();
$("#" + name).find(".con").css({"maxHeight": wheight2});
}
}
})
}
},
render: function (cx, cy, bpzcenter) { //end渲染
if (bpzcenter != null) { //碰撞吸附
if (bpzcenter[0] != null && bpzcenter[1] == null) {
//y轴吸附,x轴不吸附
if (bpzcenter[0].type == "start" || bpzcenter[0].type == "end" || bpzcenter[0].type == "gateway") {
cx = bpzcenter[0].cx;
} else if (bpzcenter[0].type == "userTask" || bpzcenter[0].type == "subProcess") {
cx = bpzcenter[0].x + bpzcenter[0].w / 2;
}
} else if (bpzcenter[0] == null && bpzcenter[1] != null) {
//x轴吸附,y轴不吸附
if (bpzcenter[1].type == "start" || bpzcenter[1].type == "end" || bpzcenter[1].type == "gateway") {
cy = bpzcenter[1].cy;
} else if (bpzcenter[1].type == "userTask" || bpzcenter[1].type == "subProcess") {
cy = bpzcenter[1].y + bpzcenter[1].h / 2;
}
} else if (bpzcenter[0] != null && bpzcenter[1] != null) {
//y轴吸附,x轴吸附
if (bpzcenter[0].type == "start" || bpzcenter[0].type == "end" || bpzcenter[0].type == "gateway") {
cx = bpzcenter[0].cx;
} else if (bpzcenter[0].type == "userTask" || bpzcenter[0].type == "subProcess") {
cx = bpzcenter[0].x + bpzcenter[0].w / 2;
}
if (bpzcenter[1].type == "start" || bpzcenter[1].type == "end" || bpzcenter[1].type == "gateway") {
cy = bpzcenter[1].cy;
} else if (bpzcenter[1].type == "userTask" || bpzcenter[1].type == "subProcess") {
cy = bpzcenter[1].y + bpzcenter[1].h / 2;
}
}
}
//end圆的重新渲染
this.cx = cx;
this.cy = cy;
this.element.attr({"cx": cx, "cy": cy});
this.bbox = this.element.getBBox();
this.centerpoint = [cx, cy];
//扩大的外框
this.elementbox.attr({"x": this.bbox.x - this.bmargin, "y": this.bbox.y - this.bmargin});
//修改坐标(L,R,T,B)
this.coordinate[0] = this.bbox.x;
this.coordinate[1] = this.bbox.x + this.bbox.width;
this.coordinate[2] = this.bbox.y;
this.coordinate[3] = this.bbox.y + this.bbox.height;
//圆心
this.ccelement.attr({"cx": this.centerpoint[0], "cy": this.centerpoint[1]});
//中心点向外扩展centerMargin=10,得到4条边,坐标(L,R,T,B)
this.centerLineCoordinate = [];
this.centerLineCoordinate.push(this.centerpoint[0] - this.centerMargin, this.centerpoint[0] + this.centerMargin, this.centerpoint[1] - this.centerMargin, this.centerpoint[1] + this.centerMargin);
//文字
this.text.attr({"x": this.centerpoint[0], "y": this.centerpoint[1] + this.r + 12});
//移动隐藏的中心竖线
this.centerLineY.attr("path", "M" + this.centerpoint[0] + ",0L" + this.centerpoint[0] + "," + this.flow._DEFALUTS_.height);
//移动隐藏的中心横线
this.centerLineX.attr("path", "M0," + this.centerpoint[1] + "L" + this.flow._DEFALUTS_.width + "," + this.centerpoint[1]);
var _that = this;
//所有进入的线,因为坐标变了,需要重绘
$.each(this.linein, function (index, lineElem) {
lineElem.redrawEnd(_that.cx, _that.cy);
});
//父元素处理
var parent = this.comeInSubProcess();
if (parent != null) {
//目前进入到子流程中
parent.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5});
}
//无论是否有父元素,都需要进入这个方法
this.addParent(parent);
},
setText: function (wenbenid) {
//得到文本框的值,重新赋值给text //Raphaël\nkicks\nbutt!
var tvalue = $(".taskinput input").val();
var temp = tvalue;
if ($.trim(tvalue) != "" && wenbenid == this.id) {
this.text.attr({"text": temp});
$(".taskinput input").val("");//清空
}
},
unSelect: function () {//非选中状态
//小菜单回归原位
$(".right").css({"left": -100, "top": -100});
//外框隐藏
this.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5}).hide();
this.ccelement.hide();
//文本框
if (this.selected == true) {
var wenbenid = $(".taskinput input").attr("wenbenid");
if (wenbenid) {
this.setText(wenbenid);
}
this.text.show();
}
//文本框回归原位
$(".taskinput").css({"left": -100, "top": -100});
//中心线隐藏
this.centerLineX.hide();
this.centerLineY.hide();
this.selected = false;
//完成情况的显示
if (this.completeState != 0) {
var name = "divshow_" + this.id;
$("#" + name).hide();
}
},
removeElement: function () {//end圆删除元素
this.element.remove();
this.centerLineX.remove();
this.centerLineY.remove();
this.elementbox.remove();
this.ccelement.remove();
this.text.remove();
//文本框回归
$(".taskinput").css({"left": -100, "top": -100});
//小菜单回归原位
$(".right").css({"left": -100, "top": -100});
//父元素
if (this.parentElem) {
this.parentElem.removeSubElement(this);
this.parentElem = null;
}
//移除相关的线
var tempinlines = [];
$.each(this.linein, function (index, line) {
tempinlines.push(line);
});
$.each(tempinlines, function (index, line) {
line && line.removeElement();
});
},
removeInLine: function (line) {
var _that = this;
$.each(this.linein, function (index, elem) {
if (elem && elem.id == line.id) {
_that.linein.splice(index, 1);
}
})
},
comeInSubProcess: function () { //判断是否在子流程里面
var parent = this.flow.collisionSubProcess(this.coordinate[0], this.coordinate[1], this.coordinate[2], this.coordinate[3]); //被碰撞
return parent;
},
comeInSubProcess2: function (L, R, T, B) {//判断是否在子流程里面
var parent = this.flow.collisionSubProcess(L, R, T, B); //被碰撞
return parent;
},
addParent: function (parent) {//在子流程里的处理
//判断落点是否在子流程内,如果落在子流程内,则需要修改parentElem
if (!parent) {
parent = this.flow.collisionSubProcess(this.coordinate[0], this.coordinate[1], this.coordinate[2], this.coordinate[3]); //被碰撞
}
if (parent != null) {
var ids = [];
$.each(parent.subElement, function (index, elem) {
ids.push(elem.id);
})
if ($.inArray(this.id, ids) == -1) {
this.parentElem = parent;
parent.subElement.push(this);
//表示新加入的到某个节点上,则原来的所有的线段需要移除
//移除相关的线
this.removeLine();
//节点置前
//this.element.toFront();
this.elementbox.toFront();
}
} else {//没有父元素
if (this.parentElem) {
this.parentElem.removeSubElement(this);
this.parentElem = null;
//表示新加入的到其他的,则原来子流程中的所有的线段需要移除
this.removeLine();
}
}
//return parent;
},
getText: function () {
return this.text.attr("text");
},
removeLine: function () { //删除线段
var tempinlines = [];
$.each(this.linein, function (index, line) {
if (!line.self) {
tempinlines.push(line);
}
});
$.each(tempinlines, function (index, line) {
line && line.removeElement();
if (line) {
delete this.flow.alllines[line.id]; //删除线元素
}
});
}
});
//转数字判断
function floatToFix4(num) {
return parseFloat(num).toFixed(4);
}
//线上的圆点移动 lineintance是Line的实例,
function _lineCircleMove(tx, ty, x, y, e, lineintance, circlecx, circlecy, circle, circlepxindex) {
//console.log(tx,ty,x,y,e);
lineintance.linepointsxy[circlepxindex][1] = circlecx + tx;
lineintance.linepointsxy[circlepxindex][2] = circlecy + ty;
//重写线段
lineintance.linestr = lineintance.combPath();
//lineintance.linestr="M"+lineintance.x1+","+lineintance.y1+"L"+(circlecx+tx)+","+(circlecy+ty)+"L"+lineintance.x2+","+lineintance.y2;
lineintance.line.attr("path", lineintance.linestr);
//lineintance.paper.circle(lineintance.bbox.cx+tx,lineintance.bbox.cy+ty,"3").attr("fill","#ff00ff");
circle.attr({"cx": circlecx + tx, "cy": circlecy + ty});
}
function _lineCircleStart(x, y, e, lineintance, circlecx, circlecy) {
return lineintance.currentPointInPathIndex(circlecx, circlecy);
}
function _lineCircleEnd(e, lineintance) {
lineintance.bbox = lineintance.line.getBBox();
lineintance.linebox.attr({
"x": lineintance.bbox.x,
"y": lineintance.bbox.y,
"width": lineintance.bbox.width,
"height": lineintance.bbox.height
});
lineintance.linepointsxy = Raphael.parsePathString(lineintance.linestr);
}
function Gateway(flow, options) {
this.flow = flow; //FlowDesigner类的实例
this.paper = flow.paper; //画布rapheal
this.options = options;
this.type = "gateway";
this.selected = false;
this.id = options.id ? options.id : "";
this.isLoad = options.isLoad ? true : false; //是否是加载的元素
this.detail = options.detail;
this.parentElem = null; //所属父级
this.parentElemStr = options.parentElem; //加载时所属父级的名称
this.element = null; //path 正菱形
this.img = null;
this.elementbox = null; //扩大外框
this.bbox = null; //外框
this.coordinate = []; //当前元素的四条边坐标
this.fourpoint = []; //四个元素顶点坐标
this.centerLineCoordinate = []; //圆元素的上下左右四条边坐标,为显示中心线,小一点
this.centerMargin = 10; //向中心点向外4个方向扩展的距离
//元素
this.cx = options.cx; //中心点坐标x
this.cy = options.cy;//中心点坐标y
this.r = options.r; //正菱形中心点到其他4个点的垂直距离
this.bmargin = 4; //外框和元素的边距
this.centerLineX = null;
this.centerLineY = null;
this.ccelement = null; //圆心
this.centerpoint = []; //矩形的中心点
this.linein = []; //所有进来的线
this.lineout = [];//所有出去的线
this.text = null; //文本
this.content = {}; //网关内容
this.completeState = options.completeState || 0; //0 代表否 1代表已完 2代表正当 3代表还未开始
}
Gateway.prototype = $.extend(Gateway.prototype, {
init: function () {
var number = this.flow.createGatewayNum();
var tempName = (new Date()).getTime();
//根据中心点和垂直半径得到四个顶点 //左上右下
this.fourpoint = [{"x": this.cx - this.r, "y": this.cy}, {
"x": this.cx,
"y": this.cy - this.r
}, {"x": this.cx + this.r, "y": this.cy}, {"x": this.cx, "y": this.cy + this.r}];
//var c = paper.path("M10 10L90 90");
var str = "M" + this.fourpoint[0].x + "," + this.fourpoint[0].y + "L" + this.fourpoint[1].x + "," + this.fourpoint[1].y + "L" + this.fourpoint[2].x + "," + this.fourpoint[2].y + "L" + this.fourpoint[3].x + "," + this.fourpoint[3].y + "Z";
//菱形元素
switch (this.completeState) {
case 1: //蓝色
this.element = this.paper.path(str).attr({
"fill": "#e0e9fe",
"cursor": "pointer",
"stroke": "#2632aa",
"stroke-width": 1
});
break;
case 2://绿色
this.element = this.paper.path(str).attr({
"fill": "#ebf8eb",
"cursor": "pointer",
"stroke": "#017501",
"stroke-width": 1
});
break;
case 3://灰色
this.element = this.paper.path(str).attr({
"fill": "#dadada",
"cursor": "pointer",
"stroke": "#acacac",
"stroke-width": 1
});
break;
default:
this.element = this.paper.path(str).attr({
"cursor": "pointer",
"fill": "#ffffff",
"stroke": "#585858",
"stroke-width": 1
});
break;
}
//正菱形
switch (this.detail) {
case "exclusiveGateway":
//this.img=this.paper.image("/flowmodify/images/exclusive_bg.png", this.cx-9, this.cy-9, 18, 18);
if (this.completeState == 0) {
this.img = this.paper.image(GatewayImgs.exclusiveGateway, this.cx - 9, this.cy - 9, 18, 18).attr({"cursor": "pointer"});
} else if (this.completeState == 1) { //蓝色
this.img = this.paper.image(GatewayImgsBlue.exclusiveGateway, this.cx - 9, this.cy - 9, 18, 18).attr({"cursor": "pointer"});
} else if (this.completeState == 2) {//绿色
this.img = this.paper.image(GatewayImgsGreen.exclusiveGateway, this.cx - 9, this.cy - 9, 18, 18).attr({"cursor": "pointer"});
} else if (this.completeState == 3) {//灰色
this.img = this.paper.image(GatewayImgsGray.exclusiveGateway, this.cx - 9, this.cy - 9, 18, 18).attr({"cursor": "pointer"});
}
if (!this.isLoad) {
this.id = "exclusiveGateway_" + tempName;
}
break;
case "parallelGateway":
if (this.completeState == 0) {
this.img = this.paper.image(GatewayImgs.parallelGateway, this.cx - 10, this.cy - 10, 20, 20).attr({"cursor": "pointer"});
} else if (this.completeState == 1) {//蓝色
this.img = this.paper.image(GatewayImgsBlue.parallelGateway, this.cx - 10, this.cy - 10, 20, 20).attr({"cursor": "pointer"});
} else if (this.completeState == 2) {//绿色
this.img = this.paper.image(GatewayImgsGreen.parallelGateway, this.cx - 10, this.cy - 10, 20, 20).attr({"cursor": "pointer"});
} else if (this.completeState == 3) {//灰色
this.img = this.paper.image(GatewayImgsGray.parallelGateway, this.cx - 10, this.cy - 10, 20, 20).attr({"cursor": "pointer"});
}
if (!this.isLoad) {
this.id = "parallelGateway_" + tempName;
}
break;
case "inclusiveGateway":
if (this.completeState == 0) {
this.img = this.paper.image(GatewayImgs.inclusiveGateway, this.cx - 11, this.cy - 11, 22, 22).attr({"cursor": "pointer"});
} else if (this.completeState == 1) {//蓝色
this.img = this.paper.image(GatewayImgsBlue.inclusiveGateway, this.cx - 11, this.cy - 11, 22, 22).attr({"cursor": "pointer"});
} else if (this.completeState == 2) {//绿色
this.img = this.paper.image(GatewayImgsGreen.inclusiveGateway, this.cx - 11, this.cy - 11, 22, 22).attr({"cursor": "pointer"});
} else if (this.completeState == 3) {//灰色
this.img = this.paper.image(GatewayImgsGray.inclusiveGateway, this.cx - 11, this.cy - 11, 22, 22).attr({"cursor": "pointer"});
}
if (!this.isLoad) {
this.id = "inclusiveGateway_" + tempName;
}
break;
}
//外框
this.bbox = this.element.getBBox();
//console.log(this.bbox);
//扩大外框
this.elementbox = this.paper.rect(this.bbox.x - this.bmargin, this.bbox.y - this.bmargin, this.bbox.width + this.bmargin * 2, this.bbox.height + this.bmargin * 2).attr({
"stroke-dasharray": "- ",
stroke: "#000000",
"stroke-width": 0.5,
"fill": "#ff0000",
"fill-opacity": 0
});
//坐标(L,R,T,B)
this.coordinate.push(this.bbox.x, this.bbox.x + this.bbox.width, this.bbox.y, this.bbox.y + this.bbox.height);
//中心点坐标
this.centerpoint = [this.bbox.x + this.bbox.width / 2, this.bbox.y + this.bbox.height / 2];
//中心点向外扩展centerMargin=10,得到4条边,坐标(L,R,T,B)
this.centerLineCoordinate.push(this.centerpoint[0] - this.centerMargin, this.centerpoint[0] + this.centerMargin, this.centerpoint[1] - this.centerMargin, this.centerpoint[1] + this.centerMargin);
//文字
if (!this.isLoad) {
this.text = this.paper.text(this.centerpoint[0], this.centerpoint[1] + this.r + 12, "网关" + number).attr({"font-size": "12px"});
} else {
this.text = this.paper.text(this.centerpoint[0], this.centerpoint[1] + this.r + 12, this.options.text).attr({"font-size": "12px"});
}
//隐藏的中心竖线
this.centerLineY = this.paper.path("M" + this.centerpoint[0] + ",0L" + this.centerpoint[0] + "," + this.flow._DEFALUTS_.height).attr({
"stroke-width": 2,
"stroke": "#c1c1c1",
"stroke-dasharray": "- "
}).hide();
//隐藏的中心横线
this.centerLineX = this.paper.path("M0," + this.centerpoint[1] + "L" + this.flow._DEFALUTS_.width + "," + this.centerpoint[1]).attr({
"stroke-width": 2,
"stroke": "#c1c1c1",
"stroke-dasharray": "- "
}).hide();
this.ccelement = this.paper.circle(this.centerpoint[0], this.centerpoint[1], 2).attr({
"fill": "#ff0000",
"stroke": "ff0000"
}).hide(); //圆心
//添加父元素
if (!this.isLoad) {
this.addParent();
}
var _that = this;
if (this.completeState == 0) {
//菱形的外框点击
this.elementbox.click(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
//小菜单
$(".right").css({
"left": _that.cx + _that.r + 10 - _that.flow.getScrollx(),
"top": _that.cy - _that.r + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()
}).attr("tempid", _that.id).end().find(".sequence").attr("tempid", _that.id).show();
_that.selected = true; //选中元素
var wenbenid = $(".taskinput input").attr("wenbenid");
if (wenbenid) {
_that.setText(wenbenid);
}
_that.text.show();
}
});
//菱形的外框双击
this.elementbox.dblclick(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
var tvalue = _that.text.attr("text");
$(".taskinput input").val(tvalue);
$(".taskinput input").attr("wenbenid", _that.id);
//显示文本框,-10任意调整的,为了显示在中间
$(".taskinput").css({
"left": _that.cx - _that.r - 10 - _that.flow.getScrollx(),
"top": (_that.cy - 10 + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()),
"width": 60
});
_that.selected = true;
//文本框本身隐藏
_that.text.hide();
}
});
//菱形的单击
this.element.click(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
_that.elementbox.show();
$(".right").css({
"left": _that.cx + _that.r + 10 - _that.flow.getScrollx(),
"top": _that.cy - _that.r + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()
}).attr("tempid", _that.id).end().find(".sequence").attr("tempid", _that.id).show();
}
});
//菱形中图片的单击
this.img.click(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
_that.elementbox.show();
$(".right").css({
"left": _that.cx + _that.r + 10 - _that.flow.getScrollx(),
"top": _that.cy - _that.r + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()
}).attr("tempid", _that.id).end().find(".sequence").attr("tempid", _that.id).show();
}
});
//网关节点的外层框拖动
var weiyiX = 0;
var weiyiY = 0;
var dropStatus = false;
var startX = 0;
var startY = 0;
var bpz = null;
var bpzcenter = null;
var startpointx = 0;
var startpointy = 0;
this.elementbox.drag(function (tx, ty, x, y, e) { //move中
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
dropStatus = true;
//限制去菜单那块
if (e.clientX < (134 + _that.flow._DEFALUTS_.dx + weiyiX)) {
e.clientX = 134 + _that.flow._DEFALUTS_.dx;
dropStatus = false;
return;
}
//限制画布最右侧边界
if (e.clientX > _that.flow._DEFALUTS_.width - (_that.r + _that.bmargin) * 2 + _that.flow._DEFALUTS_.dx + weiyiX) {
dropStatus = false;
return;
}
//限制头部
if (e.clientY < (0 + _that.flow._DEFALUTS_.dy + weiyiY)) {
e.clientY = 0 + _that.flow._DEFALUTS_.dy;
dropStatus = false;
return;
}
//限制画布底部边界
if (e.clientY > (0 + _that.flow._DEFALUTS_.height - (_that.r + _that.bmargin) * 2 + _that.flow._DEFALUTS_.dy + weiyiY)) {
dropStatus = false;
return;
}
this.attr({
"x": e.clientX - _that.flow._DEFALUTS_.dx - weiyiX,
"y": e.clientY - _that.flow._DEFALUTS_.dy - weiyiY
});
//碰撞检测
var L = e.clientX - _that.flow._DEFALUTS_.dx - weiyiX;
var R = L + _that.r * 2;
var T = e.clientY - _that.flow._DEFALUTS_.dy - weiyiY;
var B = T + _that.r * 2;
bpz = _that.flow.collision(_that, L, R, T, B); //被碰撞
if (bpz != null && bpz.type != "subProcess") {
dropStatus = false;
}
bpzcenter = _that.flow.collisionCenterLine(_that, L, R, T, B); //中心线匹配
}
}, function (x, y, e) { //move开始
weiyiX = e.clientX - _that.flow._DEFALUTS_.dx - _that.bbox.x + _that.bmargin; //offsetX,不需要减1
weiyiY = e.clientY - _that.flow._DEFALUTS_.dy - _that.bbox.y + _that.bmargin; //offsetY,不需要减32
startX = _that.bbox.x - _that.bmargin;
startY = _that.bbox.y - _that.bmargin;
startpointx = e.clientX;
startpointy = e.clientY;
}, function (e) {//move结束
var endpointx = e.clientX;
var endpointy = e.clientY;
if (Math.abs(endpointx - startpointx) < 2 && Math.abs(endpointy - startpointy) < 2) {//阻止点击就移动
dropStatus = false;
}
if (dropStatus == true) {
var elemnetboxbbox = this.getBBox();
//判断是否进入子流程
if (bpz && bpz.type == "subProcess") {
//说明进入在子流程中
if (_that.parentElem == null || _that.parentElem.id != bpz.id) {
//表示新的入到一个子流程中
if (_that.linein.length > 0 || _that.lineout.length > 0) {
//如果含有线段,则必须提示,因为进入新的空间,旧的空间中的线段需要删除
$.messager.confirm('再次确认', '该网关节点进入子流程会删除原来的线段,还要继续进入吗?', function (r) {
if (!r) {
_that.elementbox.attr({"x": startX, "y": startY}); //不能落下的地方就返回
} else {
_that.render(elemnetboxbbox.cx, elemnetboxbbox.cy, bpzcenter);
}
})
} else {
//没有线段
_that.render(elemnetboxbbox.cx, elemnetboxbbox.cy, bpzcenter);
}
}
} else if (bpz == null) {
if (_that.parentElem != null) {
//原来在小空间中
if (_that.linein.length > 0 || _that.lineout.length > 0) {
//如果含有线段,则必须提示,因为进入新的空间,旧的空间中的线段需要删除
var L = elemnetboxbbox.x;
var R = L + _that.r * 2;
var T = elemnetboxbbox.y;
var B = T + _that.r * 2;
//判断当前是否已经出了小空间
if (!_that.comeInSubProcess2(L, R, T, B)) {
$.messager.confirm('再次确认', '该网关节点原属于子流程空间,进入父空间时会删除原来的线段,还要继续进入吗?', function (r) {
if (!r) {
_that.elementbox.attr({"x": startX, "y": startY}); //不能落下的地方就返回
} else {
_that.render(elemnetboxbbox.cx, elemnetboxbbox.cy, bpzcenter);
}
})
} else {
//没有出小空间
_that.render(elemnetboxbbox.cx, elemnetboxbbox.cy, bpzcenter);
}
} else {
//没有线段
_that.render(elemnetboxbbox.cx, elemnetboxbbox.cy, bpzcenter);
}
} else {
//原来在大空间中
_that.render(elemnetboxbbox.cx, elemnetboxbbox.cy, bpzcenter);
}
}
} else {
this.attr({"x": startX, "y": startY}); //不能落下的地方就返回
}
dropStatus = false;
return false;
});
}
},
render: function (cx, cy, bpzcenter) { //网关的渲染
if (bpzcenter != null) {
if (bpzcenter[0] != null && bpzcenter[1] == null) {
//y轴吸附,x轴不吸附
if (bpzcenter[0].type == "start" || bpzcenter[0].type == "end" || bpzcenter[0].type == "gateway") {
cx = bpzcenter[0].cx;
} else if (bpzcenter[0].type == "userTask" || bpzcenter[0].type == "subProcess") {
cx = bpzcenter[0].x + bpzcenter[0].w / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
} else if (bpzcenter[0] == null && bpzcenter[1] != null) {
//x轴吸附,y轴不吸附
if (bpzcenter[1].type == "start" || bpzcenter[1].type == "end" || bpzcenter[1].type == "gateway") {
cy = bpzcenter[1].cy;
} else if (bpzcenter[1].type == "userTask" || bpzcenter[1].type == "subProcess") {
cy = bpzcenter[1].y + bpzcenter[1].h / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
} else if (bpzcenter[0] != null && bpzcenter[1] != null) {
//y轴吸附,x轴吸附
if (bpzcenter[0].type == "start" || bpzcenter[0].type == "end" || bpzcenter[0].type == "gateway") {
cx = bpzcenter[0].cx;
} else if (bpzcenter[0].type == "userTask" || bpzcenter[0].type == "subProcess") {
cx = bpzcenter[0].x + bpzcenter[0].w / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
if (bpzcenter[1].type == "start" || bpzcenter[1].type == "end" || bpzcenter[1].type == "gateway") {
cy = bpzcenter[1].cy;
} else if (bpzcenter[1].type == "userTask" || bpzcenter[1].type == "subProcess") {
cy = bpzcenter[1].y + bpzcenter[1].h / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
}
}
// this.cx = x + this.r;
// this.cy = y + this.r;
this.cx = cx;
this.cy = cy;
this.fourpoint = [{"x": this.cx - this.r, "y": this.cy}, {
"x": this.cx,
"y": this.cy - this.r
}, {"x": this.cx + this.r, "y": this.cy}, {"x": this.cx, "y": this.cy + this.r}];
//var c = paper.path("M10 10L90 90");
var str = "M" + this.fourpoint[0].x + "," + this.fourpoint[0].y + "L" + this.fourpoint[1].x + "," + this.fourpoint[1].y + "L" + this.fourpoint[2].x + "," + this.fourpoint[2].y + "L" + this.fourpoint[3].x + "," + this.fourpoint[3].y + "Z";
this.element.attr("path", str);
switch (this.detail) {
case "exclusiveGateway":
this.img.attr({"x": this.cx - 9, "y": this.cy - 9});
break;
case "parallelGateway":
this.img.attr({"x": this.cx - 10, "y": this.cy - 10});
break;
case "inclusiveGateway":
this.img.attr({"x": this.cx - 11, "y": this.cy - 11});
break;
}
this.bbox = this.element.getBBox();
//扩大的外框
this.elementbox.attr({"x": this.bbox.x - this.bmargin, "y": this.bbox.y - this.bmargin});
//修改坐标(L,R,T,B)
this.coordinate[0] = this.bbox.x;
this.coordinate[1] = this.bbox.x + this.bbox.width;
this.coordinate[2] = this.bbox.y;
this.coordinate[3] = this.bbox.y + this.bbox.height;
//中心点坐标
this.centerpoint = [this.cx, this.cy];
//中心点向外扩展centerMargin=10,得到4条边,坐标(L,R,T,B)
this.centerLineCoordinate = [];
this.centerLineCoordinate.push(this.centerpoint[0] - this.centerMargin, this.centerpoint[0] + this.centerMargin, this.centerpoint[1] - this.centerMargin, this.centerpoint[1] + this.centerMargin);
//文字
this.text.attr({"x": this.centerpoint[0], "y": this.centerpoint[1] + this.r + 12});
//移动隐藏的中心竖线
this.centerLineY.attr("path", "M" + this.centerpoint[0] + ",0L" + this.centerpoint[0] + "," + this.flow._DEFALUTS_.height);
//移动隐藏的中心横线
this.centerLineX.attr("path", "M0," + this.centerpoint[1] + "L" + this.flow._DEFALUTS_.width + "," + this.centerpoint[1]);
this.ccelement.attr({"cx": this.centerpoint[0], "cy": this.centerpoint[1]});
//父元素处理
var parent = this.comeInSubProcess();
if (parent != null) {
//目前进入到子流程中
parent.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5});
}
//无论是否有父元素,都需要进入这个方法
this.addParent(parent);
var _that = this;
//所有出去的点,因为坐标变了,需要重绘
$.each(this.lineout, function (index, lineElem) {
lineElem.redrawStart(_that.cx, _that.cy);
});
//所有进入的点,因为坐标变了,需要重绘
$.each(this.linein, function (index, lineElem) {
//得到点
lineElem.redrawEnd(_that.cx, _that.cy);
});
},
setText: function (wenbenid) {
//得到文本框的值,重新赋值给text //Raphaël\nkicks\nbutt!
var tvalue = $(".taskinput input").val();
var temp = tvalue;
if ($.trim(tvalue) != "" && wenbenid == this.id) {
this.text.attr({"text": temp});
$(".taskinput input").val("");//清空
}
},
unSelect: function () { //gateway的unSelect
//小菜单回归原位
$(".right").css({"left": -100, "top": -100});
//外框隐藏
this.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5}).hide();
//圆心
this.ccelement.hide();
//文本框
if (this.selected == true) {
var wenbenid = $(".taskinput input").attr("wenbenid");
if (wenbenid) {
this.setText(wenbenid);
}
this.text.show();
}
//文本框回归原位
$(".taskinput").css({"left": -100, "top": -100});
//中心线隐藏
this.centerLineX.hide();
this.centerLineY.hide();
this.selected = false;
//完成情况的显示
if (this.completeState != 0) {
var name = "divshow_" + this.id;
$("#" + name).hide();
}
},
removeElement: function () {
this.element.remove();
this.centerLineX.remove();
this.centerLineY.remove();
this.elementbox.remove();
this.img.remove();
this.ccelement.remove();
this.text.remove();
//文本框回归
$(".taskinput").css({"left": -100, "top": -100});
//小菜单回归原位
$(".right").css({"left": -100, "top": -100});
//删除父元素中对本元素的调用
if (this.parentElem) {
this.parentElem.removeSubElement(this);
this.parentElem = null;
}
//移除相关的线
var tempoutlines = [];
$.each(this.lineout, function (index, line) {
tempoutlines.push(line);
});
$.each(tempoutlines, function (index, line) {
line && line.removeElement();
});
var tempinlines = [];
$.each(this.linein, function (index, line) {
tempinlines.push(line);
});
$.each(tempinlines, function (index, line) {
line && line.removeElement();
});
},
removeOutLine: function (line) {
var _that = this;
$.each(this.lineout, function (index, elem) {
if (elem && elem.id == line.id) {
_that.lineout.splice(index, 1);
}
})
},
removeInLine: function (line) {
var _that = this;
$.each(this.linein, function (index, elem) {
if (elem && elem.id == line.id) {
_that.linein.splice(index, 1);
}
})
},
comeInSubProcess: function () { //判断是否在子流程里面
var parent = this.flow.collisionSubProcess(this.coordinate[0], this.coordinate[1], this.coordinate[2], this.coordinate[3]); //被碰撞
return parent;
},
comeInSubProcess2: function (L, R, T, B) {//判断是否在子流程里面
console.log(L, R, T, B)
var parent = this.flow.collisionSubProcess(L, R, T, B); //被碰撞
return parent;
},
addParent: function (parent) {//在子流程里的处理
//判断落点是否在子流程内,如果落在子流程内,则需要修改parentElem
if (!parent) {
parent = this.flow.collisionSubProcess(this.coordinate[0], this.coordinate[1], this.coordinate[2], this.coordinate[3]); //被碰撞
}
if (parent != null) {
var ids = [];
$.each(parent.subElement, function (index, elem) {
ids.push(elem.id);
})
if ($.inArray(this.id, ids) == -1) {
this.parentElem = parent;
parent.subElement.push(this);
//表示新加入的到某个节点上,则原来的所有的线段需要移除
//移除相关的线
this.removeLine();
//节点置前
//this.element.toFront();
this.elementbox.toFront();
}
} else {//没有父元素
if (this.parentElem) {
this.parentElem.removeSubElement(this);
this.parentElem = null;
//表示新加入的到其他的,则原来子流程中的所有的线段需要移除
this.removeLine();
}
}
//return parent;
},
getText: function () {
return this.text.attr("text");
},
removeLine: function () { //删除线段
var tempoutlines = [];
$.each(this.lineout, function (index, line) {
if (!line.self) {
tempoutlines.push(line);
}
});
$.each(tempoutlines, function (index, line) {
line && line.removeElement();
if (line) {
delete this.flow.alllines[line.id]; //删除线元素
}
});
var tempinlines = [];
$.each(this.linein, function (index, line) {
if (!line.self) {
tempinlines.push(line);
}
});
$.each(tempinlines, function (index, line) {
line && line.removeElement();
if (line) {
delete this.flow.alllines[line.id]; //删除线元素
}
});
}
});
//子流程
function SubProcess(flow, options) {
this.flow = flow; //FlowDesigner类的实例
this.paper = flow.paper; //画布rapheal
this.options = options;
this.type = "subProcess";
this.selected = false;
this.id = options.id ? options.id : "";
this.isLoad = options.isLoad ? true : false; //是否是加载的元素
this.parentElem = null; //所属父级
//this.parentElemStr=options.parentElem; //加载时所属父级的名称
this.element = null; //任务方块
this.elementbox = null; //扩大外框
this.bbox = null; //外框
this.coordinate = []; //当前元素的上下左右坐标
this.fourpoint = []; //四个元素顶点坐标
this.centerLineCoordinate = []; //圆元素的上下左右四条边坐标,为显示中心线,小一点
this.centerMargin = 10; //向中心点向外4个方向扩展的距离
this.centerLineY = null;
this.centerLineX = null;
//控制点
this.$elementctrl1 = null;
this.$elementctrl4 = null;
//元素
this.x = options.x; //顶点坐标x
this.y = options.y;//顶点坐标y
this.w = options.w;//宽
this.h = options.h;//高
this.angle = 4; //弧度
this.bmargin = 4; //外框和元素的边距
this.ccelement = null; //圆心
this.centerpoint = []; //矩形的中心点
this.linein = []; //所有进来的线
this.lineout = [];//所有出去的线
this.subElement = [];//所有子元素
this.content = {}; //子流程内容
this.completeState = options.completeState || 0; //0 代表否 1代表已完 2代表正当 3代表还未开始
}
SubProcess.prototype = $.extend(SubProcess.prototype, {
init: function () {
var number = this.flow.createSubprocessNum();
var tempName = (new Date()).getTime();
if (!this.isLoad) {
this.id = "subProcess_" + tempName;
}
//矩形框
switch (this.completeState) {
case 1://蓝色
this.element = this.paper.rect(this.x, this.y, this.w, this.h, this.angle).attr({
"fill": "#e0e9fe",
"cursor": "pointer",
"stroke": "#2632aa"
}).toBack();
break;
case 2://绿色
this.element = this.paper.rect(this.x, this.y, this.w, this.h, this.angle).attr({
"fill": "#ebf8eb",
"cursor": "pointer",
"stroke": "#017501"
}).toBack();
break;
case 3://灰色
this.element = this.paper.rect(this.x, this.y, this.w, this.h, this.angle).attr({
"fill": "#dadada",
"cursor": "pointer",
"stroke": "#acacac"
}).toBack();
break;
default:
this.element = this.paper.rect(this.x, this.y, this.w, this.h, this.angle).attr({
"fill": "#ffffff",
"fill-opacity": 0,
"cursor": "pointer"
}).toBack();
break;
}
//外框
this.bbox = this.element.getBBox();
//扩大外框
this.elementbox = this.paper.rect(this.bbox.x - this.bmargin, this.bbox.y - this.bmargin, this.bbox.width + this.bmargin * 2, this.bbox.height + this.bmargin * 2, false).attr({
"stroke-dasharray": "- ",
stroke: "#000000",
"stroke-width": 0.5,
"fill": "#ff0000",
"fill-opacity": 0
});
//坐标(L,R,T,B)
this.coordinate.push(this.bbox.x, this.bbox.x + this.bbox.width, this.bbox.y, this.bbox.y + this.bbox.height);
//根据中心点和宽度得到四个顶点 //定点开始顺时针
this.fourpoint = [{"x": this.x, "y": this.y}, {"x": this.x + this.w, "y": this.y}, {
"x": this.x + this.w,
"y": this.y + this.h
}, {"x": this.x, "y": this.y + this.h}];
//文字
if (!this.isLoad) {
this.text = this.paper.text(this.bbox.x + this.bbox.width / 2, this.bbox.y + 14, "子流程" + number).attr({"font-size": "14px"});
} else {
this.text = this.paper.text(this.bbox.x + this.bbox.width / 2, this.bbox.y + 14, this.options.text).attr({"font-size": "14px"});
}
//控制点,-10.+8就是想放在框外边
this.$elementctrl1 = $("
");
$("#" + this.flow._DEFALUTS_.id).append(this.$elementctrl1);
this.$elementctrl4 = $("
");
$("#" + this.flow._DEFALUTS_.id).append(this.$elementctrl4);
//中心点坐标
this.centerpoint = [this.bbox.x + this.bbox.width / 2, this.bbox.y + this.bbox.height / 2];
//中心点向外扩展centerMargin=10,得到4条边,坐标(L,R,T,B)
this.centerLineCoordinate.push(this.centerpoint[0] - this.centerMargin, this.centerpoint[0] + this.centerMargin, this.centerpoint[1] - this.centerMargin, this.centerpoint[1] + this.centerMargin);
//隐藏的中心竖线
this.centerLineY = this.paper.path("M" + this.centerpoint[0] + ",0L" + this.centerpoint[0] + "," + this.flow._DEFALUTS_.height).attr({
"stroke-width": 2,
"stroke": "#c1c1c1",
"stroke-dasharray": "- "
}).hide();
//隐藏的中心横线
this.centerLineX = this.paper.path("M0," + this.centerpoint[1] + "L" + this.flow._DEFALUTS_.width + "," + this.centerpoint[1]).attr({
"stroke-width": 2,
"stroke": "#c1c1c1",
"stroke-dasharray": "- "
}).hide();
this.ccelement = this.paper.circle(this.centerpoint[0], this.centerpoint[1], 2).attr({
"fill": "#ff0000",
"stroke": "ff0000"
}).hide(); //圆心
var _that = this;
if (this.completeState == 0) {
//子流程的外框点击
this.elementbox.click(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
//小菜单
$(".right").css({
"left": _that.x + _that.w + 10 - _that.flow.getScrollx(),
"top": _that.y + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()
}).attr("tempid", _that.id).end().find(".sequence").attr("tempid", _that.id).show();
//隐藏控制点
_that.$elementctrl1.hide();
_that.$elementctrl4.hide();
_that.selected = true; //选中元素
_that.elementbox.show();
var wenbenid = $(".taskinput input").attr("wenbenid");
if (wenbenid) {
_that.setText(wenbenid);
}
_that.text.show();
}
});
//子流程的外框双击
this.elementbox.dblclick(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
var tvalue = _that.text.attr("text");
$(".taskinput input").val(tvalue);
$(".taskinput input").attr("wenbenid", _that.id);
//显示文本框
$(".taskinput").css({
"left": _that.x - _that.flow.getScrollx(),
"top": (_that.y + 2 + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()),
"width": _that.w
});
_that.selected = true;
//文本框本身隐藏
_that.text.hide();
}
});
//子流程的单击
this.element.click(function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
_that.elementbox.show();
$(".right").css({
"left": _that.x + _that.w + 10 - _that.flow.getScrollx(),
"top": _that.y + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()
}).attr("tempid", _that.id).end().find(".sequence").attr("tempid", _that.id).show();
//显示控制点
_that.$elementctrl1.show();
_that.$elementctrl4.show();
}
});
//子流程节点的外层框拖动
var weiyiX = 0;
var weiyiY = 0;
var dropStatus = false;
var startX = 0;
var startY = 0;
var bpz = null;
var bpzcenter = null;
var startpointx = 0;
var startpointy = 0;
this.elementbox.drag(function (tx, ty, x, y, e) { //move中
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
dropStatus = true;
//限制去菜单那块
if (e.clientX < (134 + _that.flow._DEFALUTS_.dx + weiyiX)) {
e.clientX = 134 + _that.flow._DEFALUTS_.dx;
dropStatus = false;
return;
}
//限制画布最右侧边界
if (e.clientX > _that.flow._DEFALUTS_.width - (_that.w + _that.bmargin * 2) + _that.flow._DEFALUTS_.dx + weiyiX) {
dropStatus = false;
return;
}
//限制头部
if (e.clientY < (0 + _that.flow._DEFALUTS_.dy + weiyiY)) {
e.clientY = 0 + _that.flow._DEFALUTS_.dy;
dropStatus = false;
return;
}
//限制画布底部边界
if (e.clientY > (0 + _that.flow._DEFALUTS_.height - (_that.h + _that.bmargin * 2) + _that.flow._DEFALUTS_.dy + weiyiY)) {
dropStatus = false;
return;
}
this.attr({
"x": e.clientX - _that.flow._DEFALUTS_.dx - weiyiX,
"y": e.clientY - _that.flow._DEFALUTS_.dy - weiyiY
});
//碰撞检测
var L = e.clientX - _that.flow._DEFALUTS_.dx - weiyiX;
var R = L + _that.w;
var T = e.clientY - _that.flow._DEFALUTS_.dy - weiyiY;
var B = T + _that.h;
//console.log(_that.id, L, R, T, B);
bpz = _that.flow.collision(_that, L, R, T, B); //被碰撞
if (bpz != null) {
dropStatus = false;
}
bpzcenter = _that.flow.subProcessCollisionCenterLine(_that, L, R, T, B); //中心线匹配
}
}, function (x, y, e) { //move开始
//文本框回归原位
$(".taskinput").css({"left": -100, "top": -100});
weiyiX = e.clientX - _that.flow._DEFALUTS_.dx - _that.bbox.x + _that.bmargin; //offsetX,不需要减1
weiyiY = e.clientY - _that.flow._DEFALUTS_.dy - _that.bbox.y + _that.bmargin; //offsetY,不需要减32
startX = _that.bbox.x - _that.bmargin;
startY = _that.bbox.y - _that.bmargin;
startpointx = e.clientX;
startpointy = e.clientY;
}, function (e) {//move结束
var endpointx = e.clientX;
var endpointy = e.clientY;
if (Math.abs(endpointx - startpointx) < 2 && Math.abs(endpointy - startpointy) < 2) {//阻止点击就移动
dropStatus = false;
}
if (dropStatus == true) {
var x = e.clientX - _that.flow._DEFALUTS_.dx - weiyiX;
var y = e.clientY - _that.flow._DEFALUTS_.dy - weiyiY;
//本身渲染
var dxy = _that.render(x, y, bpzcenter);
//子元素的移动
//var dx=endpointx - startpointx;
//var dy=endpointy - startpointy;
var dx = dxy.dx;
var dy = dxy.dy;
var lines = [];
var linestrs = [];
//收集线段,必须先收集线段,修改小圆点坐标,再收集节点。因为节点上需要修改起始和结束的位置,需要已经修改好的小圆点
$.each(_that.subElement, function (index, elem) {
switch (elem.type) {
case "end":
$.each(elem.linein, function (index, line) {
if ($.inArray(line.id, linestrs) == -1) {
linestrs.push(line.id);
lines.push(line);
}
});
break;
case "start":
$.each(elem.lineout, function (index, line) {
if ($.inArray(line.id, linestrs) == -1) {
linestrs.push(line.id);
lines.push(line);
}
});
break;
case "gateway":
case "userTask":
$.each(elem.linein, function (index, line) {
if ($.inArray(line.id, linestrs) == -1) {
linestrs.push(line.id);
lines.push(line);
}
});
$.each(elem.lineout, function (index, line) {
if ($.inArray(line.id, linestrs) == -1) {
linestrs.push(line.id);
lines.push(line);
}
})
break;
}
})
//修改线段上的小圆点坐标
//线上小圆点的渲染
$.each(lines, function (index, line) {
$.each(line.linepoints, function (index, sc) {
var circlepxindex = sc.belongLine.currentPointInPathIndex(sc.cx, sc.cy);
var newcx = sc.cx + dx, newcy = sc.cy + dy;
sc.render({"cx": newcx, "cy": newcy});
sc.belongLine.linepointsxy[circlepxindex][1] = newcx;
sc.belongLine.linepointsxy[circlepxindex][2] = newcy;
//重写线段
sc.belongLine.linestr = sc.belongLine.combPath();
sc.belongLine.line.attr("path", sc.belongLine.linestr);
//修改text坐标
sc.belongLine.renderText();
})
})
//收集元素
$.each(_that.subElement, function (index, elem) {
switch (elem.type) {
case "end":
case "gateway":
case "start":
var cx = elem.cx + dx, cy = elem.cy + dy;
elem.render(cx, cy, null);
break;
case "userTask":
var x = elem.x + dx, y = elem.y + dy;
elem.render(x, y, null);
break;
}
});
} else {
this.attr({"x": startX, "y": startY}); //不能落下的地方就返回
}
dropStatus = false;
return false;
});
//子流程的控制点4的移动
var ctrl4startx = 0;
var ctrl4starty = 0;
var ctrl4oldstartx = 0;
var ctrl4oldstarty = 0;
this.$elementctrl4.draggable({
cursor: "se-resize",
revert: true,
onStartDrag: function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
ctrl4oldstartx = ctrl4startx = e.clientX;
ctrl4oldstarty = ctrl4starty = e.clientY;
}
},
onDrag: function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
var elementboxbox = _that.elementbox.getBBox();
var width = elementboxbox.width;
var height = elementboxbox.height;
var ctrl4dragpointx = e.clientX;
var ctrl4dragpointy = e.clientY;
width = width + ctrl4dragpointx - ctrl4startx;
height = height + ctrl4dragpointy - ctrl4starty;
_that.elementbox.attr({"width": width, "height": height});
ctrl4startx = ctrl4dragpointx;
ctrl4starty = ctrl4dragpointy;
}
},
onStopDrag: function (e) {
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
var ctrl4endx = e.clientX;
var ctrl4endy = e.clientY;
var dwidth = ctrl4endx - ctrl4oldstartx;
var dheight = ctrl4endy - ctrl4oldstarty;
var elementWidth = _that.element.attr("width");
var elementHeight = _that.element.attr("height");
_that.element.attr({"width": elementWidth + dwidth, "height": elementHeight + dheight});
_that.w = elementWidth + dwidth;
_that.h = elementHeight + dheight;
_that.render(_that.bbox.x, _that.bbox.y, null);
}
}
})
//子流程的控制点1的移动(移动的是left,top,width,height)
var ctrl1startx = 0;
var ctrl1starty = 0;
var ctrl1oldstartx = 0;
var ctrl1oldstarty = 0;
var ctr1tx = 0;
var ctr1ty = 0;
this.$elementctrl1.draggable({
cursor: "nw-resize",
revert: true,
onStartDrag: function (e) {
ctrl1oldstartx = ctrl1startx = e.clientX;
ctrl1oldstarty = ctrl1starty = e.clientY;
var oldleft = $(this).css("left");
var oldtop = $(this).css("top");
ctr1tx = e.clientX - parseFloat(oldleft);
ctr1ty = e.clientY - parseFloat(oldtop);
},
onDrag: function (e) {
var elementboxbox = _that.elementbox.getBBox();
var width = elementboxbox.width;
var height = elementboxbox.height;
var ctrl1dragpointx = e.clientX;
var ctrl1dragpointy = e.clientY;
width = width - (ctrl1dragpointx - ctrl1startx);
height = height - (ctrl1dragpointy - ctrl1starty);
var ctr1left = e.clientX - ctr1tx - _that.flow._DEFALUTS_.dx + 10;
var ctr1top = e.clientY - ctr1ty - _that.flow._DEFALUTS_.dy + 10;
_that.elementbox.attr({"x": ctr1left, "y": ctr1top, "width": width, "height": height});
ctrl1startx = ctrl1dragpointx;
ctrl1starty = ctrl1dragpointy;
},
onStopDrag: function (e) {
var ctrl1endx = e.clientX;
var ctrl1endy = e.clientY;
var x = ctrl1endx - ctr1tx - _that.flow._DEFALUTS_.dx + _that.bmargin + 10;
var y = ctrl1endy - ctr1ty - _that.flow._DEFALUTS_.dy + _that.bmargin + 10;
var dwidth = -(ctrl1endx - ctrl1oldstartx);
var dheight = -(ctrl1endy - ctrl1oldstarty);
var elementWidth = _that.element.attr("width");
var elementHeight = _that.element.attr("height");
//元素
_that.element.attr({
"x": x,
"y": y,
"width": elementWidth + dwidth,
"height": elementHeight + dheight
});
//属性
_that.x = x;
_that.y = y;
_that.w = elementWidth + dwidth;
_that.h = elementHeight + dheight;
_that.render(x, y, null);
}
})
}
},
render: function (x, y, bpzcenter) { //子流程的渲染
if (bpzcenter != null) {
if (bpzcenter[0] != null && bpzcenter[1] == null) {
//y轴吸附,x轴不吸附
if (bpzcenter[0].type == "start" || bpzcenter[0].type == "end" || bpzcenter[0].type == "gateway") {
x = bpzcenter[0].cx - this.w / 2;
} else if (bpzcenter[0].type == "userTask" || bpzcenter[0].type == "subProcess") {
x = bpzcenter[0].x + bpzcenter[0].w / 2 - this.w / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
} else if (bpzcenter[0] == null && bpzcenter[1] != null) {
//x轴吸附,y轴不吸附
if (bpzcenter[1].type == "start" || bpzcenter[1].type == "end" || bpzcenter[1].type == "gateway") {
y = bpzcenter[1].cy - this.h / 2;
} else if (bpzcenter[1].type == "userTask" || bpzcenter[1].type == "subProcess") {
y = bpzcenter[1].y + bpzcenter[1].h / 2 - this.h / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
} else if (bpzcenter[0] != null && bpzcenter[1] != null) {
//y轴吸附,x轴吸附
if (bpzcenter[0].type == "start" || bpzcenter[0].type == "end" || bpzcenter[0].type == "gateway") {
x = bpzcenter[0].cx - this.w / 2;
} else if (bpzcenter[0].type == "userTask" || bpzcenter[0].type == "subProcess") {
x = bpzcenter[0].x + bpzcenter[0].w / 2 - this.w / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
if (bpzcenter[1].type == "start" || bpzcenter[1].type == "end" || bpzcenter[1].type == "gateway") {
y = bpzcenter[1].cy - this.h / 2;
} else if (bpzcenter[1].type == "userTask" || bpzcenter[1].type == "subProcess") {
y = bpzcenter[1].y + bpzcenter[1].h / 2 - this.h / 2; //因为2个元素的大小不一定相同,先到中心点,再减去自身的一半
}
}
}
var oldx = this.x;
var oldy = this.y;
this.x = x;
this.y = y;
this.element.attr({"x": x, "y": y});
this.bbox = this.element.getBBox();
this.text.attr({"x": this.bbox.x + this.bbox.width / 2, "y": this.bbox.y + 14})
//扩大的外框
this.elementbox.attr({"x": this.bbox.x - this.bmargin, "y": this.bbox.y - this.bmargin});
//修改坐标(L,R,T,B)
this.coordinate[0] = this.bbox.x;
this.coordinate[1] = this.bbox.x + this.bbox.width;
this.coordinate[2] = this.bbox.y;
this.coordinate[3] = this.bbox.y + this.bbox.height;
//中心点坐标
this.centerpoint = [this.bbox.x + this.w / 2, this.bbox.y + this.h / 2];
//圆心
this.ccelement.attr({"cx": this.centerpoint[0], "cy": this.centerpoint[1]});
//根据中心点和宽度高度得到四个顶点 //定点开始顺时针
this.fourpoint = [{"x": this.x, "y": this.y}, {"x": this.x + this.w, "y": this.y}, {
"x": this.x + this.w,
"y": this.y + this.h
}, {"x": this.x, "y": this.y + this.h}];
//中心点向外扩展centerMargin=10,得到4条边,坐标(L,R,T,B)
this.centerLineCoordinate = [];
this.centerLineCoordinate.push(this.centerpoint[0] - this.centerMargin, this.centerpoint[0] + this.centerMargin, this.centerpoint[1] - this.centerMargin, this.centerpoint[1] + this.centerMargin);
//移动隐藏的中心竖线
this.centerLineY.attr("path", "M" + this.centerpoint[0] + ",0L" + this.centerpoint[0] + "," + this.flow._DEFALUTS_.height);
//移动隐藏的中心横线
this.centerLineX.attr("path", "M0," + this.centerpoint[1] + "L" + this.flow._DEFALUTS_.width + "," + this.centerpoint[1]);
//控制点
this.$elementctrl1.css({
"left": (this.bbox.x - this.bmargin - 10),
"top": (this.bbox.y - this.bmargin - 10 + this.flow._DEFALUTS_.dy)
});
this.$elementctrl4.css({
"left": (this.bbox.x - this.bmargin + this.bbox.width + 8),
"top": (this.bbox.y - this.bmargin + this.bbox.height + 8 + this.flow._DEFALUTS_.dy)
});
//所有出去的点,因为坐标变了,需要重绘
var _that = this;
$.each(this.lineout, function (index, lineElem) {
if (!lineElem.self) { //不是指向自身的点
lineElem.redrawStart(_that.bbox.cx, _that.bbox.cy);
} else {
//是指向自身的线,需要和节点一起变化,重绘
lineElem.renderMoveSelf();
}
});
//所有进入的点,因为坐标变了,需要重绘
$.each(this.linein, function (index, lineElem) {
//得到点
if (!lineElem.self) {
lineElem.redrawEnd(_that.bbox.cx, _that.bbox.cy);
} else {
//是指向自身的线,需要和节点一起变化,重绘
lineElem.renderMoveSelf();
}
});
return {"dx": x - oldx, "dy": y - oldy};
},
unSelect: function () {//非选中状态
//小菜单回归原位
$(".right").css({"left": -100, "top": -100});
if (this.selected == true) {
var wenbenid = $(".taskinput input").attr("wenbenid");
if (wenbenid) {
this.setText(wenbenid);
}
this.text.show();
}
//文本框回归原位
$(".taskinput").css({"left": -100, "top": -100});
//圆心
this.ccelement.hide();
//外框隐藏
this.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5}).hide();
//中心线隐藏
this.centerLineX.hide();
this.centerLineY.hide();
this.$elementctrl1.hide();
this.$elementctrl4.hide();
this.selected = false;
//完成情况的显示
if (this.completeState != 0) {
var name = "divshow_" + this.id;
$("#" + name).hide();
}
},
setText: function (wenbenid) {
//得到文本框的值,重新赋值给text //Raphaël\nkicks\nbutt!
var tvalue = $(".taskinput input").val();
var temp = tvalue;
if ($.trim(tvalue) != "" && wenbenid == this.id) {
var zishu = Math.floor(this.w / 14); //一行可显示的中文字数
var hangshu = parseInt(tvalue.length / zishu) + 1; //行数
var arr = [];
if (tvalue.length > zishu) {
for (var j = 0; j < hangshu; j++) {
for (var i = j * zishu; i < (j + 1) * zishu; i = i + 1) {
if (tvalue[i]) {
if (arr[j]) {
arr[j] += tvalue[i];
} else {
arr[j] = tvalue[i];
}
}
}
}
temp = arr.join('\n');
}
this.text.attr({"text": temp});
$(".taskinput input").val("");//清空
}
},
removeSubElement: function (elem) { //删除子元素
var _that = this;
$.each(this.subElement, function (index, ele) {
if (ele && ele.id == elem.id) {
_that.subElement.splice(index, 1);
}
});
},
removeElement: function () { //子流程删除本身
this.element.remove();
this.centerLineX.remove();
this.centerLineY.remove();
this.elementbox.remove();
this.$elementctrl1.remove();
this.$elementctrl4.remove();
this.text.remove();
this.ccelement.remove();
//小菜单回归原位
$(".right").css({"left": -100, "top": -100});
//文本框回归
$(".taskinput").css({"left": -100, "top": -100});
//移除相关的线
var tempoutlines = [];
$.each(this.lineout, function (index, line) {
tempoutlines.push(line);
});
$.each(tempoutlines, function (index, line) {
line && line.removeElement();
});
var tempinlines = [];
$.each(this.linein, function (index, line) {
tempinlines.push(line);
});
$.each(tempinlines, function (index, line) {
line && line.removeElement();
});
},
removeOutLine: function (line) {
var _that = this;
$.each(this.lineout, function (index, elem) {
if (elem && elem.id == line.id) {
_that.lineout.splice(index, 1);
}
})
},
removeInLine: function (line) {
var _that = this;
$.each(this.linein, function (index, elem) {
if (elem && elem.id == line.id) {
_that.linein.splice(index, 1);
}
})
},
getText: function () {
return this.text.attr("text");
}
})
var FlowDesigner = function (options) { //构造函数
if (!(this instanceof FlowDesigner)) {
console.log("FlowDesigner 是一个构造函数,应该用new关键字调用!");
return;
}
this.allnodes = {};//设计器上所有节点集合
this.alllines = {};//设计器上所有线条
this.addPoint = false;//是否正在线上加圆点的状态
this.subtractPoint = false; //是否减点状态
//默认配置参数
this._DEFALUTS_ = {
"id": "container",
"mode": "design", //设计模式design 查看模式view
"height": 500,
"width": 500,
"dx": 0, //画布距离屏幕的x偏移量
"dy": 46, //画布距离屏幕的y偏移量
"startmax": 0, //计数
"taskmax": 0 //任务编号计数
, "linemax": 0 //线段编号计数
, "smallcirclemax": 0 //线上的小圆点编号累加
, "endmax": 0 //end节点计数
, "gatewaymax": 0 //网关的计数
, "subprocessmax": 0 //子流程的计数
}
$.extend(this._DEFALUTS_, options || {});
this.paper = Raphael(this._DEFALUTS_.id, this._DEFALUTS_.width, this._DEFALUTS_.height);
$("#" + this._DEFALUTS_.id).css({
"width": this._DEFALUTS_.width,
"height": this._DEFALUTS_.height
});
var _that = this;
$("#" + this._DEFALUTS_.id).click(function (e) {
//IE8下点击画布是DIV
if ((e.target.nodeName == "DIV" || e.target.nodeName == "svg") && (_that.addPoint == false && _that.subtractPoint == false)) {
_that.allUnSelect();
} else if (_that.addPoint == true) {
//检查落点是否在线上
var x = e.clientX - _that._DEFALUTS_.dx;
var y = e.clientY - _that._DEFALUTS_.dy;
//console.log("x,y",x,y);
var x1, y1, x2, y2, tempy, tempx;
var arrLen = 0;
$.each(_that.alllines, function (i, line) {
arrLen = line.linepointsxy.length;
//console.log(line.linepointsxy);
$.each(line.linepointsxy, function (index, arr) {
if (index + 1 < arrLen) {
var x1 = arr[1];
var y1 = arr[2];
var x2 = line.linepointsxy[index + 1][1];
var y2 = line.linepointsxy[index + 1][2];
//console.log("察看",x1,y1,x2,y2);
if (floatToFix4(x1) != floatToFix4(x2)) { //x1!=x2
tempy = _that.getYLinePointFormula(x1, y1, x2, y2, x);
var max = Math.max(x1, x2);
var min = Math.min(x1, x2);
//console.log("tempy",tempy);
if (floatToFix4(tempy - 1.5) <= floatToFix4(y) && floatToFix4(y) <= floatToFix4(tempy + 1.5) && x > min && x < max) {
//表示找到线和点的位置
//加入到该线段上
_that.addLinePosition(line, index + 1, x, y);
// //关掉加点状态
// _that.addPoint=false;
return false;
}
} else {
tempx = _that.getXLinePointFormula(x1, y1, x2, y2, y);
//console.log("tempx",tempx);
var max = Math.max(y1, y2);
var min = Math.min(y1, y2);
if (floatToFix4(tempx - 1.5) <= floatToFix4(x) && floatToFix4(x) <= floatToFix4(tempx + 1.5) && y > min && y < max) {
//表示找到线和点的位置
//加入到该线段上
_that.addLinePosition(line, index + 1, x, y);
// //关掉加点状态
// _that.addPoint=false;
return false;
}
}
}
});
})
}
})
}
FlowDesigner.prototype.getScrollx = function () { //出现滚动条时的dx
return parseInt($("#" + this._DEFALUTS_.id).parent().scrollLeft());
}
FlowDesigner.prototype.getScrolly = function () { //出现滚动条时的dx
return parseInt($("#" + this._DEFALUTS_.id).parent().scrollTop());
}
FlowDesigner.prototype.zoomin = function () {
var options = this.getOptions();
var width = options.width * 1.1;
var height = options.height * 1.1;
options.width = width;
options.height = height;
this.paper.setSize(width, height);
$("#" + this._DEFALUTS_.id).css({"height": height, "width": width});
}
FlowDesigner.prototype.zoomout = function () {
var options = this.getOptions();
var width = options.width / 1.1;
var height = options.height / 1.1;
options.width = width;
options.height = height;
this.paper.setSize(width, height);
$("#" + this._DEFALUTS_.id).css({"height": height, "width": width});
}
FlowDesigner.prototype.getOptions = function () {
return this._DEFALUTS_;
}
/*start编号累加*/
FlowDesigner.prototype.createStartNodeNum = function () {
this._DEFALUTS_.startmax++;
return this._DEFALUTS_.startmax;
}
/*usertask编号累加*/
FlowDesigner.prototype.createTaskNum = function () {
this._DEFALUTS_.taskmax++;
return this._DEFALUTS_.taskmax;
}
/*线编号累加*/
FlowDesigner.prototype.createLineNum = function () {
this._DEFALUTS_.linemax++;
return this._DEFALUTS_.linemax;
}
/*线上的小圆点编号累加*/
FlowDesigner.prototype.createSmallCircleNodeNum = function () {
this._DEFALUTS_.smallcirclemax++;
return this._DEFALUTS_.smallcirclemax;
}
/*线上的end编号累加*/
FlowDesigner.prototype.createEndNodeNum = function () {
this._DEFALUTS_.endmax++;
return this._DEFALUTS_.endmax;
}
/*线上的gateway编号累加*/
FlowDesigner.prototype.createGatewayNum = function () {
this._DEFALUTS_.gatewaymax++;
return this._DEFALUTS_.gatewaymax;
}
/*线上的子流程编号累加*/
FlowDesigner.prototype.createSubprocessNum = function () {
this._DEFALUTS_.subprocessmax++;
return this._DEFALUTS_.subprocessmax;
}
/*清除画布所有元素*/
FlowDesigner.prototype.clear = function () {
var _that = this;
$.messager.confirm('再次确认', '您确定要清除画布中所有元素?', function (r) {
if (r) {
$.each(_that.allnodes, function (name, elem) {
elem.removeElement();
});
$.each(_that.alllines, function (name, elem) {
elem.removeElement();
})
_that.paper.clear(); //全部元素移除
_that.allnodes = {};
_that.alllines = {};
}
});
}
/*清除画布所有元素,不需要确认*/
FlowDesigner.prototype.clear2 = function () {
var _that = this;
$.each(_that.allnodes, function (name, elem) {
elem.removeElement();
});
$.each(_that.alllines, function (name, elem) {
elem.removeElement();
})
_that.paper.clear(); //全部元素移除
_that.allnodes = {};
_that.alllines = {};
}
/*去掉所有元素的选择状态*/
FlowDesigner.prototype.allUnSelect = function () {
//循环所有节点,调用自身的unselect方法
$.each(this.allnodes, function (name, elem) {
elem.unSelect();
});
//循环所有线,调用自身的unselect方法
$.each(this.alllines, function (name, elem) {
elem.unSelect();
});
}
/*找出所有指定类型的节点*/
FlowDesigner.prototype.findAllNodeByType = function (type) {
var findAll = [];
$.each(this.allnodes, function (name, elem) {
if (elem.type == type) {
findAll.push({"id": elem.id, "text": elem.getText()});
}
});
return findAll;
}
/*两个方块间的碰撞检测moveid是正在移动元素的类实例的id ,后面的4个参数是移动元素的四个坐标,返回一个被撞元素 */
FlowDesigner.prototype.collision = function (move, L1, R1, T1, B1) {
var bpz = null; //被碰撞元素
if (move.type != "subProcess") {
$.each(this.allnodes, function (id, elem) {
if (id != move.id) {
if (elem.type != "subProcess") {
if (pz(L1, R1, T1, B1, elem.coordinate[0], elem.coordinate[1], elem.coordinate[2], elem.coordinate[3])) {
bpz = elem;
elem.elementbox.show().attr({"stroke": "#ff0000", "stroke-width": 2});
//elem.$moveDiv.css({"borderColor":"#ff0000","zIndex":0});
return false;
} else {
elem.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5});
//elem.$moveDiv.css({"borderColor":"#000000","zIndex":-1});
}
} else {
if (pz(L1, R1, T1, B1, elem.coordinate[0], elem.coordinate[1], elem.coordinate[2], elem.coordinate[3]) && (move.parentElem == null || elem.id != move.parentElem.id)) {
bpz = elem;
//绿色
elem.elementbox.show().attr({"stroke": "#84ff20", "stroke-width": 2});
//elem.$moveDiv.css({"borderColor":"#ff0000","zIndex":0});
return false;
} else {
elem.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5});
//elem.$moveDiv.css({"borderColor":"#000000","zIndex":-1});
}
}
}
});
} else {//移动元素是子流程时
$.each(this.allnodes, function (id, elem) {
if (id != move.id) {
if (elem.parentElem == null) {//只有外部元素才匹配
if (pz(L1, R1, T1, B1, elem.coordinate[0], elem.coordinate[1], elem.coordinate[2], elem.coordinate[3])) {
bpz = elem;
elem.elementbox.show().attr({"stroke": "#ff0000", "stroke-width": 2});
//elem.$moveDiv.css({"borderColor":"#ff0000","zIndex":0});
return false;
} else {
elem.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5});
//elem.$moveDiv.css({"borderColor":"#000000","zIndex":-1});
}
}
}
});
}
return bpz;
}
FlowDesigner.prototype.collisionSubProcess = function (L1, R1, T1, B1) {
var bpz = null; //被碰撞元素
$.each(this.allnodes, function (id, elem) {
if (elem.type == "subProcess") {
if (pz(L1, R1, T1, B1, elem.coordinate[0], elem.coordinate[1], elem.coordinate[2], elem.coordinate[3])) {
bpz = elem;
return false;
}
}
});
return bpz;
}
//判断当前点是否在区域内
FlowDesigner.prototype.lineFootholdDraging = function (startNode, sourcex, sourcey) {
$.each(this.allnodes, function (id, elem) {
if (elem.type == "userTask" || elem.type == "end" || elem.type == "gateway" || (elem.type == "subProcess" && (startNode.parentElem == null || startNode.parentElem.id != elem.id))) {
if (elem.coordinate[0] <= sourcex && sourcex <= elem.coordinate[1] && elem.coordinate[2] <= sourcey && sourcey < elem.coordinate[3]) {
//在区域内
elem.elementbox.attr({"stroke": "#84ff20", "stroke-width": 4}).show();
} else {
elem.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5}).hide();
}
}
});
}
//判断当前的点是否落在区域块中,并返回该对象
FlowDesigner.prototype.lineFoothold = function (startNode, sourcex, sourcey) {
var target = null;
$.each(this.allnodes, function (id, elem) {
if (elem.type == "userTask" || elem.type == "end" || elem.type == "gateway" || (elem.type == "subProcess" && (startNode.parentElem == null || startNode.parentElem.id != elem.id))) {
if (elem.coordinate[0] <= sourcex && sourcex <= elem.coordinate[1] && elem.coordinate[2] <= sourcey && sourcey < elem.coordinate[3]) {
//在区域内
target = elem;
return false;
}
}
});
return target;
}
/*元素碰撞:前4个是移动元素坐标,后面4个被撞元素坐标 */
function pz(L1, R1, T1, B1, L2, R2, T2, B2) {
if (R1 < L2 || L1 > R2 || B1 < T2 || T1 > B2) {//碰不着
return false;
} else {
return true;
}
}
/*其他元素的中心线显示:两个方块间的碰撞检测move是正在移动元素的类实例,后面的4个参数是移动元素的四个坐标 */
FlowDesigner.prototype.collisionCenterLine = function (move, L1, R1, T1, B1) {
var bpzcentery = []; //被碰撞中心元素集合,选出最近的元素,做吸附对齐,y方向。
var bpzcenterx = []; //被碰撞中心元素集合,选出最近的元素,做吸附对齐,x方向。
var bpzcenter = [null, null]; //有2个元素,第一个元素是y方向上的对齐元素,第二个元素是x方向上的对齐元素。
$.each(this.allnodes, function (id, elem) {
if (move.parentElem != null) { //有父元素的时候
if (elem.type == "subProcess" && elem.id == move.parentElem.id) { //基本元素move,在自家子流程之内移动,不匹配自家父元素
return true; //跳出本次循环
} else {
if (id != move.id && elem.parentElem != null && elem.parentElem.id == move.parentElem.id) { //2.基本元素move,自家子流程内,只有和自家的其它元素匹配
switch (pz2(L1, R1, T1, B1, elem.coordinate[0], elem.coordinate[1], elem.coordinate[2], elem.coordinate[3])) {
case "竖线":
elem.centerLineY.show().toBack();
bpzcentery.push(elem);
break;
case "横线":
elem.centerLineX.show().toBack();
bpzcenterx.push(elem);
break;
case "":
elem.centerLineX.hide();
elem.centerLineY.hide();
break;
}
}
}
} else {//没有父元素的时候,也不匹配子流程内部的元素
if (id != move.id && elem.parentElem == null) {
switch (pz2(L1, R1, T1, B1, elem.centerLineCoordinate[0], elem.centerLineCoordinate[1], elem.centerLineCoordinate[2], elem.centerLineCoordinate[3])) {
case "竖线":
elem.centerLineY.show().toBack();
bpzcentery.push(elem);
break;
case "横线":
elem.centerLineX.show().toBack();
bpzcenterx.push(elem);
break;
case "":
elem.centerLineX.hide();
elem.centerLineY.hide();
break;
}
}
}
});
//得到最贴近的2个元素,第一个是y方向,第二个是x方向
if (bpzcentery.length >= 2) {
var centerx = (L1 + R1) / 2;
var minIndex = 0;
$.each(bpzcentery, function (index, elem) {
if (index > 0 && Math.abs((elem.centerLineCoordinate[0] + elem.centerLineCoordinate[1]) / 2 - centerx) < Math.abs((bpzcentery[minIndex].centerLineCoordinate[0] + bpzcentery[minIndex].centerLineCoordinate[0]) / 2 - centerx)) {
minIndex = index;
}
})
bpzcenter[0] = bpzcentery[minIndex];
} else if (bpzcentery.length == 1) {
bpzcenter[0] = bpzcentery[0];
} else if (bpzcentery.length == 0) {
bpzcenter[0] = null;
}
//第二个是x方向
if (bpzcenterx.length >= 2) {
var centery = (T1 + B1) / 2;
var minIndex = 0;
$.each(bpzcenterx, function (index, elem) {
if (index > 0 && Math.abs((elem.centerLineCoordinate[2] + elem.centerLineCoordinate[3]) / 2 - centery) < Math.abs((bpzcenterx[minIndex].centerLineCoordinate[2] + bpzcenterx[minIndex].centerLineCoordinate[3]) / 2 - centery)) {
minIndex = index;
}
})
bpzcenter[1] = bpzcenterx[minIndex];
} else if (bpzcenterx.length == 1) {
bpzcenter[1] = bpzcenterx[0];
} else if (bpzcenterx.length == 0) {
bpzcenter[1] = null;
}
return bpzcenter;
}
/*子流程的中心线碰撞move是子流程 其他元素的中心线显示:两个方块间的碰撞检测move是正在移动元素的类实例的 ,后面的4个参数是移动元素的四个坐标 */
FlowDesigner.prototype.subProcessCollisionCenterLine = function (move, L1, R1, T1, B1) {
var bpzcentery = []; //被碰撞中心元素集合,选出最近的元素,做吸附对齐,y方向。
var bpzcenterx = []; //被碰撞中心元素集合,选出最近的元素,做吸附对齐,x方向。
var bpzcenter = [null, null]; //有2个元素,第一个元素是y方向上的对齐元素,第二个元素是x方向上的对齐元素。
$.each(this.allnodes, function (id, elem) {
if (id != move.id && elem.parentElem == null) { //只和外部元素碰撞
switch (pz2(L1, R1, T1, B1, elem.centerLineCoordinate[0], elem.centerLineCoordinate[1], elem.centerLineCoordinate[2], elem.centerLineCoordinate[3])) {
case "竖线":
elem.centerLineY.show().toBack();
bpzcentery.push(elem);
break;
case "横线":
elem.centerLineX.show().toBack();
bpzcenterx.push(elem);
break;
case "":
elem.centerLineX.hide();
elem.centerLineY.hide();
break;
}
}
});
//得到最贴近的2个元素,第一个是y方向,第二个是x方向
if (bpzcentery.length >= 2) {
var centerx = (L1 + R1) / 2;
var minIndex = 0;
$.each(bpzcentery, function (index, elem) {
if (index > 0 && Math.abs((elem.centerLineCoordinate[0] + elem.centerLineCoordinate[1]) / 2 - centerx) < Math.abs((bpzcentery[minIndex].centerLineCoordinate[0] + bpzcentery[minIndex].centerLineCoordinate[0]) / 2 - centerx)) {
minIndex = index;
}
})
bpzcenter[0] = bpzcentery[minIndex];
} else if (bpzcentery.length == 1) {
bpzcenter[0] = bpzcentery[0];
} else if (bpzcentery.length == 0) {
bpzcenter[0] = null;
}
//第二个是x方向
if (bpzcenterx.length >= 2) {
var centery = (T1 + B1) / 2;
var minIndex = 0;
$.each(bpzcenterx, function (index, elem) {
if (index > 0 && Math.abs((elem.centerLineCoordinate[2] + elem.centerLineCoordinate[3]) / 2 - centery) < Math.abs((bpzcenterx[minIndex].centerLineCoordinate[2] + bpzcenterx[minIndex].centerLineCoordinate[3]) / 2 - centery)) {
minIndex = index;
}
})
bpzcenter[1] = bpzcenterx[minIndex];
} else if (bpzcenterx.length == 1) {
bpzcenter[1] = bpzcenterx[0];
} else if (bpzcenterx.length == 0) {
bpzcenter[1] = null;
}
return bpzcenter;
}
//小圆点的碰撞
FlowDesigner.prototype.collisionSelfCenterLine = function (small, L1, R1, T1, B1) {
var bpzcenter = [null, null];
var start = small.belongLine.nodestart;
var L2 = start.centerLineCoordinate[0];
var R2 = start.centerLineCoordinate[1];
var T2 = start.centerLineCoordinate[2];
var B2 = start.centerLineCoordinate[3];
var end = small.belongLine.nodeend;
var L3 = end.centerLineCoordinate[0];
var R3 = end.centerLineCoordinate[1];
var T3 = end.centerLineCoordinate[2];
var B3 = end.centerLineCoordinate[3];
if (L2 < L1 && R1 < R2) {
bpzcenter[0] = start.centerpoint[0];
}
if (T3 < T1 && B1 < B3) {
bpzcenter[1] = end.centerpoint[1];
}
if (L3 < L1 && R1 < R3) {
bpzcenter[0] = end.centerpoint[0];
}
if (T2 < T1 && B1 < B2) {
bpzcenter[1] = start.centerpoint[1];
}
return bpzcenter;
}
/*元素中心线碰撞:前4个是移动元素坐标,后面4个被撞元素坐标*/
function pz2(L1, R1, T1, B1, L2, R2, T2, B2) {
var ret = "";
if ((L1 < L2 && R1 > L2) || (L1 < R2 && R1 > R2) || (L1 < L2 && R2 < R1)) {
ret = "竖线";
} else if ((T1 < T2 && B1 > T2) || (T1 < B2 && B1 > B2) || (T1 < T2 && B2 < B1)) {
//console.log(L1, R1, T1, B1,"," ,L2, R2, T2, B2);
ret = "横线";
}
return ret;
}
/*两个点之间形成公式,输入x,得到y轴坐标 */
FlowDesigner.prototype.getYLinePointFormula = function (x1, y1, x2, y2, x) {
if (floatToFix4(x1) != floatToFix4(x2)) {
var y = y2 + (x - x2) * (y1 - y2) / (x1 - x2);
} else {
y = y2;
}
return y;
}
/*两个点之间形成公式,输入y,得到x轴坐标 */
FlowDesigner.prototype.getXLinePointFormula = function (x1, y1, x2, y2, y) {
if (floatToFix4(y1) != floatToFix4(y2)) {
var x = x2 + (x1 - x2) * (y - y2) / (y1 - y2);
} else {
var x = x2;
}
return x;
}
//通过对象id找到指定元素类实例
FlowDesigner.prototype.FindElementById = function (id) {
var find = null;
$.each(this.allnodes, function (name, elem) {
if (name == id) {
find = elem;
}
});
if (find == null) { //如果不是元素,则查找线段
$.each(this.alllines, function (name, elem) {
if (name == id) {
find = elem;
}
});
}
return find;
}
//删除元素
FlowDesigner.prototype.removeElement = function (obj) {
var _that = this;
$.messager.confirm('再次确认', '您确定要删除该元素吗?', function (r) {
if (r) {
var elemid = $(obj).closest(".right").attr("tempid");
var elem = _that.FindElementById(elemid);
elem && elem.removeElement();//画布上的元素清除
if (elem && elem.type != "line") {
delete _that.allnodes[elemid]; //删除元素
}
if (elem && elem.type == "line") {
delete _that.alllines[elemid]; //删除线
}
}
});
}
//得到目标的箭头坐标 ,只适合于目标是矩形
FlowDesigner.prototype.getArrowPosXY = function (startNode, dropElem) {
//线的开始坐标,即startNode的中心点,但需要获得目标节点边框上的点,作为线的(箭头)的最终点
//1.判断开始节点和目标节点的位置关系。2.得到两个节点中心点间的直线公式,算出箭头中心点。3.通过startNode的中心点和箭头中心点,创建线段对象。
var pos = -1;
if (startNode.coordinate[0] >= dropElem.coordinate[1] && startNode.coordinate[3] <= dropElem.coordinate[2]) { //Start元素在目标元素的右上面
pos = 21;
} else if (startNode.coordinate[1] <= dropElem.coordinate[0] && startNode.coordinate[3] <= dropElem.coordinate[2]) { //Start元素在目标元素的左上面
pos = 20;
} else if (startNode.coordinate[1] <= dropElem.coordinate[0] && startNode.coordinate[2] >= dropElem.coordinate[3]) { //Start元素在目标元素的左下面
pos = 30;
} else if (startNode.coordinate[0] >= dropElem.coordinate[1] && startNode.coordinate[2] >= dropElem.coordinate[3]) { //Start元素在目标元素的右下面
pos = 13;
} else if (startNode.coordinate[3] <= dropElem.coordinate[2]) {
pos = 2; //Start元素在目标元素的上面
} else if (startNode.coordinate[1] < dropElem.coordinate[0]) {
pos = 0;//Start元素在目标元素的左边
} else if (startNode.coordinate[2] >= dropElem.coordinate[3]) {
pos = 3; //Start元素在目标元素的下面
} else if (startNode.coordinate[0] >= dropElem.coordinate[1]) {
pos = 1; //Start元素在目标元素的右面
}
var x = 0;
var y = 0;
var x1 = 0, y1 = 0;
if (pos != -1) {
switch (pos) {
case 0: //Start元素在目标元素的左边
x = dropElem.coordinate[0];
y = flowDesigner.getYLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], x);
break;
case 1: //Start元素在目标元素的右面
x = dropElem.coordinate[1];
y = flowDesigner.getYLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], x);
break;
case 2://Start元素在目标元素的上面
y = dropElem.coordinate[2];
x = flowDesigner.getXLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], y);
break;
case 3://Start元素在目标元素的下面
y = dropElem.coordinate[3];
x = flowDesigner.getXLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], y);
break;
case 21: //Start元素在目标元素的右上
y1 = dropElem.coordinate[2]; //2
x1 = flowDesigner.getXLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], y1);
if (dropElem.x < x1 && x1 < (dropElem.x + dropElem.w)) {
x = x1;
y = y1;
} else {
x1 = dropElem.coordinate[1];
y1 = flowDesigner.getYLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], x1);
x = x1;
y = y1;
}
break;
case 20: //2和0 ,Start元素在目标元素的左上
y1 = dropElem.coordinate[2]; //2
x1 = flowDesigner.getXLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], y1);
if (dropElem.x < x1 && x1 < (dropElem.x + dropElem.w)) {
x = x1;
y = y1;
} else {
x1 = dropElem.coordinate[0]; //0
y1 = flowDesigner.getYLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], x1);
x = x1;
y = y1;
}
break;
case 13: //1和3,Start元素在目标元素的右下面
y1 = dropElem.coordinate[3]; //3
x1 = flowDesigner.getXLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], y1);
if (dropElem.x < x1 && x1 < dropElem.x + dropElem.w) {
x = x1;
y = y1;
} else {
x1 = dropElem.coordinate[1]; //1的判断 Start元素在目标元素的右面
y1 = flowDesigner.getYLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], x1);
x = x1;
y = y1;
}
break;
case 30: //0和3,Start元素在目标元素的左下
y1 = dropElem.coordinate[3]; //3
x1 = flowDesigner.getXLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], y1);
if (dropElem.x < x1 && x1 < (dropElem.x + dropElem.w)) {
x = x1;
y = y1;
} else {
x1 = dropElem.coordinate[0]; //0
y1 = flowDesigner.getYLinePointFormula(startNode.centerpoint[0], startNode.centerpoint[1], dropElem.centerpoint[0], dropElem.centerpoint[1], x1);
x = x1;
y = y1;
}
break;
}
}
return {"x": x, "y": y}
}
//得到目标的箭头坐标,目标是end节点
FlowDesigner.prototype.getCircleArrowPosXY = function (startNode, dropElem) {
var linestr = "M" + startNode.centerpoint
[0] + "," + startNode.centerpoint[1] + "L" + dropElem.centerpoint[0] + "," + dropElem.centerpoint[1];
var linehide = this.paper.path(linestr).hide();
var linelength = linehide.getTotalLength();
var point = linehide.getPointAtLength(linelength - dropElem.r);
linehide.remove();
return {"x": point.x, "y": point.y}
}
//得到线的出发点
FlowDesigner.prototype.getStartPosXY = function (startNode, dropElem) {
var retPoint = null;
switch (startNode.type) {
case "smallcircle":
case "start":
retPoint = this.getCircleStartPosXY(startNode, dropElem);
break;
case "gateway":
case "subProcess":
case "userTask":
retPoint = this.getQuadrangleStartPosXY(startNode, dropElem);
break;
}
return retPoint;
}
//得到线的出发点,开始节点是圆
FlowDesigner.prototype.getCircleStartPosXY = function (startNode, dropElem) {
var linestr = "M" + startNode.centerpoint
[0] + "," + startNode.centerpoint[1] + "L" + dropElem.centerpoint[0] + "," + dropElem.centerpoint[1];
var linehide = this.paper.path(linestr).hide();
var point = linehide.getPointAtLength(startNode.r);
linehide.remove();
return {"x": point.x, "y": point.y}
}
//得到线的出发点,开始节点是四边形
FlowDesigner.prototype.getQuadrangleStartPosXY = function (startNode, dropElem) {
var point = null;
var a = {"x": startNode.centerpoint[0], "y": startNode.centerpoint[1]};
var b = {"x": dropElem.centerpoint[0], "y": dropElem.centerpoint[1]};
//console.log("startNode",startNode);
//console.log("dropElem",dropElem);
$.each(startNode.fourpoint, function (index, elem) {
//循环4个点,依次形成4条线cd,分别和ab,求交点,求到一个交点就结束
//console.log(a,b,dropElem.fourpoint[index%4],dropElem.fourpoint[(index+1)%4]);
point = segmentsIntr(a, b, startNode.fourpoint[index % 4], startNode.fourpoint[(index + 1) % 4]);
if (point != false) {
return false;
}
});
return point;
}
//得到目标的箭头坐标,目标是Gateway节点
FlowDesigner.prototype.getGatewayArrowPosXY = function (startNode, dropElem) {
var point = null;
var a = {"x": startNode.centerpoint[0], "y": startNode.centerpoint[1]};
var b = {"x": dropElem.centerpoint[0], "y": dropElem.centerpoint[1]};
//console.log("startNode",startNode);
//console.log("dropElem",dropElem);
$.each(dropElem.fourpoint, function (index, elem) {
//循环4个点,依次形成4条线cd,分别和ab,求交点,求到一个交点就结束
//console.log(a,b,dropElem.fourpoint[index%4],dropElem.fourpoint[(index+1)%4]);
point = segmentsIntr(a, b, dropElem.fourpoint[index % 4], dropElem.fourpoint[(index + 1) % 4]);
if (point != false) {
return false;
}
});
return point;
}
//得到两线的交点(ab是一条线,cd是另一条线)
function segmentsIntr(a, b, c, d) {
/** 1 解线性方程组, 求线段交点. **/
// 如果分母为0 则平行或共线, 不相交
var denominator = (b.y - a.y) * (d.x - c.x) - (a.x - b.x) * (c.y - d.y);
if (denominator == 0) {
return false;
}
// 线段所在直线的交点坐标 (x , y)
var x = ((b.x - a.x) * (d.x - c.x) * (c.y - a.y)
+ (b.y - a.y) * (d.x - c.x) * a.x
- (d.y - c.y) * (b.x - a.x) * c.x) / denominator;
var y = -((b.y - a.y) * (d.y - c.y) * (c.x - a.x)
+ (b.x - a.x) * (d.y - c.y) * a.y
- (d.x - c.x) * (b.y - a.y) * c.y) / denominator;
/** 2 判断交点是否在两条线段上 **/
if (
// 交点在线段1上
(x - a.x) * (x - b.x) <= 0 && (y - a.y) * (y - b.y) <= 0
// 且交点也在线段2上
&& (x - c.x) * (x - d.x) <= 0 && (y - c.y) * (y - d.y) <= 0
) {
// 返回交点p
return {
x: x,
y: y
}
}
//否则不相交
return false;
}
//得到线上的点,并且判断自身是否在直线上,如果在者不变,如果不在就按两点的距离存在的点数来设置。startNode:开始节点,endNode:结束节点,selfNode:自身本来的节点,length ,节点数+1,线被节点分成几段,index:第几个
FlowDesigner.prototype.getNewSmallCirclePosXY = function (startNode, endNode, selfNode, length, index) {
//先判断是否在直线上
if (floatToFix4(startNode.x) == floatToFix4(selfNode[1]) || floatToFix4(startNode.y) == floatToFix4(selfNode[2])) {
return {"x": selfNode[1], "y": selfNode[2]};
}
//不在直线上
var linestr = "M" + startNode.x + "," + startNode.y + "L" + endNode.x + "," + endNode.y;
var linehide = this.paper.path(linestr).hide();
var linelength = linehide.getTotalLength();
var point = linehide.getPointAtLength(linelength * index / length);
linehide.remove();
return {"x": point.x, "y": point.y};
}
//添加元素
FlowDesigner.prototype.addElement = function (options) {
switch (options.type) {
case "start":
var startNode = new Start(this, options);
startNode.init();
this.allnodes[startNode.id] = startNode;
return startNode;
break;
case "userTask":
var userTaskNode = new UserTask(this, options);
userTaskNode.init();
this.allnodes[userTaskNode.id] = userTaskNode;
return userTaskNode;
break;
case "line":
var line = new Line(this, options);
line.init();
this.alllines[line.id] = line;
return line;
break;
case "end":
var endNode = new End(this, options);
endNode.init();
this.allnodes[endNode.id] = endNode;
return endNode;
break;
case "gateway":
var gatewayNode = new Gateway(this, options);
gatewayNode.init();
this.allnodes[gatewayNode.id] = gatewayNode;
return gatewayNode;
break;
case "subProcess":
var subProcessNode = new SubProcess(this, options);
subProcessNode.init();
this.allnodes[subProcessNode.id] = subProcessNode;
return subProcessNode;
break;
}
}
//设置线的加点状态
FlowDesigner.prototype.setAddPointStatus = function () {
this.addPoint = !this.addPoint;
if (this.addPoint) {
this.allUnSelect();
}
return this.addPoint;
}
FlowDesigner.prototype.setSubtractPointStatus = function () {
this.subtractPoint = !this.subtractPoint;
if (this.subtractPoint) {
this.allUnSelect();
}
return this.subtractPoint;
}
//加入线上的小圆点 line表示所加入的线,在index位置上插入点(pointx,pointy)
FlowDesigner.prototype.addLinePosition = function (line, index, pointx, pointy) {
line.linepointsxy.splice(index, 0, ["L", pointx, pointy]);
line.linestr = Raphael.parsePathString(line.linepointsxy);
//重绘小圆点
line.redrawSmallCircle(true);
}
return FlowDesigner;
});