+(function (global, $, Raphael, factory) {
|
typeof exports == "object" && typeof module != "undefined" ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.FlowDesigner = factory());
|
|
})(this, jQuery, Raphael, function () {
|
|
function Start(flow, options) {
|
this.flow = flow; //FlowDesigner类
|
this.paper = flow.paper; //画布
|
this.options = options;
|
this.type = "start";
|
this.selected = false;
|
this.id = options.id ? options.id : "";
|
this.isLoad = options.isLoad ? true : false; //是否是加载的元素
|
|
this.parentElem = null; //所属父级
|
this.parentElemStr = options.parentElem; //加载时所属父级的名称
|
//this.stopmatching=false; //停止匹配线,只进入的子流程才为true,其它时候是false
|
this.element = null; //start圆
|
|
this.bmargin = 4; //外框和元素的边距
|
this.elementbox = null; //start圆的外框,加厚边距
|
this.bbox = null; //圆的真实外框
|
//this.$moveDiv=null; //外框拖动虚框
|
this.coordinate = []; //圆元素的上下左右四条边坐标
|
this.centerLineCoordinate = []; //圆元素的上下左右四条边坐标,为显示中心线,小一点
|
this.centerMargin = 10; //向中心点向外4个方向扩展的距离
|
|
//元素
|
this.cx = options.cx;
|
this.cy = options.cy;
|
this.centerpoint = [this.cx, this.cy];
|
this.r = options.r;
|
this.ccelement = null; //圆心
|
this.centerLineY = null;
|
this.centerLineX = null;
|
this.lineout = []; //所有的有关出去的线
|
this.text = null; //文本
|
this.content = {}; //start数据
|
this.completeState = options.completeState || 0; //0 代表否 1代表已完 2代表正当 3代表还未开始
|
|
}
|
|
Start.prototype = $.extend(Start.prototype, {
|
init: function () {
|
var number = this.flow.createStartNodeNum();
|
var tempName = (new Date()).getTime();
|
if (!this.isLoad) {
|
this.id = "start_" + tempName;
|
}
|
|
//圆
|
switch (this.completeState) {
|
|
case 1://蓝色
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#e0e9fe",
|
"cursor": "pointer",
|
"stroke": "#2632aa"
|
});
|
break;
|
case 2://绿色
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#ebf8eb",
|
"cursor": "pointer",
|
"stroke": "#017501"
|
});
|
break;
|
case 3://灰色
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#dadada",
|
"cursor": "pointer",
|
"stroke": "#acacac"
|
});
|
break;
|
default:
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#ffffff",
|
"cursor": "pointer"
|
});
|
break;
|
}
|
|
|
this.centerpoint = [this.cx, this.cy];
|
this.ccelement = this.paper.circle(this.centerpoint[0], this.centerpoint[1], 2).attr({
|
"fill": "#ff0000",
|
"stroke": "ff0000"
|
}).hide(); //圆心
|
|
//真外框
|
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).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);
|
|
//中心点向外扩展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, "开始").attr({"font-size": "12px"}).toBack();
|
} else {
|
this.text = this.paper.text(this.centerpoint[0], this.centerpoint[1] + this.r + 12, this.options.text).attr({"font-size": "12px"}).toBack();
|
|
}
|
|
//隐藏的中心竖线
|
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();
|
|
//添加父元素
|
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);
|
//显示文本框,15是宽度为60,取中间
|
$(".taskinput").css({
|
"left": _that.cx - _that.r - 15 - _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();
|
}
|
});
|
|
//圆的外层框拖动
|
var weiyiX = 0;
|
var weiyiY = 0;
|
var dropStatus = false;
|
var startX = 0;
|
var startY = 0;
|
var bpz = null;
|
var bpzcenter = null;
|
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
|
//console.log(e.clientY , _that.flow._DEFALUTS_.dy, _that.bbox.y , _that.bmargin);
|
startX = _that.bbox.x - _that.bmargin;
|
startY = _that.bbox.y - _that.bmargin;
|
|
}, function (e) {//move结束
|
|
if (dropStatus == true) {
|
var elemnetboxbbox = this.getBBox();
|
var cx = elemnetboxbbox.cx;
|
var cy = elemnetboxbbox.cy;
|
|
//判断是否进入子流程
|
if (bpz && bpz.type == "subProcess") {
|
//说明进入在子流程中
|
if (_that.parentElem == null || _that.parentElem.id != bpz.id) {
|
//表示新的入到一个子流程中
|
if (_that.lineout.length > 0) {
|
//如果含有线段,则必须提示,因为进入新的空间,旧的空间中的线段需要删除
|
$.messager.confirm('再次确认', '该开始节点进入子流程会删除原来的线段,还要继续进入吗?', function (r) {
|
if (!r) {
|
_that.elementbox.attr({"x": startX, "y": startY}); //不能落下的地方就返回
|
} else {
|
_that.render(cx, cy, bpzcenter); //重新渲染start的圆
|
}
|
})
|
} else {
|
//没有线段
|
_that.render(cx, cy, bpzcenter); //重新渲染start的圆
|
}
|
}
|
} else if (bpz == null) {
|
if (_that.parentElem != null) {
|
//原来在小空间中
|
if (_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(cx, cy, bpzcenter); //重新渲染start的圆
|
}
|
})
|
} else {
|
//没有出小空间
|
_that.render(cx, cy, bpzcenter); //重新渲染start的圆
|
}
|
} else {
|
//没有线段
|
|
_that.render(cx, cy, bpzcenter); //重新渲染start的圆
|
}
|
} else {
|
//原来在大空间中
|
_that.render(cx, cy, bpzcenter); //重新渲染start的圆
|
}
|
}
|
|
|
} else {
|
this.attr({"x": startX, "y": startY}); //不能落下的地方就返回
|
}
|
dropStatus = false;
|
|
return false;
|
|
});
|
} else if (this.completeState == 1 || this.completeState == 2) {
|
|
this.element.mouseover(function (e) {
|
$("[id*=divshow_]").hide();
|
var wheight = e.view.innerHeight; //屏幕大小
|
var wheight2 = Math.floor(wheight / 2);//屏幕大小的一半
|
var name = "divshow_" + _that.id;
|
if ($("#" + name).length == 0) {
|
//创建
|
if (e.pageY <= wheight2) {
|
var str = "<div id='" + name + "' class='show' style='left:" + (e.pageX + 0) + "px; top:" + (e.pageY + 0) + "px;'><p class='title'>" + _that.getText() + "</p><div class='con' style='max-height:" + wheight2 + "px'>";
|
} else {
|
var str = "<div id='" + name + "' class='show' style='left:" + (e.pageX + 0) + "px; bottom:" + (wheight - e.pageY + 0) + "px;'><p class='title'>" + _that.getText() + "</p><div class='con' style='max-height:" + wheight2 + "px'>";
|
}
|
|
if (_that.completeState == 1) {
|
|
str += "<h4 class='yi'>已办理</h4>";
|
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
|
|
$.each(_that.content.activityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>办理时间</strong><span>" + el.time + "</span></p><p><strong>办理意见</strong><span>" + el.advice + "</span></p>";
|
})
|
}
|
} else if (_that.completeState == 2) {
|
|
if (_that.content.waitActivityUsers && _that.content.waitActivityUsers.length > 0) {
|
str += "<h4 class='zhengzai'>正在办理</h4>";
|
$.each(_that.content.waitActivityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>开始时间</strong><span>" + el.time + "</span></p>";
|
})
|
}
|
|
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
|
str += "<h4 class='yi'>已办理</h4>";
|
$.each(_that.content.activityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>办理时间</strong><span>" + el.time + "</span></p><p><strong>办理意见</strong><span>" + el.advice + "</span></p>";
|
})
|
}
|
|
|
}
|
|
str += "</div></div>";
|
|
$("#" + _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) { //start元素重新渲染
|
|
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;
|
}
|
}
|
|
}
|
|
this.cx = cx;
|
this.cy = cy;
|
this.element.attr({"cx": cx, "cy": cy});
|
this.bbox = this.element.getBBox();
|
this.centerpoint = [cx, cy];
|
//圆心
|
this.ccelement.attr({"cx": this.centerpoint[0], "cy": this.centerpoint[1]});
|
//扩大的外框
|
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;
|
|
//中心点向外扩展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.lineout, function (index, lineElem) {
|
|
lineElem.redrawStart(_that.cx, _that.cy);
|
});
|
|
//父元素处理
|
var parent = this.comeInSubProcess();
|
if (parent != null) {
|
//目前进入到子流程中
|
parent.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5});
|
}
|
//无论是否有父元素,都需要进入这个方法
|
this.addParent(parent);
|
},
|
unSelect: function () {//非选中状态
|
//小菜单回归原位
|
$(".right").css({"left": -100, "top": -100});
|
//外框隐藏
|
this.elementbox.attr({"stroke": "#000000", "stroke-width": 0.5}).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;
|
this.ccelement.hide();
|
//完成情况的显示
|
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) {
|
this.text.attr({"text": temp});
|
$(".taskinput input").val("");//清空
|
}
|
},
|
removeElement: function () {//删除元素
|
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 templines = [];
|
$.each(this.lineout, function (index, line) {
|
templines.push(line);
|
});
|
$.each(templines, 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);
|
}
|
|
})
|
},
|
|
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();
|
}
|
}
|
|
},
|
|
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]; //删除线元素
|
}
|
});
|
}
|
|
});
|
|
//任务节点
|
function UserTask(flow, options) {
|
this.flow = flow; //FlowDesigner类的实例
|
this.paper = flow.paper; //画布rapheal
|
this.options = options;
|
this.type = "userTask";
|
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.$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.text = null; //文本
|
this.ccelement = null; //圆心
|
this.centerpoint = []; //矩形的中心点
|
this.linein = []; //所有进来的线
|
this.lineout = [];//所有出去的线
|
this.content = {}; //任务节点的数据
|
this.completeState = options.completeState || 0; //0 代表否 1代表已完 2代表正当 3代表还未开始
|
|
}
|
|
UserTask.prototype = $.extend(UserTask.prototype, {
|
init: function () {
|
var number = this.flow.createTaskNum();
|
var tempName = (new Date()).getTime();
|
if (!this.isLoad) {
|
this.id = "userTask_" + 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"
|
}).toFront();
|
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"
|
}).toFront();
|
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"
|
}).toFront();
|
break;
|
default:
|
this.element = this.paper.rect(this.x, this.y, this.w, this.h, this.angle).attr({
|
"fill": "#f9f9f9",
|
"cursor": "pointer"
|
}).toFront();
|
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).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);
|
|
|
//文字
|
if (!this.isLoad) {
|
this.text = this.paper.text(this.bbox.x + this.bbox.width / 2, this.bbox.y + this.bbox.height / 2, "任务" + number).attr({"font-size": "14px"});
|
} else {
|
this.text = this.paper.text(this.bbox.x + this.bbox.width / 2, this.bbox.y + this.bbox.height / 2, this.options.text).attr({"font-size": "14px"});
|
}
|
|
|
//中心点坐标
|
this.centerpoint = [this.bbox.x + this.bbox.width / 2, this.bbox.y + this.bbox.height / 2];
|
|
//根据中心点和宽度高度得到四个顶点 //定点开始顺时针
|
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.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(); //圆心
|
|
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.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 + _that.h / 2 - 10 + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()),
|
"width": _that.w - 2
|
});
|
_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;
|
bpz = _that.flow.collision(_that, L, R, T, B); //被碰撞
|
if (bpz != null && bpz.type != "subProcess") {//1.当碰到元素并且元素不是子流程 不可落下
|
dropStatus = false;
|
}
|
|
bpzcenter = _that.flow.collisionCenterLine(_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;
|
//判断是否进入子流程
|
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(x, y, bpzcenter);
|
}
|
})
|
} else {
|
//没有线段
|
_that.render(x, y, bpzcenter);
|
}
|
}
|
} else if (bpz == null) {
|
if (_that.parentElem != null) {
|
//原来在小空间中
|
if (_that.linein.length > 0 || _that.lineout.length > 0) {
|
//如果含有线段,则必须提示,因为进入新的空间,旧的空间中的线段需要删除
|
var L = x;
|
var R = L + _that.w;
|
var T = y;
|
var B = T + _that.h;
|
//判断当前是否已经出了小空间
|
if (!_that.comeInSubProcess2(L, R, T, B)) {
|
$.messager.confirm('再次确认', '该任务节点原属于子流程空间,进入父空间时会删除原来的线段,还要继续进入吗?', function (r) {
|
if (!r) {
|
|
_that.elementbox.attr({"x": startX, "y": startY}); //不能落下的地方就返回
|
} else {
|
|
_that.render(x, y, bpzcenter);
|
}
|
})
|
} else {
|
//没有出小空间
|
|
_that.render(x, y, bpzcenter);
|
}
|
} else {
|
//没有线段
|
|
_that.render(x, y, bpzcenter);
|
}
|
} else {
|
//原来在大空间中
|
_that.render(x, y, bpzcenter);
|
}
|
}
|
|
} else {
|
_that.elementbox.attr({"x": startX, "y": startY}); //不能落下的地方就返回
|
}
|
|
dropStatus = false;
|
return false;
|
|
});
|
} else if (this.completeState == 1 || this.completeState == 2) {
|
this.element.mouseover(function (e) {
|
$("[id*=divshow_]").hide();
|
var wheight = e.view.innerHeight; //屏幕大小
|
var wheight2 = Math.floor(wheight / 2);//屏幕大小的一半
|
var name = "divshow_" + _that.id;
|
if ($("#" + name).length == 0) {
|
//创建
|
if (e.pageY <= wheight2) {
|
var str = "<div id='" + name + "' class='show' style='left:" + (e.pageX + 0) + "px; top:" + (e.pageY + 0) + "px;'><p class='title'>" + _that.getText() + "</p><div class='con' style='max-height:" + wheight2 + "px'>";
|
} else {
|
var str = "<div id='" + name + "' class='show' style='left:" + (e.pageX + 0) + "px; bottom:" + (wheight - e.pageY + 0) + "px;'><p class='title'>" + _that.getText() + "</p><div class='con' style='max-height:" + wheight2 + "px'>";
|
}
|
|
if (_that.completeState == 1) {
|
|
str += "<h4 class='yi'>已办理</h4>";
|
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
|
|
$.each(_that.content.activityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>办理时间</strong><span>" + el.time + "</span></p><p><strong>办理意见</strong><span>" + el.advice + "</span></p>";
|
})
|
}
|
} else if (_that.completeState == 2) {
|
|
if (_that.content.waitActivityUsers && _that.content.waitActivityUsers.length > 0) {
|
str += "<h4 class='zhengzai'>正在办理</h4>";
|
$.each(_that.content.waitActivityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>开始时间</strong><span>" + el.time + "</span></p>";
|
})
|
}
|
|
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
|
str += "<h4 class='yi'>已办理</h4>";
|
$.each(_that.content.activityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>办理时间</strong><span>" + el.time + "</span></p><p><strong>办理意见</strong><span>" + el.advice + "</span></p>";
|
})
|
}
|
|
|
}
|
|
str += "</div></div>";
|
|
$("#" + _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});
|
}
|
|
}
|
|
|
})
|
|
}
|
|
/* 控制点4的移动
|
//控制点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)
|
// //控制点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) { //userTask的渲染
|
|
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个元素的大小不一定相同,先到中心点,再减去自身的一半
|
}
|
|
}
|
}
|
|
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 + this.bbox.height / 2})
|
//扩大的外框
|
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.$elementctrl4.css({ "left": (this.bbox.x - this.bmargin + this.bbox.width + 8), "top": (this.bbox.y - this.bmargin + this.bbox.height + 8) });
|
|
// //是否有父元素
|
// var parent = this.addParent();
|
// if (parent != null) {
|
// //目前进入到子流程中
|
// parent.elementbox.attr({ "stroke": "#000000", "stroke-width": 0.5 });
|
// } else {
|
// //在子流程外
|
// if (this.parentElem) {
|
// this.parentElem.removeSubElement(this);
|
// this.parentElem = null;
|
// //表示新加入的到某个,则原来子流程中的所有的线段需要移除
|
// this.removeLine();
|
// }
|
// }
|
|
//父元素处理
|
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) {
|
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);
|
}
|
});
|
|
|
},
|
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("");//清空
|
}
|
},
|
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});
|
//父元素
|
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) {//判断是否在子流程里面
|
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 Line(flow, options) {
|
this.flow = flow; //FlowDesigner类的实例
|
this.paper = flow.paper; //画布rapheal
|
this.options = options;
|
this.type = "line";
|
this.selected = false;
|
this.id = options.id ? options.id : "";
|
this.isLoad = options.isLoad ? true : false; //是否是加载的元素
|
this.linetype = options.linetype ? options.linetype : 0;
|
|
//元素
|
this.x1 = options.x1; //起点坐标x
|
this.y1 = options.y1;//起点坐标y
|
this.x2 = options.x2;//终点坐标x
|
this.y2 = options.y2;//终点坐标y
|
|
this.nodestart = options.nodestart;
|
this.nodeend = options.nodeend;
|
this.self = options.self; //起点和终点是否是同一个
|
//添加节点
|
this.linestr = ""; //线的字符串
|
this.line = null;//线
|
this.bbox = null; //线的外框
|
this.linebox = null; //线的可见外框
|
this.text = null; //线的文字
|
this.textPosWord = 0; //线上的文字向左偏移字的个数
|
|
this.linepoints = []; //线上的小圆点
|
this.linepointsxy = []; //线上的线段集合
|
|
this.content = {}; //线段数据
|
|
}
|
|
Line.prototype = $.extend(Line.prototype, {
|
init: function () {
|
var linenumber = this.flow.createLineNum();
|
var tempName = (new Date()).getTime();
|
if (!this.isLoad) {
|
this.id = "line_" + tempName;
|
}
|
|
//线
|
if (!this.self) {
|
if (!this.isLoad) {
|
//如果类型是双向,则需要画双箭头
|
if (this.linetype == 1) {
|
var arrowPos = computeArrowPos(this.x2, this.y2, this.x1, this.y1);
|
var x1a = arrowPos[0][0];
|
var y1a = arrowPos[0][1];
|
var x1b = arrowPos[1][0];
|
var y1b = arrowPos[1][1];
|
|
var result = ["M", this.x1, this.y1, "L", x1a, y1a, "M", this.x1, this.y1, "L", x1b, y1b, "M", this.x1, this.y1, "L", this.x2, this.y2];
|
|
this.linestr = result.join(",");
|
} else {
|
this.linestr = "M" + this.x1 + "," + this.y1 + "L" + this.x2 + "," + this.y2;
|
}
|
} else {
|
this.linestr = this.options.linestr;
|
}
|
|
this.line = this.paper.path(this.linestr).attr({
|
"stroke-width": 2,
|
"stroke": "#000000",
|
"arrow-end": "open-wide",
|
"cursor": "pointer",
|
"stroke-linecap": "round",
|
"stroke-linejoin": "round"
|
});
|
|
|
this.bbox = this.line.getBBox();
|
|
//可见外框
|
this.linebox = this.paper.rect(this.bbox.x, this.bbox.y, this.bbox.width, this.bbox.height).attr({
|
"stroke-dasharray": "- ",
|
"stroke": "#000000",
|
"stroke-width": 0.5
|
}).hide();
|
//中间的圆点
|
if (!this.isLoad) {
|
var centercircle = new SmallCircle(this.flow, this, {"cx": this.bbox.cx, "cy": this.bbox.cy});
|
centercircle.init();
|
this.linepoints.push(centercircle);
|
this.linestr = "M" + this.x1 + "," + this.y1 + "L" + this.bbox.cx + "," + this.bbox.cy + "L" + this.x2 + "," + this.y2;
|
this.linepointsxy = Raphael.parsePathString(this.linestr);
|
} else {
|
this.linepointsxy = Raphael.parsePathString(this.linestr);
|
|
//如果类型是双向,则需要删除前面几个节点
|
if (this.linetype == 1) {
|
this.linepointsxy.splice(0, 4);
|
}
|
|
//中间小圆点
|
for (var i = 1; i < this.linepointsxy.length - 1; i++) {
|
var centercircle = new SmallCircle(this.flow, this, {
|
"cx": this.linepointsxy[i][1],
|
"cy": this.linepointsxy[i][2]
|
});
|
centercircle.init();
|
this.linepoints.push(centercircle);
|
}
|
}
|
|
|
//文字 中心节点
|
if (!this.isLoad) {
|
this.text = this.paper.text(this.bbox.cx + 12, this.bbox.cy - 6, "线" + linenumber).attr({"font-size": "12px"}).toBack();
|
|
} else {
|
|
//第一个小圆点的位置
|
if (this.linepoints.length > 0) {
|
this.text = this.paper.text(this.linepoints[0].cx + 12, this.linepoints[0].cy - 6, this.options.text).attr({"font-size": "12px"}).toBack();
|
} else {
|
this.text = this.paper.text(this.bbox.cx + 12, this.bbox.cy - 6, this.options.text).attr({"font-size": "12px"}).toBack();
|
}
|
|
}
|
|
} else {
|
if (!this.isLoad) {
|
//开始节点自身线
|
var x3 = this.x1;
|
var y3 = this.y1 + this.nodestart.h * 1 / 4;
|
var x4 = x3 - this.nodestart.w * 3 / 4;
|
var y4 = y3;
|
var x5 = x4;
|
var y5 = y4 - this.nodestart.h * 3 / 4;
|
|
|
this.linestr = "M" + this.x1 + "," + this.y1 + "L" + x3 + "," + y3 + "L" + x4 + "," + y4 + "L" + x5 + "," + y5 + "L" + this.x2 + "," + this.y2;
|
} else {
|
this.linestr = this.options.linestr;
|
}
|
|
this.line = this.paper.path(this.linestr).attr({
|
"stroke-width": 2,
|
"stroke": "#000000",
|
"arrow-end": "open-wide",
|
"cursor": "pointer",
|
"stroke-linecap": "round",
|
"stroke-linejoin": "round"
|
});
|
|
//外框
|
this.bbox = this.line.getBBox();
|
|
//可见外框
|
this.linebox = this.paper.rect(this.bbox.x, this.bbox.y, this.bbox.width, this.bbox.height).attr({
|
"stroke-dasharray": "- ",
|
"stroke": "#000000",
|
"stroke-width": 0.5
|
}).hide();
|
this.linepointsxy = Raphael.parsePathString(this.linestr);
|
this.redrawSmallCircle(false);
|
|
//文字 第一个小圆点
|
if (!this.isLoad) {
|
this.text = this.paper.text(x3 + 12, y3, "线" + linenumber).attr({"font-size": "12px"}).toBack();
|
} else {
|
this.text = this.paper.text(x3 + 12, y3, this.options.text).attr({"font-size": "12px"}).toBack();
|
}
|
|
}
|
|
//开始节点增加出去的线
|
this.nodestart && this.nodestart.lineout.push(this);
|
//目标节点增加进入的线
|
this.nodeend && this.nodeend.linein.push(this);
|
|
|
var _that = this;
|
if (this.flow._DEFALUTS_.mode == "design") {
|
//线的点击
|
this.line.click(function (event) {
|
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
|
_that.linebox.show();
|
//小菜单
|
$(".right").css({
|
"left": _that.bbox.x + _that.bbox.width + 10 - _that.flow.getScrollx(),
|
"top": _that.bbox.y + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()
|
}).attr("tempid", _that.id).end().find(".sequence").hide();
|
//显示线上的圆点
|
$.each(_that.linepoints, function (index, circle) {
|
circle.element.show();
|
|
});
|
//显示两头节点上的圆心
|
_that.nodestart && _that.nodestart.ccelement.show();
|
_that.nodeend && _that.nodeend.ccelement.show();
|
|
_that.selected = true; //选中元素
|
var wenbenid = $(".taskinput input").attr("wenbenid");
|
if (wenbenid) {
|
_that.setText(wenbenid);
|
}
|
_that.text.show();
|
}
|
});
|
|
//线的双击
|
this.line.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);
|
//显示文本框
|
//线的宽度可能很细,需要取Max
|
$(".taskinput").css({
|
"left": _that.bbox.cx - 15 - _that.flow.getScrollx(),
|
"top": (_that.bbox.cy - 10 + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()),
|
"width": Math.max(_that.bbox.width, 60)
|
});
|
_that.selected = true;
|
//文本框本身隐藏
|
_that.text.hide();
|
}
|
|
});
|
|
|
this.line.mouseover(function () {
|
//只有当lining状态为true时,使用
|
if (_that.flow.addPoint == true || _that.flow.subtractPoint == true) {
|
//_that.linebox.show();
|
$.each(_that.linepoints, function (index, circle) {
|
circle.element.show();
|
});
|
}
|
|
});
|
|
}
|
|
|
},
|
unSelect: function () { //非选中状态
|
|
//可见外框隐藏
|
this.linebox.hide();
|
//所有的线上的圆不显示
|
$.each(this.linepoints, function (index, circle) {
|
|
circle.element.hide();
|
});
|
//文本框
|
if (this.selected == true) {
|
var wenbenid = $(".taskinput input").attr("wenbenid");
|
if (wenbenid && wenbenid == this.id) {
|
var value = $(".taskinput input").val();
|
value = $.trim(value);
|
if (value) {
|
this.setText(wenbenid);
|
} else {
|
this.setNullText();
|
}
|
|
$(".taskinput input").attr("wenbenid", "");
|
}
|
this.text.show();
|
}
|
//文本框回归原位
|
$(".taskinput").css({"left": -100, "top": -100});
|
this.selected = false;
|
|
},
|
removeElement: function () {
|
this.line.remove();
|
this.linebox.remove();
|
this.text.remove();
|
//文本框回归
|
$(".taskinput").css({"left": -100, "top": -100});
|
|
//小圆点
|
$.each(this.linepoints, function (index, circle) {
|
circle.removeElement();
|
});
|
|
this.nodestart && this.nodestart.removeOutLine(this);
|
this.nodeend && this.nodeend.removeInLine(this);
|
//
|
//小菜单回归原位
|
$(".right").css({"left": -100, "top": -100});
|
|
|
},
|
redrawStart: function (startcx, startcy) { //开始坐标修改后,重绘
|
|
//重写线段
|
this.linestr = this.combPathFromStart(startcx, startcy); //找到合适的下一个点,作为目标点,做连线
|
this.line.attr("path", this.linestr);
|
|
this.bbox = this.line.getBBox();
|
//外框
|
this.linebox.attr({
|
"x": this.bbox.x,
|
"y": this.bbox.y,
|
"width": this.bbox.width,
|
"height": this.bbox.height
|
});
|
//this.linestr = this.combPath();
|
//console.log("整理好后str", this.linestr);
|
//根据坐标点重新渲染小圆点
|
this.redrawSmallCircle(false);
|
//重绘文本位置
|
this.renderText();
|
|
},
|
redrawEnd: function (endcx, endcy) {
|
|
|
//重写线段,endcx,endcy是中心点调整,重新计算开始坐标,需要得到箭头的坐标,如果中间点还在一条直线上,则还需要计算新的中间点坐标
|
|
this.linestr = this.combPathFromEnd(endcx, endcy);
|
//console.log(this.linestr);
|
this.line.attr("path", this.linestr);
|
|
this.bbox = this.line.getBBox();
|
//外框
|
this.linebox.attr({
|
"x": this.bbox.x,
|
"y": this.bbox.y,
|
"width": this.bbox.width,
|
"height": this.bbox.height
|
});
|
//this.linestr = this.combPath();
|
//console.log("整理好后str", this.linestr);
|
//根据坐标点重新渲染小圆点
|
this.redrawSmallCircle(false);
|
//重绘文本位置
|
this.renderText();
|
},
|
linePointsDrag: function () {
|
//线上的点拖动
|
var _that = this;
|
$.each(this.linepoints, function (index, elem) {
|
var circlecx = 0;
|
var circlecy = 0;
|
var circlepxindex = 0;
|
elem.drag(function (tx, ty, x, y, e) { //拖动中
|
|
_lineCircleMove(tx, ty, x, y, e, _that, circlecx, circlecy, this, circlepxindex);
|
},
|
function (x, y, e) { //开始
|
var bbox = this.getBBox();
|
//得到圆点的中心点坐标
|
circlecx = bbox.cx;
|
circlecy = bbox.cy;
|
circlepxindex = _lineCircleStart(x, y, e, _that, circlecx, circlecy);
|
//console.log(circlepxindex);
|
}, function (e) { //结束拖动
|
|
_lineCircleEnd(e, _that);
|
});
|
});
|
},
|
|
combPath: function () { //通过线段集合重新组合path
|
var path = "";
|
$.each(this.linepointsxy, function (index, elem) {
|
path += elem[0] + elem[1] + "," + elem[2];
|
})
|
return path;
|
},
|
combPathFromStart: function (nsx, nsy) { //通过线段集合重新组合path,从start出发
|
var path = "";
|
//判断相邻的两个点连成的直线,第三个点是否在上面,如果在,则把第二个点去掉,再判断第四个点是否在上面,如果在则把第三个点去掉,如果不在,则到第三个点位置。
|
//这个方法就是判断到两个点直线直到转折为止。
|
var temp = [];
|
temp.push(["M", nsx, nsy]); //这个赋值只是个占位,后面还得改下
|
var x1 = this.linepointsxy[0][1];
|
var y1 = this.linepointsxy[0][2];
|
var x2 = this.linepointsxy[1][1];
|
var y2 = this.linepointsxy[1][2];
|
var zhixianindex = 1;
|
var _that = this;
|
var modifyNodes = []; //需要修改的小圆点的坐标
|
var modifyNodesIndexs = [];//需要修改的小圆点的位置
|
var length = this.linepointsxy.length;
|
$.each(this.linepointsxy, function (index, elem) {
|
|
if (index > 1) {
|
if (floatToFix4(x1) != floatToFix4(x2)) {
|
var y = _that.flow.getYLinePointFormula(x1, y1, x2, y2, elem[1]);
|
//console.log(y,elem[2])
|
if (floatToFix4(y) == floatToFix4(elem[2])) {
|
zhixianindex = index;
|
modifyNodes.push(_that.linepointsxy[index - 1]);
|
modifyNodesIndexs.push(index - 1);
|
} else {
|
return false;
|
}
|
|
} else {
|
var x = _that.flow.getXLinePointFormula(x1, y1, x2, y2, elem[2]);
|
//console.log(x,elem[1])
|
if (floatToFix4(x) == floatToFix4(elem[1])) {
|
zhixianindex = index;
|
modifyNodes.push(_that.linepointsxy[index - 1]);
|
modifyNodesIndexs.push(index - 1);
|
} else {
|
return false;
|
}
|
}
|
}
|
|
});
|
|
//zhixianindex的值当等于最后一个节点时,重新计算箭头节点
|
if (zhixianindex == length - 1) {
|
if (this.nodeend.type == "end") {
|
var arrow = this.flow.getCircleArrowPosXY(this.nodestart, this.nodeend);
|
} else if (this.nodeend.type == "gateway") {
|
var arrow = this.flow.getGatewayArrowPosXY(this.nodestart, this.nodeend);
|
} else if (this.nodeend.type == "userTask" || this.nodeend.type == "subProcess") {
|
var arrow = this.flow.getArrowPosXY(this.nodestart, this.nodeend);
|
}
|
|
this.linepointsxy[length - 1][1] = arrow.x;
|
this.linepointsxy[length - 1][2] = arrow.y;
|
|
}
|
if (zhixianindex == length - 1) {
|
var tempEnd = this.nodeend;
|
} else {
|
tempEnd = this.linepoints[zhixianindex - 1];
|
}
|
|
//重新计算开始节点
|
var startPoint = flowDesigner.getStartPosXY(this.nodestart, tempEnd);
|
this.x1 = startPoint.x;
|
this.y1 = startPoint.y;
|
this.linepointsxy[0][1] = startPoint.x;
|
this.linepointsxy[0][2] = startPoint.y;
|
|
temp[0] = ["M", startPoint.x, startPoint.y];
|
|
$.each(this.linepointsxy, function (index, elem) {
|
if (index >= zhixianindex) {
|
temp.push(elem);
|
}
|
});
|
|
if (modifyNodes.length > 0) {
|
//根据坐标修改小圆点
|
this.modifyLineCircle(modifyNodes, modifyNodesIndexs, startPoint, {"x": temp[1][1], "y": temp[1][2]});
|
}
|
|
//如果节点类型是1,则表明是双向,需要画双箭头
|
if (this.content && this.content.nodeType && this.content.nodeType == "1") {
|
var arrowPos = computeArrowPos(temp[1][1], temp[1][2], temp[0][1], temp[0][2]);
|
var x1a = arrowPos[0][0];
|
var y1a = arrowPos[0][1];
|
var x1b = arrowPos[1][0];
|
var y1b = arrowPos[1][1];
|
|
temp.splice(1, 0, ["L", x1a, y1a], ["M", startPoint.x, startPoint.y], ["L", x1b, y1b], ["M", startPoint.x, startPoint.y]);
|
}
|
|
$.each(temp, function (index, elem) {
|
path += elem[0] + elem[1] + "," + elem[2];
|
});
|
|
return path;
|
},
|
|
combPathFromEnd: function (nex, ney) { //通过线段集合重新组合path,从end向上找出合适的出发点,和新的目的中心点连接,找出箭头点。
|
var path = "";
|
//判断相邻的两个点连成的直线,第三个点是否在上面,如果在,则把第二个点去掉,再判断第四个点是否在上面,如果在则把第三个点去掉,如果不在,则到第三个点位置。
|
//这个方法就是判断到两个点直线直到转折为止。
|
var temp = [];
|
var length = this.linepointsxy.length;
|
temp.push(["L", nex, ney]); //这个赋值只是个占位,最终箭头的nex和ney还是要计算获得
|
var x1 = this.linepointsxy[length - 1][1];
|
var y1 = this.linepointsxy[length - 1][2];
|
var x2 = this.linepointsxy[length - 2][1];
|
var y2 = this.linepointsxy[length - 2][2];
|
var zhixianindex = length - 2;
|
var _that = this;
|
var modifyNodes = []; //需要修改的小圆点的坐标
|
var modifyNodesIndexs = [];//需要修改的小圆点的位置
|
|
//console.log(_that.linepointsxy);
|
for (var i = length - 3; i >= 0; i--) {
|
//console.log(x1, y1, x2, y2, _that.linepointsxy[i][1]);
|
|
if (floatToFix4(x1) != floatToFix4(x2)) { //求y值时,会出现x1-x2为0的情况
|
var y = _that.flow.getYLinePointFormula(x1, y1, x2, y2, _that.linepointsxy[i][1]);
|
//console.log(floatToFix4(y) ,floatToFix4(_that.linepointsxy[i][2]));
|
if (floatToFix4(y) == floatToFix4(_that.linepointsxy[i][2])) {
|
zhixianindex = i;
|
modifyNodes.unshift(_that.linepointsxy[i + 1]); //向前插入
|
modifyNodesIndexs.unshift(i + 1);
|
} else {
|
break;
|
}
|
} else {//求y值时,会出现x1-x2为0的情况,当出现时,求x值,来进行判断
|
var x = _that.flow.getXLinePointFormula(x1, y1, x2, y2, _that.linepointsxy[i][2]);
|
if (floatToFix4(x) == floatToFix4(_that.linepointsxy[i][1])) {
|
zhixianindex = i;
|
modifyNodes.unshift(_that.linepointsxy[i + 1]);
|
modifyNodesIndexs.unshift(i + 1);
|
} else {
|
break;
|
}
|
|
}
|
|
}
|
// $.each(this.linepointsxy, function (index, elem) {
|
// if (index >= zhixianindex) {
|
// temp.unshift(elem);
|
// }
|
// });
|
for (var i = zhixianindex; i >= 0; i--) {
|
temp.unshift(_that.linepointsxy[i]);
|
}
|
|
//根据两点得到箭头坐标
|
//1.首先得到是从哪个小圆点出发的
|
var nearx = temp[temp.length - 2][1];
|
var neary = temp[temp.length - 2][2];
|
var source = null;
|
$.each(this.linepoints, function (index, circle) {
|
if (floatToFix4(nearx) == floatToFix4(circle.cx) && floatToFix4(neary) == floatToFix4(circle.cy)) {
|
source = circle;
|
return false;
|
}
|
});
|
|
if (source == null) {
|
source = this.nodestart;
|
//修改开始节点
|
var startPoint = flowDesigner.getStartPosXY(source, this.nodeend);
|
this.x1 = startPoint.x;
|
this.y1 = startPoint.y;
|
this.linepointsxy[0][1] = startPoint.x;
|
this.linepointsxy[0][2] = startPoint.y;
|
temp[0][1] = startPoint.x;
|
temp[0][2] = startPoint.y;
|
}
|
|
|
switch (this.nodeend.type) {
|
case "end":
|
arrow = this.flow.getCircleArrowPosXY(source, this.nodeend);
|
break;
|
case "gateway":
|
arrow = this.flow.getGatewayArrowPosXY(source, this.nodeend);
|
break;
|
case "subProcess":
|
case "userTask":
|
arrow = this.flow.getArrowPosXY(source, this.nodeend);
|
break;
|
}
|
|
//console.log("arrow",arrow);
|
temp[temp.length - 1][1] = arrow.x;
|
temp[temp.length - 1][2] = arrow.y;
|
|
//console.log("modifyNodes",modifyNodes);
|
if (modifyNodes.length > 0) {
|
//根据坐标修改小圆点
|
|
this.modifyLineCircle(modifyNodes, modifyNodesIndexs, {
|
"x": temp[temp.length - 2][1],
|
"y": temp[temp.length - 2][2]
|
}, {"x": arrow.x, "y": arrow.y});
|
|
}
|
this.linepointsxy[length - 1][1] = arrow.x;
|
this.linepointsxy[length - 1][2] = arrow.y;
|
this.x2 = arrow.x;
|
this.y2 = arrow.y;
|
|
//如果节点类型是1,则表明是双向,需要画双箭头
|
if (this.content && this.content.nodeType && this.content.nodeType == "1") {
|
var arrowPos = computeArrowPos(temp[1][1], temp[1][2], temp[0][1], temp[0][2]);
|
var x1a = arrowPos[0][0];
|
var y1a = arrowPos[0][1];
|
var x1b = arrowPos[1][0];
|
var y1b = arrowPos[1][1];
|
|
temp.splice(1, 0, ["L", x1a, y1a], ["M", startPoint.x, startPoint.y], ["L", x1b, y1b], ["M", startPoint.x, startPoint.y]);
|
}
|
|
$.each(temp, function (index, elem) {
|
path += elem[0] + elem[1] + "," + elem[2];
|
});
|
|
return path;
|
},
|
|
//修改线上的小圆点的坐标, modifypoints需要修改的小圆点,modifyNodesIndexs需要修改的小圆点的在linepointsxy的索引,startpoint 线上的开始节点,endpoint 线上的结束节点
|
modifyLineCircle: function (modifypoints, modifyNodesIndexs, startpoint, endpoint) {
|
var length = modifypoints.length;
|
var newPoint;
|
//console.log("startpoint",startpoint);
|
//console.log("endpoint",endpoint);
|
for (var i = 0; i < length; i++) {
|
|
//循环需要修改的小圆点
|
// nx = (startpoint.x + endpoint.x) * (i + 1) / (length + 1);
|
// ny = (startpoint.y + endpoint.y) * (i + 1) / (length + 1);
|
newPoint = this.flow.getNewSmallCirclePosXY(startpoint, endpoint, modifypoints, length + 1, i + 1);
|
|
//得到新的坐标的值
|
var _that = this;
|
_that.linepointsxy[modifyNodesIndexs[i]][1] = newPoint.x;
|
_that.linepointsxy[modifyNodesIndexs[i]][2] = newPoint.y;
|
|
|
// $.each(this.linepoints, function (index, circle) {
|
|
// if (floatToFix4(modifypoints[i][1]) == floatToFix4(circle.cx) && floatToFix4(modifypoints[i][2]) == floatToFix4(circle.cy)) {
|
// //circle.element.attr({ "cx": nx, "cy": ny });
|
// circle.render({ "cx": newPoint.x, "cy": newPoint.y });
|
// console.log("新坐标", newPoint.x, newPoint.y);
|
// console.log(_that.linepointsxy);
|
// console.log("所在位置", modifyNodesIndexs[i]);
|
// _that.linepointsxy[modifyNodesIndexs[i]][1] = newPoint.x;
|
// _that.linepointsxy[modifyNodesIndexs[i]][2] = newPoint.y;
|
// }
|
// });
|
}
|
},
|
|
|
currentPointInPathIndex: function (x, y) { //当前节点在线段上的所属位置
|
var curIndex = 0;
|
//console.log("当前节点在线段上的所属位置", this.linepointsxy);
|
$.each(this.linepointsxy, function (index, elem) {
|
|
if (floatToFix4(elem[1]) == floatToFix4(x) && floatToFix4(elem[2]) == floatToFix4(y)) {
|
curIndex = index;
|
return false;
|
}
|
});
|
return curIndex;
|
},
|
|
//重绘线上所有的小圆点 show:true表示小圆点显示
|
redrawSmallCircle: function (show) {
|
//先去掉线上的小圆点
|
$.each(this.linepoints, function (index, circle) {
|
circle.removeElement();
|
});
|
this.linepoints = [];
|
//重新获取设置线上的小圆点
|
var newlength = this.linepointsxy.length;
|
_that = this;
|
$.each(this.linepointsxy, function (index, arr) {
|
if (index > 0 && index < newlength - 1) { //去掉头尾两个小圆点
|
//生成小圆点
|
var tempCircle = new SmallCircle(_that.flow, _that, {"cx": arr[1], "cy": arr[2], "show": show});
|
tempCircle.init();
|
_that.linepoints.push(tempCircle);
|
}
|
});
|
},
|
|
//删除线上的小圆点
|
removeSmallCircle: function (circle) {
|
|
if (this.linepoints.length <= 1) {
|
$.messager.alert("删除线上小圆点-提示", "当线段只有唯一一个小圆点时,该小圆点不能被删除!");
|
return false;
|
}
|
var deleindex = 0;
|
var oldlength = this.linepointsxy.length;
|
$.each(this.linepointsxy, function (index, attr) {
|
if (floatToFix4(circle.cx) == floatToFix4(attr[1]) && floatToFix4(circle.cy) == floatToFix4(attr[2])) {
|
deleindex = index;
|
return false;
|
}
|
});
|
|
this.linepointsxy.splice(deleindex, 1);
|
var newlength = this.linepointsxy.length;
|
var _that = this;
|
if (deleindex == oldlength - 2) {
|
//重新计算箭头节点
|
var source = null;
|
if (newlength == 2) {
|
source = this.nodestart;
|
} else {
|
|
$.each(this.linepoints, function (index, elem) {
|
|
if (floatToFix4(_that.linepointsxy[newlength - 2][1]) == floatToFix4(elem.cx) && floatToFix4(_that.linepointsxy[newlength - 2][2]) == floatToFix4(elem.cy)) {
|
source = elem;
|
}
|
});
|
}
|
if (this.nodeend.type == "end") {
|
var arrow = this.flow.getCircleArrowPosXY(source, this.nodeend);
|
} else if (this.nodeend.type == "gateway") {
|
var arrow = this.flow.getGatewayArrowPosXY(source, this.nodeend);
|
} else if (this.nodeend.type == "userTask" || this.nodeend.type == "subProcess") {
|
var arrow = this.flow.getArrowPosXY(source, this.nodeend);
|
}
|
|
this.linepointsxy[newlength - 1][1] = arrow.x;
|
this.linepointsxy[newlength - 1][2] = arrow.y;
|
|
}
|
|
this.linestr = Raphael.parsePathString(this.linepointsxy);
|
//重绘小圆点
|
this.redrawSmallCircle(true); //this.linepoints的改变在线段的重绘小圆点里面
|
//重新画线
|
this.line.attr("path", this.linestr);
|
|
},
|
//重绘文本位置
|
renderText: function () {
|
//跟着小圆点的位置,如果有小圆点,就跟着第一个小圆点,如果没有去中心点
|
if (this.linepoints.length > 0) {
|
this.text.attr({"x": this.linepoints[0].cx + 12, "y": this.linepoints[0].cy - 6})
|
} else {
|
this.bbox = this.line.getBBox();
|
this.text.attr({"x": this.bbox.cx + 12, "y": this.bbox.cy - 6});
|
}
|
|
},
|
setNullText: function () {
|
this.text.attr({"text": ""});
|
},
|
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(Math.max(this.bbox.width, 60) / 12); //一行可显示的中文字数
|
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("");//清空
|
}
|
},
|
getText: function () {
|
return this.text.attr("text");
|
},
|
//移动节点含有自身线时,重绘
|
renderMoveSelf: function () {
|
//开始节点自身线
|
this.x1 = this.nodestart.centerpoint[0];
|
this.y1 = this.nodestart.centerpoint[1] + this.nodestart.h / 2;
|
this.x2 = this.nodestart.x;
|
this.y2 = this.nodestart.centerpoint[1];
|
var x3 = this.x1;
|
var y3 = this.y1 + this.nodestart.h * 1 / 4;
|
var x4 = x3 - this.nodestart.w * 3 / 4;
|
var y4 = y3;
|
var x5 = x4;
|
var y5 = y4 - this.nodestart.h * 3 / 4;
|
this.linestr = "M" + this.x1 + "," + this.y1 + "L" + x3 + "," + y3 + "L" + x4 + "," + y4 + "L" + x5 + "," + y5 + "L" + this.x2 + "," + this.y2;
|
this.linepointsxy = [];
|
this.linepointsxy = Raphael.parsePathString(this.linestr);
|
this.render2();
|
},
|
recalculatePath: function () { //重新计算路径
|
if (!this.self) {
|
this.redrawStart(this.x1, this.y1);
|
} else {
|
this.renderMoveSelf();
|
}
|
},
|
render2: function () {//重绘线段
|
this.line.attr("path", this.linestr);
|
|
//外框
|
this.bbox = this.line.getBBox();
|
|
//可见外框
|
this.linebox.attr({
|
"x": this.bbox.x,
|
"y": this.bbox.y,
|
"width": this.bbox.width,
|
"height": this.bbox.height
|
});
|
//线上原来的小圆点删除
|
for (var i = 0; i < this.linepoints.length; i++) {
|
this.linepoints[i].removeElement();
|
}
|
this.linepoints = [];
|
//中间小圆点
|
for (var i = 1; i < this.linepointsxy.length - 1; i++) {
|
var centercircle = new SmallCircle(this.flow, this, {
|
"cx": this.linepointsxy[i][1],
|
"cy": this.linepointsxy[i][2]
|
});
|
centercircle.init();
|
this.linepoints.push(centercircle);
|
}
|
this.renderText();
|
}
|
|
});
|
|
//计算自定义箭头坐标
|
function computeArrowPos(x1, y1, x2, y2) {
|
var angle = Raphael.angle(x1, y1, x2, y2);//得到两点之间的角度
|
var a45 = Raphael.rad(angle - 30);//角度转换成弧度
|
var a45m = Raphael.rad(angle + 30);
|
var x1a = x2 + Math.cos(a45) * 10;
|
var y1a = y2 + Math.sin(a45) * 10;
|
var x1b = x2 + Math.cos(a45m) * 10;
|
var y1b = y2 + Math.sin(a45m) * 10;
|
|
return [[x1a, y1a], [x1b, y1b]];
|
}
|
|
//线上的小圆点
|
function SmallCircle(flow, belongLine, options) {
|
this.flow = flow; //FlowDesigner类
|
this.paper = flow.paper;
|
this.belongLine = belongLine;
|
this.type = "smallcircle";
|
|
this.options = options;
|
this.id = "";
|
this.element = null; //start圆
|
this.bbox = null; //圆的真实外框
|
this.coordinate = []; //圆元素的上下左右坐标
|
//元素
|
this.cx = options.cx;
|
this.cy = options.cy;
|
this.centerpoint = [this.cx, this.cy];
|
this.r = 3;
|
this.show = options.show;
|
|
}
|
|
SmallCircle.prototype = $.extend(SmallCircle.prototype, {
|
init: function () {
|
var number = this.flow.createSmallCircleNodeNum();
|
var tempName = (new Date()).getTime();
|
this.id = "smallcircle_" + tempName;
|
//圆
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#ff00ff",
|
"cursor": "move"
|
}).hide();
|
if (this.show) {
|
this.element.show();
|
}
|
this.centerpoint = [this.cx, this.cy];
|
//真外框
|
this.bbox = this.element.getBBox();
|
//坐标(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);
|
var _that = this;
|
|
//圆点的移动
|
var circlecx = 0;
|
var circlecy = 0;
|
var circlepxindex = 0;
|
var weiyiX = 0;
|
var weiyiY = 0;
|
var bpzcenter = null;
|
this.element.drag(function (tx, ty, x, y, e) { //move
|
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
|
|
var currentX = circlecx + tx;
|
var currentY = circlecy + ty;
|
//碰撞自身的中心线
|
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;
|
bpzcenter = _that.flow.collisionSelfCenterLine(_that, L, R, T, B); //中心线匹配
|
if (bpzcenter[0] != null) {
|
currentX = bpzcenter[0];
|
}
|
if (bpzcenter[1] != null) {
|
currentY = bpzcenter[1];
|
}
|
|
_that.belongLine.linepointsxy[circlepxindex][1] = currentX;
|
_that.belongLine.linepointsxy[circlepxindex][2] = currentY;
|
//重写线段
|
_that.belongLine.linestr = _that.belongLine.combPath();
|
_that.belongLine.line.attr("path", _that.belongLine.linestr);
|
//修改text坐标
|
_that.belongLine.renderText();
|
//自身渲染,这个渲染可能包含重绘线段开始和结束坐标
|
_that.render({"cx": currentX, "cy": currentY});
|
|
}
|
|
|
}, function (x, y, e) { //start
|
//得到圆点的中心点坐标
|
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
|
circlecx = _that.bbox.cx;
|
circlecy = _that.bbox.cy;
|
circlepxindex = _that.belongLine.currentPointInPathIndex(circlecx, circlecy);
|
|
weiyiX = e.clientX - _that.flow._DEFALUTS_.dx - _that.bbox.x;//offsetX,不需要减1
|
weiyiY = e.clientY - _that.flow._DEFALUTS_.dy - _that.bbox.y; //offsetY,不需要减32
|
}
|
}, function (e) { //end
|
if (_that.flow.addPoint == false && _that.flow.subtractPoint == false) {
|
_that.belongLine.bbox = _that.belongLine.line.getBBox();
|
_that.belongLine.linebox.attr({
|
"x": _that.belongLine.bbox.x,
|
"y": _that.belongLine.bbox.y,
|
"width": _that.belongLine.bbox.width,
|
"height": _that.belongLine.bbox.height
|
});
|
_that.belongLine.linepointsxy = Raphael.parsePathString(_that.belongLine.linestr);
|
}
|
})
|
//小圆点双击减点自身
|
this.element.dblclick(function () {
|
if (_that.flow.subtractPoint == true) {
|
_that.belongLine.removeSmallCircle(_that);
|
}
|
|
});
|
},
|
render: function (options) { //小圆点
|
this.cx = options.cx;
|
this.cy = options.cy;
|
this.centerpoint = [this.cx, this.cy];
|
this.element.attr({"cx": this.cx, "cy": this.cy});
|
this.centerpoint = [this.cx, this.cy];
|
//真外框
|
this.bbox = this.element.getBBox();
|
//坐标(L,R,T,B)
|
this.coordinate = [];
|
this.coordinate.push(this.bbox.x, this.bbox.x + this.bbox.width, this.bbox.y, this.bbox.y + this.bbox.height);
|
|
//如果该点是连接线段是两个节点,则需要重绘开始节点和箭头节点
|
var length = this.belongLine.linepointsxy.length;
|
var circlepxindex = this.belongLine.currentPointInPathIndex(this.cx, this.cy);
|
if (circlepxindex == 1) {
|
//重绘开始节点
|
var startPoint = flowDesigner.getStartPosXY(this.belongLine.nodestart, this);
|
this.belongLine.x1 = startPoint.x;
|
this.belongLine.y1 = startPoint.y;
|
this.belongLine.linepointsxy[0][1] = startPoint.x;
|
this.belongLine.linepointsxy[0][2] = startPoint.y;
|
}
|
if (length == 3 || circlepxindex == length - 2) {
|
//重绘结束节点
|
switch (this.belongLine.nodeend.type) {
|
|
case "end":
|
var arrow = this.flow.getCircleArrowPosXY(this, this.belongLine.nodeend);
|
break;
|
case "gateway":
|
arrow = this.flow.getGatewayArrowPosXY(this, this.belongLine.nodeend);
|
break;
|
case "subProcess":
|
case "userTask":
|
arrow = this.flow.getArrowPosXY(this, this.belongLine.nodeend);
|
break;
|
}
|
|
this.belongLine.x2 = arrow.x;
|
this.belongLine.y2 = arrow.y;
|
this.belongLine.linepointsxy[length - 1][1] = arrow.x;
|
this.belongLine.linepointsxy[length - 1][2] = arrow.y;
|
|
}
|
this.belongLine.linestr = this.belongLine.combPath();
|
this.belongLine.line.attr("path", this.belongLine.linestr);
|
|
},
|
removeElement: function () {
|
this.element.remove();
|
delete this;
|
}
|
});
|
|
function End(flow, options) {
|
this.flow = flow; //FlowDesigner类
|
this.paper = flow.paper; //画布
|
this.options = options;
|
this.type = "end";
|
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; //start圆
|
|
this.bmargin = 4; //外框和元素的边距
|
this.elementbox = null; //start圆的外框,加厚边距
|
this.bbox = null; //圆的真实外框
|
//this.$moveDiv=null; //外框拖动虚框
|
this.coordinate = []; //圆元素的上下左右四条边坐标
|
this.centerLineCoordinate = []; //圆元素的上下左右四条边坐标,为显示中心线,小一点
|
this.centerMargin = 10; //向中心点向外4个方向扩展的距离
|
this.centerLineX = null;
|
this.centerLineY = null;
|
|
//元素
|
this.cx = options.cx;
|
this.cy = options.cy;
|
this.centerpoint = [this.cx, this.cy];
|
this.r = options.r;
|
this.ccelement = null; //圆心
|
|
this.linein = []; //所有的有关进入的线
|
this.text = null; //文本
|
this.content = {}; //结束节点内容
|
this.completeState = options.completeState || 0; //0 代表否 1代表已完 2代表正当 3代表还未开始
|
|
}
|
|
End.prototype = $.extend(End.prototype, {
|
init: function () {
|
var number = this.flow.createEndNodeNum();
|
var tempName = (new Date()).getTime();
|
if (!this.isLoad) {
|
this.id = "end_" + tempName;
|
}
|
|
//圆
|
switch (this.completeState) {
|
|
case 1: //蓝色
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#e0e9fe",
|
"cursor": "pointer",
|
"stroke": "#2632aa",
|
"stroke-width": 3
|
});
|
break;
|
case 2://绿色
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#ebf8eb",
|
"cursor": "pointer",
|
"stroke": "#017501",
|
"stroke-width": 3
|
});
|
break;
|
case 3://灰色
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#dadada",
|
"cursor": "pointer",
|
"stroke": "#acacac",
|
"stroke-width": 3
|
});
|
break;
|
default:
|
this.element = this.paper.circle(this.cx, this.cy, this.r).attr({
|
"fill": "#ffffff",
|
"stroke-width": 3,
|
"cursor": "pointer"
|
});
|
break;
|
}
|
|
this.centerpoint = [this.cx, this.cy];
|
this.ccelement = this.paper.circle(this.centerpoint[0], this.centerpoint[1], 2).attr({
|
"fill": "#ff0000",
|
"stroke": "ff0000"
|
}).hide(); //圆心
|
|
//end真外框
|
this.bbox = this.element.getBBox();
|
//end扩大的外框
|
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);
|
|
//中心点向外扩展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"}).toBack();
|
} else {
|
this.text = this.paper.text(this.centerpoint[0], this.centerpoint[1] + this.r + 12, this.options.text).attr({"font-size": "12px"}).toBack();
|
}
|
|
|
//隐藏的中心竖线
|
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();
|
|
|
//添加父元素
|
if (!this.isLoad) {
|
this.addParent();
|
}
|
|
|
var _that = this;
|
//end圆的外框点击
|
if (this.completeState == 0) {
|
this.elementbox.click(function (e) {
|
//小菜单
|
$(".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").hide();
|
//显示外框
|
_that.selected = true; //选中元素
|
var wenbenid = $(".taskinput input").attr("wenbenid");
|
if (wenbenid) {
|
_that.setText(wenbenid);
|
}
|
_that.text.show();
|
|
});
|
|
//end圆的外框双击
|
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.cx - _that.r - 15 - _that.flow.getScrollx(),
|
"top": (_that.cy - 10 + _that.flow._DEFALUTS_.dy - _that.flow.getScrolly()),
|
"width": 60
|
});
|
_that.selected = true;
|
//文本框本身隐藏
|
_that.text.hide();
|
}
|
|
});
|
|
//end圆的点击元素
|
this.element.click(function (e) {
|
_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").hide(); //这个8,是为了对齐随便写的
|
});
|
|
//end圆的外层框拖动
|
var weiyiX = 0;
|
var weiyiY = 0;
|
var dropStatus = false;
|
var startX = 0;
|
var startY = 0;
|
var bpz = null;
|
var bpzcenter = null;
|
this.elementbox.drag(function (tx, ty, x, y, e) { //move中
|
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;
|
|
}, function (e) {//move结束
|
|
if (dropStatus == true) {
|
var elemnetboxbbox = this.getBBox();
|
var cx = elemnetboxbbox.cx;
|
var cy = elemnetboxbbox.cy;
|
|
|
//判断是否进入子流程
|
if (bpz && bpz.type == "subProcess") {
|
//说明进入在子流程中
|
if (_that.parentElem == null || _that.parentElem.id != bpz.id) {
|
//表示新的入到一个子流程中
|
if (_that.linein.length > 0) {
|
//如果含有线段,则必须提示,因为进入新的空间,旧的空间中的线段需要删除
|
$.messager.confirm('再次确认', '该结束节点进入子流程会删除原来的线段,还要继续进入吗?', function (r) {
|
if (!r) {
|
|
_that.elementbox.attr({"x": startX, "y": startY}); //不能落下的地方就返回
|
} else {
|
_that.render(cx, cy, bpzcenter);
|
|
}
|
})
|
} else {
|
//没有线段
|
_that.render(cx, cy, bpzcenter);
|
}
|
}
|
} else if (bpz == null) {
|
if (_that.parentElem != null) {
|
//原来在小空间中
|
if (_that.linein.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(cx, cy, bpzcenter);
|
}
|
})
|
} else {
|
//没有出小空间
|
|
_that.render(cx, cy, bpzcenter);
|
}
|
} else {
|
//没有线段
|
|
_that.render(cx, cy, bpzcenter);
|
}
|
} else {
|
//原来在大空间中
|
_that.render(cx, cy, bpzcenter);
|
}
|
}
|
|
} else {
|
this.attr({"x": startX, "y": startY}); //不能落下的地方就返回
|
}
|
dropStatus = false;
|
|
return false;
|
|
});
|
} else if (this.completeState == 1 || this.completeState == 2) {
|
|
this.element.mouseover(function (e) {
|
$("[id*=divshow_]").hide();
|
var wheight = e.view.innerHeight; //屏幕大小
|
var wheight2 = Math.floor(wheight / 2);//屏幕大小的一半
|
var name = "divshow_" + _that.id;
|
if ($("#" + name).length == 0) {
|
//创建
|
if (e.pageY <= wheight2) {
|
var str = "<div id='" + name + "' class='show' style='left:" + (e.pageX + 0) + "px; top:" + (e.pageY + 0) + "px;'><p class='title'>" + _that.getText() + "</p><div class='con' style='max-height:" + wheight2 + "px'>";
|
} else {
|
var str = "<div id='" + name + "' class='show' style='left:" + (e.pageX + 0) + "px; bottom:" + (wheight - e.pageY + 0) + "px;'><p class='title'>" + _that.getText() + "</p><div class='con' style='max-height:" + wheight2 + "px'>";
|
}
|
|
if (_that.completeState == 1) {
|
|
str += "<h4 class='yi'>已办理</h4>";
|
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
|
|
$.each(_that.content.activityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>办理时间</strong><span>" + el.time + "</span></p><p><strong>办理意见</strong><span>" + el.advice + "</span></p>";
|
})
|
}
|
} else if (_that.completeState == 2) {
|
|
if (_that.content.waitActivityUsers && _that.content.waitActivityUsers.length > 0) {
|
str += "<h4 class='zhengzai'>正在办理</h4>";
|
$.each(_that.content.waitActivityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>开始时间</strong><span>" + el.time + "</span></p>";
|
})
|
}
|
|
if (_that.content.activityUsers && _that.content.activityUsers.length > 0) {
|
str += "<h4 class='yi'>已办理</h4>";
|
$.each(_that.content.activityUsers, function (i, el) {
|
str += "<p><strong>办理人员</strong><span>" + el.name + "</span><strong>办理时间</strong><span>" + el.time + "</span></p><p><strong>办理意见</strong><span>" + el.advice + "</span></p>";
|
})
|
}
|
|
|
}
|
|
str += "</div></div>";
|
|
$("#" + _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 = $("<div class='resizehandle1' style='left:" + (this.bbox.x - this.bmargin - 10 - this.flow.getScrollx()) + "px; top:" + (this.bbox.y - this.bmargin - 10 + this.flow._DEFALUTS_.dy - this.flow.getScrolly()) + "px;'></div>");
|
$("#" + this.flow._DEFALUTS_.id).append(this.$elementctrl1);
|
|
this.$elementctrl4 = $("<div class='resizehandle4' style='left:" + (this.bbox.x - this.bmargin + this.bbox.width + 8 - this.flow.getScrollx()) + "px; top:" + (this.bbox.y - this.bmargin + this.bbox.height + 8 + this.flow._DEFALUTS_.dy - this.flow.getScrolly()) + "px;'></div>");
|
$("#" + 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;
|
});
|