html部分
组节点坐标随机生成
<!DOCTYPE html>
<html>
<head>
<title>组节点</title>
<meta charset="UTF-8">
<script type="text/javascript">
mxBasePath = '../src';
</script>
<script type="text/javascript" src="../src/js/mxClient.js"></script>
<script type="text/javascript">
function main(container)
{
if (!mxClient.isBrowserSupported())
{
mxUtils.error('Browser is not supported!', 200, false);
}
else
{
var nodeWidth = 160;
var nodeHeight = 130;
var minMargin = 150;
var defaultRadiu = Math.max(nodeWidth / 2, nodeHeight / 2);
var width = document.getElementById('graphContainer').offsetWidth;
var _w = width-10;
var defaultVertexStyleStr = 'fillColor=#339966;labelBorderColor=none;fontColor=#FFFFFF;labelBackgroundColor=none;strokeColor=none';
var defaultEdgeStyleStr = 'fontColor=#000;';
var levelTemp1 = ['a1','a2','a3'];
var levelTemp2 = ['b1','b2','b3'];
var topSpace = 90;
var prefixStr = 'nodeid';
var nodeData = [];
function RandomCoord(obj){
this.dWidth = obj.width;
this.dHeight = obj.height;
this.fix = obj.fix || false;
this.minMargin = obj.minMargin;
this.minRadius = obj.minRadius || 30;
this.total = obj.total || 10;
this.coordArray = [];
}
RandomCoord.prototype.check = function(x,y,r){
return !(x+r>this.dWidth || x-r<0||y+r>this.dHeight||y-r<0||x<r);
};
RandomCoord.prototype.getR = function(x,y){
if(this.coordArray.length == 0){
return true;
}
var lenArr = this.coordArray.map(function(c){
let _x = c.x-x;
let _y = c.y-y;
return Math.floor(Math.sqrt(Math.pow(_x, 2) + Math.pow(_y, 2))) - c.r;
});
var minCircleLen = Math.min.apply(null, lenArr);
let tempR = minCircleLen - this.minMargin;
let bool = tempR >= this.minRadius;
if(bool){
return tempR;
}else{
return false;
}
}
RandomCoord.prototype.createOneCircle = function () {
let x, y, r;
let createCircleTimes = 0;
while (true){
createCircleTimes ++;
x = Math.floor(Math.random()*this.dWidth);
y = Math.floor(Math.random()*this.dHeight);
let TR = this.getR(x, y);
if(!TR){
continue;
}else{
r = defaultRadiu;
}
if(this.check(x,y,r) || createCircleTimes > 200){
if(this.total == 1){
this.coordArray.push({x:x,y:y,r:r});
}
break;
}
}
this.check(x,y,r) && this.coordArray.push({x:x,y:y,r:r});
}
RandomCoord.prototype.init = function(){
let n = 0;
let that = this;
while(this.coordArray.length < this.total){
this.coordArray = [];
let i=0;
while(this.coordArray.length < this.total){
this.createOneCircle();
i++;
if(i>=100){
break;
}
}
n++;
if(n>=100){
break;
}
}
}
RandomCoord.prototype.getPositionCoords = function(){
return this.coordArray;
};
var _n = [];
var _tempStatusArr= [];
var totalAttach = 3;
var linesData = [];
var graphType = 1; // 1-折线 2-直线
var model = new mxGraphModel();
var graph = new mxGraph(document.getElementById('graphContainer'), model);
// 节点是否可以改变大小
graph.setCellsResizable(false);
// 是否拖动节点
mxGraphHandler.prototype.setMoveEnabled(true);
// 是否可以移动连线
graph.setCellsLocked(false);
graph.setConnectable(false);
// 整体移动
graph.setPanning(true);
graph.panningHandler.useLeftButtonForPanning = true;
graph.setHtmlLabels(true);
graph.setTooltips(true);
// 设置两个节点是否可以建立多个连接
graph.setMultigraph(true);
graph.foldingEnabled = false; // 关闭组折叠功能
graph.isSelectedEdge(false); // 添加自定义设置,线不可选中且不可移动
if(graphType == 1){
graph.lineType = 'brokenLine';
}else{
graph.lineType = 'straightLine';
}
graph.isCellFoldable = function(cell, collapse){
var childCount = this.model.getChildCount(cell);
for(var i=0;i<childCount;i++){
var child = this.model.getChildAt(cell, i);
var geo = this.getCellGeometry(child);
if(geo != null && geo.relative){
return false;
}
}
return childCount > 0;
};
function getRelativePosition(state, dx, dy){
if(state != null){
var model = graph.getModel();
var geo = model.getGeometry(state.cell);
if(geo != null && geo.relative && !model.isEdge(state.cell)){
var parent = model.getParent(state.cell);
if(model.isVertex(parent)){
var pstate = graph.view.getState(parent);
if(pstate!=null){
var x = state.x+dx;
var y = state.y+dy;
x = (x-pstate.x)/pstate.width;
y = (y-pstate.y)/pstate.height;
var scaleW = geo.width / pstate.width;
var scaleH = geo.height / pstate.height;
if(x<=0){x=0}
if(y<=0){y=0}
if(x>=1||(x+scaleW>=1)){x=1}
if(y>=1||(y+scaleH>=1)){y=1}
return new mxPoint(x, y);
}
}
}
}
return null;
}
graph.translateCell = function(cell, dx, dy){
var rel = getRelativePosition(this.view.getState(cell), dx*graph.view.scale, dy*graph.view.scale);
if(rel != null){
var geo = this.model.getGeometry(cell);
if(geo != null && geo.relative){
geo = geo.clone();
geo.x = rel.x;
geo.y = rel.y;
// 重置x
geo.offset.x = 0;
if(rel.x == 1){
geo.offset.x -= geo.width;
}
// 重置y
geo.offset.y = 0;
if(rel.y == 1){
geo.offset.y -= geo.height;
}
this.model.setGeometry(cell, geo);
}
}
else{
mxGraph.prototype.translateCell.apply(this, arguments);
}
};
graph.graphHandler.getDelta = function(me){
var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY());
var delta = new mxPoint(point.x - this.first.x, point.y - this.first.y);
return delta;
};
graph.graphHandler.shouldRemoveCellsFromParent = function (parent, cells, evt) {
console.log(cells);
return cells.length == 0&&!cells[0].geometry.relative&&mxGraphHandler.prototype.shouldRemoveCellsFromParent.apply(this, arguments);
};
var parent = graph.getDefaultParent();
var layout = new mxCustomEdgeLayout(graph);
var layoutMgr = new mxLayoutManager(graph);
layoutMgr.getLayout = function(cell){
if(cell.getChildCount() > 0){
return layout;
}
};
var style = graph.getStylesheet().getDefaultEdgeStyle();
// 折线
if(graphType == 1){
style[mxConstants.STYLE_ROUNDED] = true; // false:直角 true:圆角
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.BlineConnector;
graph.alternateEdgeStyle = 'elbow=vertical';
}else{ // 直线
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.straightLineConnector;
}
var nodelistData = [
{
id:'b1',text:'食品',x:0,y:0,width:0,height:0,level:1,parents:parent.id,
parentID:null,childs:[
{id:'n11',text:'苹果',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b1',level:2},
{id:'n12',text:'草莓',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b1',level:2},
{id:'n13',text:'菠萝',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b1',level:2},
]
},
{
id:'b2',text:'家具',x:0,y:0,width:0,height:0,level:1,parents:parent.id,
parentID:null,childs:[
{id:'n21',text:'柜子',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b2',level:2},
{id:'n22',text:'沙发',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b2',level:2},
{id:'n23',text:'躺椅',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b2',level:2},
]
},
{
id:'b3',text:'家电',x:0,y:0,width:0,height:0,level:1,parents:parent.id,
parentID:null,childs:[
{id:'n31',text:'冰箱',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b3',level:2},
{id:'n32',text:'洗衣机',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b3',level:2},
{id:'n33',text:'空调',x:0,y:0,width:nodeWidth,height:nodeHeight,parentID:'b3',level:2},
]
}
];
for(var i=0;i<nodelistData.length;i++){
var totalNode = nodelistData[i].childs.length;
var tempFun = null;
if(totalNode > 0){
var height = Math.ceil(Math.sqrt(totalNode)*(Math.sqrt(defaultRadiu)*Math.sqrt(totalNode))*Math.sqrt(minMargin));
tempFun = new RandomCoord({total: totalNode, minMargin:minMargin, height:height, width:_w-100-defaultRadiu});
tempFun.init();
var tempCoords = tempFun.getPositionCoords();
for(var c = 0;c<totalNode;c++){
nodelistData[i].childs[c].x = tempCoords[c].x;
nodelistData[i].childs[c].y = tempCoords[c].y;
}
}
}
for(var j=0;j<nodelistData.length;j++){
nodeData.push(nodelistData[j]);
if(nodelistData[j].childs.length > 0){
for(var k=0;k<nodelistData[j].childs.length;k++){
nodeData.push(nodelistData[j].childs[k]);
}
}
}
linesData = [
{originalId: prefixStr+'n11', targetId:prefixStr+'n31', id: 'l1', text:'苹果-l1'},
{originalId: prefixStr+'n12', targetId:prefixStr+'n31', id: 'l2', text:'草莓-l2'},
{originalId: prefixStr+'n13', targetId:prefixStr+'n31', id: 'l3', text:'菠萝-l3'},
{originalId: prefixStr+'n22', targetId:prefixStr+'n32', id: 'l4', text:'沙发+洗衣机'},
];
function createNodeItem(arr){
if(!arr)return;
var arrLen = arr.length;
for(var i=0;i<arrLen;i++){
var doc = mxUtils.createXmlDocument();
var itemElem = doc.createElement('relation');
itemElem.setAttribute('text', arr[i].text);
itemElem.setAttribute('id', arr[i].id);
itemElem.setAttribute('level', arr[i].level);
itemElem.setAttribute('parents', arr[i].parents);
itemElem.setAttribute('parentID', arr[i].parentID);
itemElem.setAttribute('isSelected', arr[i].level == 2 ?'true':'false');
if(arr[i].parentID == null){
arr[i].width = _w;
var layer0StyleStr = '';
if(arr[i].id == 'b1'){
layer0StyleStr = layer0StyleStr+'fillColor=none;';
arr[i].preNode = null;
}else if(arr[i].id == 'b2'){
layer0StyleStr = layer0StyleStr+'fillColor=none;';
arr[i].preNode = 'b1';
}else if(arr[i].id == 'b3'){
layer0StyleStr = layer0StyleStr+'fillColor=none;';
arr[i].preNode = 'b2';
}
if(arr[i].childs.length == 0){
arr[i].height = 200;
}
if(i==0){
var vertex = graph.insertVertex(
parent, arr[i].id, itemElem, 0, 0,
arr[i].width, arr[i].height,
layer0StyleStr+'align=left;strokeColor=#cccccc;'
);
}else {
var _previousId = levelTemp2[levelTemp2.indexOf(arr[i].id) - 1];
model.getCell(_previousId).geometry.height = model.getCell(_previousId).geometry.height + 90;
var _y = model.getCell(_previousId).geometry.y + model.getCell(_previousId).geometry.height + 20;
var vertex = graph.insertVertex(
parent, arr[i].id, itemElem, 0, _y,
arr[i].width, arr[i].height,
layer0StyleStr+'align=left;strokeColor=#cccccc;'
);
}
_n.push(vertex);
}else{
itemElem.setAttribute('parents', parent.id);
var node = graph.insertVertex(
model.getCell(arr[i].parentID), prefixStr+arr[i].id,
itemElem,
arr[i].x || 0,
arr[i].y || 0,
arr[i].width || nodeWidth,
arr[i].height || nodeHeight,
defaultVertexStyleStr+(arr[i].style || '')
);
_n.push(node);
}
}
createLinks(linesData);
}
function createLinks(arr){
var linkArrLen = arr.length;
var tempObj1 = {};
// 统计单个节点的线的总数
for(var i=0;i<linkArrLen;i++){
// 折线
if(graphType == 1){
if(tempObj1[arr[i].originalId] != undefined && tempObj1[arr[i].originalId].totalEdges != undefined){
tempObj1[arr[i].originalId].totalEdges ++;
}else{
tempObj1[arr[i].originalId] = {};
tempObj1[arr[i].originalId].totalEdges = 1;
}
}
if(tempObj1[arr[i].targetId] != undefined && tempObj1[arr[i].targetId].totalEdges!=undefined){
tempObj1[arr[i].targetId].totalEdges ++;
}else{
tempObj1[arr[i].targetId] = {};
tempObj1[arr[i].targetId].totalEdges = 1;
}
}
// 计算space
for(var k in tempObj1){
var tempCell = model.getCell(k);
var cellGeo = model.getGeometry(tempCell);
var cellGeoClone = cellGeo.clone();
for(var c in tempObj1[k]){
cellGeoClone[c] = tempObj1[k][c];
cellGeoClone.space = Math.ceil(Math.min(cellGeoClone.height, cellGeoClone.width) / (cellGeoClone[c] + totalAttach));
model.setGeometry(tempCell, cellGeoClone);
}
}
for(var j=0;j<linkArrLen;j++){
var doc = mxUtils.createXmlDocument();
var itemLink = doc.createElement('relation');
itemLink.setAttribute('text', arr[j].text);
var linkItem = graph.insertEdge(
parent, arr[j].id, arr[j].text,
model.getCell(arr[j].originalId),
model.getCell(arr[j].targetId), ''
);
}
}
// 修改节点显示的信息
// if(graph.lineType == 1){
graph.convertValueToString = function(cell){
if(cell.vertex){
var div = document.createElement('div');
if(mxUtils.isNode(cell.value)){
var text = cell.getAttribute('text');
var level = cell.getAttribute('level');
if(level == 1){
div.innerHTML = "<div class='celllabelcon reset-celllabelcon'>"+text+"</div>";
}else{
div.innerHTML = "<div class='celllabelcon'>"+text+"</div>";
}
return div;
}
}
return cell.value;
}
// }
// 鼠标移入时显示节点和与线label
graph.getTooltip=function(state){
var cell = state.cell;
var model = this.getModel();
var text = cell.getAttribute('text');
if(model.isEdge(cell)){
if(text != 'null' && text != undefined){
return '<div style="color:#db3338">'+text+'</div>';
}
}
}
window.cellMoved = false;
graph.getModel().beginUpdate();
try{
createNodeItem(nodeData);
}finally{
graph.cellsOrdered(_n, null);
graph.getModel().endUpdate();
}
var edges = [],highlightFnArr = [],highlight=null;
graph.addListener(mxEvent.FIRE_MOUSE_EVENT, function(sender, evt){
var evtName = evt.getProperty('eventName');
var me = evt.getProperty('event');
if(evtName==mxEvent.MOUSE_DOWN && me.state != undefined){
var cell = me.state.cell;
if(cell.children){
removedHighlight(); // 删除高亮
}
if(cell!=null&&cell!=undefined&&model.isVertex(cell)&&!cell.children){
removedHighlight();
edges = cell.edges;
setHighlight(edges);
if(graphType == 1){
window.cellMoved = true; // 判断当前是否有移动的节点,true:是 false:否
var edgelist = cell.edges;
if(edgelist&&edgelist.length > 0){
var len = edgelist.length;
for(var i=0;i<len;i++){
var _e = edgelist[i];
var _eGeo = model.getGeometry(_e);
var _eGeoClone = _eGeo.clone();
var src = graph.view.getVisibleTerminal(_e, true);
var trg = graph.view.getVisibleTerminal(_e, false);
var srcGeo = model.getGeometry(src);
var trgGeo = model.getGeometry(trg);
var srcGeoClone = srcGeo.clone();
var trgGeoClone = trgGeo.clone();
// 先删除节点上的统计数
deleteEdgeGeometry(src, srcGeoClone, false, _eGeoClone);
// 先删除节点上的统计数
deleteEdgeGeometry(trg, trgGeoClone, false, _eGeoClone);
// 再删除线上的统计数
deleteEdgeGeometry(_e, _eGeoClone, true);
}
}
}
}
}
});
// 设置线高亮
function setHighlight(arr){
if(!arr)return;
for(var i =0;i<arr.length;i++){
var edge = arr[i];
highlightFn(edge, graph);
}
}
// 删除线高亮
function removedHighlight(){
if(highlightFnArr.length > 0){
for(var j=0;j<highlightFnArr.length;j++){
highlightFnArr[j].destroy();
highlight=null;
}
highlightFnArr = [];
edges = [];
}
}
function highlightFn(cell, graph){
highlight = new mxCellHighlight(graph, '#00FF00', 1);
highlight.spacing = -1;
highlight.highlight(graph.view.getState(graph.model.getCell(cell.id)));
highlightFnArr.push(highlight);
}
if(graphType == 1){
graph.addListener(mxEvent.CELLS_MOVED, function(cells, evt){
var cell = evt.getProperty('cells')[0];
var dx = evt.getProperty('dx');
var dy = evt.getProperty('dy');
window.cellMoved = true;
delete window.edgesLabelMap;
if(model.isVertex(cell)){
var edgelist = cell.edges;
if(edgelist&&edgelist.length>0){
for(var i=0;i<edgelist.length;i++){
var _e = edgelist[i];
var _eGeo = model.getGeometry(_e);
var _eGeoClone = _eGeo.clone();
var src = graph.view.getVisibleTerminal(_e, true);
var trg = graph.view.getVisibleTerminal(_e, false);
var srcGeo = model.getGeometry(src);
var trgGeo = model.getGeometry(trg);
var srcGeoClone = srcGeo.clone();
var trgGeoClone = trgGeo.clone();
// 先删除节点上的统计数
deleteEdgeGeometry(src, srcGeoClone, false, _eGeoClone);
// 先删除节点上的统计数
deleteEdgeGeometry(trg, trgGeoClone, false, _eGeoClone);
// 再删除线上的统计数
deleteEdgeGeometry(_e, _eGeoClone, true);
}
}
}
});
// 删除已存在的统计线数据
function deleteEdgeGeometry(_e, _eGeoClone, flag, edgeGeo){
if(flag){
if(_eGeoClone.left){
delete _eGeoClone.left;
}
if(_eGeoClone.right){
delete _eGeoClone.right;
}
}else{
if(_eGeoClone.left == edgeGeo.left){
delete _eGeoClone.left;
}
if(_eGeoClone.right == edgeGeo.right){
delete _eGeoClone.right;
}
}
model.setGeometry(_e, _eGeoClone);
}
}else{
graph.addListener(mxEvent.CELLS_MOVED, function(cells, evt){
delete window.edgesLabelCountMap;
});
}
}
}
</script>
</head>
<body onload="main(document.getElementById('graphContainer'))">
<div id="graphContainer"
style="position:relative;overflow:hidden;width:100%;height:100%;background:url('editors/images/grid.gif');cursor:default;">
</div>
</body>
</html>
以下为需要修改的js部分
路径:javascript\src\js\mxClient.js
// 引入自定义的线构造函数
mxClient.include(mxClient.basePath+'/js/layout/mxCustomEdgeLayout.js');
路径:javascript\src\js\layout\mxCustomEdgeLayout.js(此文件为新增文件)
function mxCustomEdgeLayout(graph)
{
mxGraphLayout.call(this, graph);
};
mxCustomEdgeLayout.prototype = new mxGraphLayout();
mxCustomEdgeLayout.prototype.constructor = mxCustomEdgeLayout;
mxCustomEdgeLayout.prototype.spacing = 12;
mxCustomEdgeLayout.prototype.execute = function(parent)
{
var lookup = this.findParallels(parent);
this.graph.model.beginUpdate();
try
{
for (var i in lookup)
{
var parallels = lookup[i];
this.layout(parallels);
}
}
finally
{
this.graph.model.endUpdate();
}
};
mxCustomEdgeLayout.prototype.findParallels = function(parent)
{
var model = this.graph.getModel();
var lookup = [];
var childCount = model.getChildCount(parent);
for (var i = 0; i < childCount; i++)
{
var child = model.getChildAt(parent, i);
if (!this.isEdgeIgnored(child))
{
var id = this.getEdgeId(child);
if (id != null)
{
if (lookup[id] == null)
{
lookup[id] = [];
}
lookup[id].push(child);
}
}
}
return lookup;
};
mxCustomEdgeLayout.prototype.getEdgeId = function(edge)
{
var view = this.graph.getView();
var src = view.getVisibleTerminal(edge, true);
var trg = view.getVisibleTerminal(edge, false);
if (src != null && trg != null)
{
src = mxObjectIdentity.get(src);
trg = mxObjectIdentity.get(trg);
return (src > trg) ? trg + '-' + src : src + '-' + trg;
}
return null;
};
mxCustomEdgeLayout.prototype.layout = function(parallels)
{
var edge = parallels[0];
var view = this.graph.getView();
var model = this.graph.getModel();
var src = model.getGeometry(view.getVisibleTerminal(edge, true));
var trg = model.getGeometry(view.getVisibleTerminal(edge, false));
var srcCell = view.getVisibleTerminal(edge,true);
var trgCell = view.getVisibleTerminal(edge,false);
var srcParent = model.getCell(srcCell.parent.id);
var trgParent = model.getCell(trgCell.parent.id);
var srcParentGeo = model.getGeometry(srcParent);
var trgParentGeo = model.getGeometry(trgParent);
if(srcCell.parent.id != trgCell.parent.id){
src.x = src.x + srcParentGeo.x;
src.y = src.y + srcParentGeo.y;
trg.x = trg.x + trgParentGeo.x;
trg.y = trg.y + trgParentGeo.y;
}
if (src == trg)
{
var x0 = src.x + src.width + this.spacing;
var y0 = src.y + src.height / 2;
for (var i = 0; i < parallels.length; i++)
{
this.route(parallels[i], x0, y0);
x0 += this.spacing;
}
}
else if (src != null && trg != null)
{
var scx = src.x + src.width / 2;
var scy = src.y + src.height / 2;
var tcx = trg.x + trg.width / 2;
var tcy = trg.y + trg.height / 2;
var dx = tcx - scx;
var dy = tcy - scy;
var len = Math.sqrt(dx * dx + dy * dy); // 对角线
if (len > 0)
{
var x0 = scx + dx / 2;
var y0 = scy + dy / 2;
var nx = dy * this.spacing / len;
var ny = dx * this.spacing / len;
x0 += nx * (parallels.length - 1) / 2;
y0 -= ny * (parallels.length - 1) / 2;
// 当线超出父级宽度或小于0时的异常处理
if(x0 > 0){
var _space = (parallels.length -1)*nx;
var totalSpace = Math.abs(_space) + x0;
if(totalSpace > srcParentGeo.width){
var cur0 = totalSpace-srcParentGeo.width-nx; // 还要少一个间隙的空间
x0 -= cur0;
}
}else{
x0 = 10;
}
for (var i = 0; i < parallels.length; i++)
{
this.route(parallels[i], x0, y0);
x0 -= nx;
y0 += ny;
}
if(srcCell.parent.id != trgCell.parent.id){
src.x = src.x - srcParentGeo.x;
src.y = src.y - srcParentGeo.y;
trg.x = trg.x - trgParentGeo.x;
trg.y = trg.y - trgParentGeo.y;
}
}
}
};
mxCustomEdgeLayout.prototype.route = function(edge, x, y)
{
if (this.graph.isCellMovable(edge))
{
this.setEdgePoints(edge, [new mxPoint(x, y)]);
}
};
路径:javascript\src\js\view\mxEdgeStyle.js
// 折线
BlineConnector: function(state, source, target, points, result){
var pt = (points!=null&&points.length>0)?points[0]:null;
var vertical = false;
var horizontal = false;
if(source!=null && target!=null){
if(pt!=null){
var left = Math.min(source.x, target.x);
var right = Math.max(source.x+source.width, target.x + target.width);
var top = Math.min(source.y, target.y);
var bottom = Math.max(source.y+source.height, target.y+target.height);
pt = state.view.transformControlPoint(state, pt);
vertical = pt.y < top || pt.y > bottom;
horizontal = pt.x < left || pt.x > right;
}else{
var left = Math.max(source.x, target.x);
var right = Math.min(source.x+source.width, target.x + target.width);
vertical = left == right;
if(!vertical){
var top = Math.max(source.y, target.y);
var bottom = Math.min(source.y+source.height, target.y+target.height);
horizontal = top == bottom;
}
}
if(!horizontal && (vertical || state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL)){
// 水平
mxEdgeStyle.horizontalEdge(state, source, target, points, result);
}else{
// 垂直
mxEdgeStyle.verticalEdge(state, source, target, points, result);
}
}
},
// 折线-水平
horizontalEdge: function(state, source, target, points, result){},
// 折线-垂直
verticalEdge: function(state, source, target, points, result){
var view = state.view;
var model = view.graph.getModel();
var src = view.getVisibleTerminal(state.cell, true); // 源節點
var trg = view.getVisibleTerminal(state.cell, false); // 目標節點
var scale = state.view.scale;
var srcParent = model.getCell(src.parent.id);
var srcParentGeo = model.getGeometry(srcParent);
var trgParent = model.getCell(trg.parent.id);
var trgParentGeo = model.getCell(trgParent);
var srcg = model.getGeometry(src);
var trgg = model.getGeometry(trg);
var stateCell = model.getGeometry(state.cell);
var stateCellClone = stateCell.clone();
var srcGeo = srcg.clone();
var trgGeo = trgg.clone();
if(!window.cellMoved){
if(srcGeo.x < trgGeo.x){
if(points[0].x > (srcGeo.x + srcGeo.width)){
if(srcGeo.right != null){
srcGeo.right ++;
}else{
srcGeo.right = 1;
}
stateCellClone.right = srcGeo.right;
stateCellClone.rightId = src.id;
}
if(points[0].x < trgGeo.x){
if(trgGeo.left != null){
trgGeo.left ++;
}else{
trgGeo.left = 1;
}
stateCellClone.left = trgGeo.left;
stateCellClone.leftId = trg.id;
}
}else if(srcGeo.x > trgGeo.x){
if(points[0].x - srcParentGeo.x < srcGeo.x){
if(srcGeo.left != null){
srcGeo.left ++;
}else{
srcGeo.left = 1;
}
stateCellClone.left = srcGeo.left;
stateCellClone.leftId = src.id;
}
if(points[0].x - srcParentGeo.x > trgGeo.x+trgGeo.width){
if(trgGeo.right != null){
trgGeo.right ++;
}else{
trgGeo.right = 1;
}
stateCellClone.right = trgGeo.right;
stateCellClone.rightId = trg.id;
}
}
model.setGeometry(view.getVisibleTerminal(state.cell, true), srcGeo);
model.setGeometry(view.getVisibleTerminal(state.cell, false), trgGeo);
model.setGeometry(state.cell, stateCellClone);
}else{
if(srcGeo.x < trgGeo.x){
var _resultRight = [];
if(src.edges.length > 0){
for(var i=0;i<src.edges.length;i++){
var _e = src.edges[i];
if(_e.geometry.rightId == src.id){
_resultRight.push(_e.geometry.right);
}
}
}
var srcResult = getInsetEdgePosition(src.geometry.totalEdges, _resultRight, []);
if(srcResult.length > 0){
srcGeo.right = srcResult[0];
}else{
srcGeo.right = 1;
}
var _resultLeft = [];
if(trg.edges.length > 0){
for(var i=0;i<trg.edges.length;i++){
var _e = trg.edges[i];
if(_e.geometry.leftId == trg.id){
_resultLeft.push(_e.geometry.left);
}
}
}
var trgResult = getInsetEdgePosition(trg.geometry.totalEdges, _resultLeft, []);
if(trgResult.length > 0){
trgGeo.left = trgResult[0];
}else{
trgGeo.left = 1;
}
stateCellClone.right = srcGeo.right;
stateCellClone.left = trgGeo.left;
stateCellClone.rightId = src.id;
stateCellClone.leftId = trg.id;
}else{
var _resultLeft = [];
if(src.edges.length > 0){
for(var i=0;i<src.edges.length;i++){
var _e = src.edges[i];
if(_e.geometry.leftId == src.id){
_resultLeft.push(_e.geometry.left);
}
}
}
var srcResult = getInsetEdgePosition(src.geometry.totalEdges, _resultLeft, []);
if(srcResult.length > 0){
srcGeo.left = srcResult[0];
}else{
srcGeo.left = 1;
}
var _resultRight = [];
if(trg.edges.length > 0){
for(var i=0;i<trg.edges.length;i++){
var _e = trg.edges[i];
if(_e.geometry.rightId == trg.id){
_resultRight.push(_e.geometry.right);
}
}
}
var trgResult = getInsetEdgePosition(trg.geometry.totalEdges, _resultRight, []);
if(trgResult.length > 0){
trgGeo.right = trgResult[0];
}else{
trgGeo.right = 1;
}
stateCellClone.right = trgGeo.right;
stateCellClone.left = srcGeo.left;
stateCellClone.rightId = trg.id;
stateCellClone.leftId = src.id;
}
model.setGeometry(view.getVisibleTerminal(state.cell, true), srcGeo);
model.setGeometry(view.getVisibleTerminal(state.cell, false), trgGeo);
model.setGeometry(state.cell, stateCellClone);
}
// 返回當前節點左邊或右邊空缺的位置
function getInsetEdgePosition(total, arr, results){
for(var i =0;i<total+2;i++){
results.push(i+1);
}
if(arr.length > 0){
for(var j=0;j<arr.length;j++){
var index = results.indexOf(arr[j]);
if(index > -1){
results.splice(index, 1);
}
}
}
return results;
}
var pt = (points!=null&&points.length>0)?points[0] : null;
var pts = state.absolutePoints;
var p0 = pts[0];
var pe = pts[pts.length - 1 ];
if(pt!=null){
pt = view.transformControlPoint(state, pt);
}
if(p0!=null){
source = new mxCellState();
source.x = p0.x;
source.y = p0.y;
}
if(pe!=null){
target = new mxCellState();
target.x = pe.x;
target.y = pe.y;
}
if(source != null && target!=null){
var l = Math.max(source.x ,target.x);
var r = Math.min(source.x+source.width, target.x+target.width);
var x = (pt!=null)?pt.x : Math.round(r+(l-r)/2);
var y1 = view.getRoutingCenterY(source);
var y2 = view.getRoutingCenterY(target);
if(pt!=null){
if(pt.y>=source.y && pt.y <= source.y + source.height){
y1 = pt.y;
}
if(pt.y>=target.y && pt.y <= target.y + target.height){
y2 = pt.y;
}
}
if(!mxUtils.contains(target, x, y1) && !mxUtils.contains(source, x, y1)){
result.push(new mxPoint(x, y1));
}
if(!mxUtils.contains(target, x, y2) && !mxUtils.contains(source, x, y2)){
result.push(new mxPoint(x, y2));
}
// 計算當前線坐標
function setCoords(curLine, space, y, result){
if(curLine % 2 == 0){
result = y - Math.floor(space * (curLine / 2));
}else{
result = y + Math.floor(space * (Math.floor(curLine / 2)));
}
return result;
}
// 當線沒有拐點時(線為直線)
if(result.length == 1){
if(pt != null){
if(!mxUtils.contains(target, x, pt.y) && !mxUtils.contains(source, x, pt.y)){
result.push(new mxPoint(x, pt.y));
}
}else{
var t = Math.max(source.y, target.y);
var b = Math.min(source.y+source.height, target.y+target.height);
result.push(new mxPoint(x, t+(b-t)/2));
}
if(!result[1]) return;
result[0] = new mxPoint(0,0);
result[0].x = result[1].x;
if(source.y < target.y){
result[0].y = source.y+source.height;
}else{
result[0].y = source.y;
}
result[2] = new mxPoint(0,0);
result[2].x = result[1].x;
if(source.y < target.y){
result[2].y = target.y;
}else{
result[2].y = target.y+target.height;
}
}else{ // 折線
var curStateCell = model.getGeometry(state.cell);
var curSrcgeo = model.getGeometry(view.getVisibleTerminal(state.cell, true));
var curTrggeo = model.getGeometry(view.getVisibleTerminal(state.cell, false));
// 3段線, 4組坐標
if(result.length > 1){
if(result[1].x != result[2].x || result[1].y != result[2].y){
// 第一個坐標點
result[0] = new mxPoint(0,0);
if(points[0].x < curSrcgeo.x && points[0].x < curTrggeo.x){
var _x0 = source.x;
}else if(points[0].x > curSrcgeo.x && points[0].x > curTrggeo.x){
var _x0 = source.x+source.width;
}else{
if(points[0].x > curSrcgeo.x+curSrcgeo.width && points[0].x < curTrggeo.x){
var _x0 = source.x + source.width;
}else{
var _x0 = source.x;
}
}
result[0].x = _x0;
var _y0 = view.getRoutingCenterY(source);
if(source.x + source.width < target.x){
var curLine = curSrcgeo.right;
}else{
var curLine = curSrcgeo.left;
}
var _space = curSrcgeo.space * scale;
result[0].y = setCoords(curLine, _space, _y0, result[0].y);
result[1].y = result[0].y;
// 最後一個坐標點
result[3] = new mxPoint(0,0);
if(points[0].x < curSrcgeo.x && points[0].x < curTrggeo.x){
var _x3 = target.x;
}else if(points[0].x > curSrcgeo.x && points[0].x > curTrggeo.x){
var _x3 = target.x+target.width;
}else{
if(points[0].x > curSrcgeo.x+curSrcgeo.width && points[0].x < curTrggeo.x){
var _x3 = target.x;
}else{
var _x3 = target.x+target.width;
}
}
result[3].x = _x3;
var _y1 = view.getRoutingCenterY(target);
if(source.x + source.width < target.x){
var curLine = curTrggeo.left;
}else{
var curLine = curTrggeo.right;
}
var _space = curTrggeo.space * scale;
result[3].y = setCoords(curLine, _space, _y1, result[3].y);
result[2].y = result[3].y;
}else{
result[0] = new mxPoint(0,0);
if(source.x < target.x){
result[0].x = source.x + source.width;
}else{
result[0].x = source.x;
}
var _y0 = view.getRoutingCenterY(source);
if(source.x+source.width < target.x){
var curLine = curSrcgeo.right;
}else{
var curLine = curSrcgeo.left;
}
var _space = curSrcgeo.space * scale;
result[0].y = setCoords(curLine, _space, _y0, result[0].y);
result[1].y = result[0].y;
var minSpace = Math.min(curSrcgeo.space, curTrggeo.space) * scale;
result[1].x = setCoords(window.initNum, minSpace, result[1].x, result[1].x);
result[2].x = result[1].x;
result[3] = new mxPoint(0,0);
if(source.x < target.x){
result[3].x = target.x;
}else{
result[3].x = target.x + target.width;
}
var _y1 = view.getRoutingCenterY(target);
if(source.x + source.width < target.x){
var curLine = curTrggeo.left;
}else{
var curLine = curTrggeo.right;
}
var _space = curTrggeo.space * scale;
result[3].y = setCoords(curLine, _space, _y1, result[3].y);
result[2].y = result[3].y;
window.initNum ++; // 兩節點之間x軸一樣,每畫一次則加1
}
}else{ // 2段線, 3組坐標
if(source.x < target.x){
if(result[1].y > source.y && result[1].y < source.y+source.height){
if(source.y < target.y){
var curLine = curStateCell.right;
}else{
var curLine = curStateCell.left;
}
var _space = curSrcgeo.space*scale;
result[0] = new mxPoint(0,0);
var _x0 = source.x < target.x ? source.x+source.width : source.x;
result[0].x = _x0;
result[1].y = setCoords(curLine, _space, result[1].y, result[1].y);
result[0].y = result[1].y;
result[2] = new mxPoint(0,0);
result[2].x = result[1].x;
if(source.y < target.y){
result[2].y = target.y;
}else{
result[2].y = target.y+target.height;
}
}else {
if(source.x < target.x && source.y+srcParentGeo.y < source.y+srcParentGeo.y+source.height){
if(source.x < target.x){
var curLine = curStateCell.left;
}else{
var curLine = curStateCell.right;
}
var _space = curTrggeo.space * scale;
result[0] = new mxPoint(0,0);
result[0].x = result[1].x;
if(source.y < target.y){
result[0].y = source.y + source.height;
}else{
result[0].y = source.y;
}
result[2] = new mxPoint(0,0);
result[2].x = source.x < target.x ? target.x : target.x+target.width;
result[1].y = setCoords(curLine, _space, result[1].y, result[1].y);
result[2].y = result[1].y;
}
}
}else{
if(result[1].y > source.y && result[1].y < source.y + source.height){
if(source.x < target.x){
var curLine = curStateCell.right;
}else{
var curLine = curStateCell.left;
}
var _space = curSrcgeo.space * scale;
result[0] = new mxPoint(0,0);
var _x0 = source.x < target.x ? source.x+source.width : source.x;
result[0].x = _x0;
result[1].y = setCoords(curLine, _space, result[1].y, result[1].y);
result[0].y = result[1].y;
result[2] = new mxPoint(0,0);
result[2].x = result[1].x;
if(source.y < target.y){
result[2].y = target.y;
}else{
result[2].y = target.y+target.height;
}
}else{
if(source.x > target.x){
var curLine = curStateCell.right;
}else{
var curLine = curStateCell.left;
}
var _space = curTrggeo.space * scale;
result[0] = new mxPoint(0,0);
result[0].x = result[1].x;
if(source.y < target.y){
result[0].y = source.y+source.height;
}else{
result[0].y = source.y;
}
result[2] = new mxPoint(0,0);
result[2].x = source.x < target.x ? target.x : target.x+target.width;
result[1].y = setCoords(curLine, _space, result[1].y, result[1].y);
result[2].y = result[1].y;
}
}
}
}
}
},
// 直线
straightLineConnector: function(state, source, target, points, result) {
result = result ? result : [];
var view = state.view;
var model = view.graph.getModel();
var angle = Math.atan2((source.y-target.y), (source.x-target.x));
var theta = parseInt(angle*(180/Math.PI));
var spgeo = model.getGeometry(model.getCell(view.getVisibleTerminal(state.cell, true).parent.id));
var tpgeo = model.getGeometry(model.getCell(view.getVisibleTerminal(state.cell, false).parent.id));
var src = view.getVisibleTerminal(state.cell, true);
var srcgeo = model.getGeometry(src);
var srcgeoclone = srcgeo.clone();
var trg = view.getVisibleTerminal(state.cell, false);
var trggeo = model.getGeometry(trg);
var trggeoclone = trggeo.clone();
var stateCell = model.getGeometry(state.cell);
var sourceCX = source.getCenterX();
var sourceCY = source.getCenterY();
var stateCellClone = stateCell.clone();
var obj = {};
obj.sid = source.cell.id;
obj.tid = target.cell.id;
obj.sX = source.x;
obj.sY = source.y;
obj.sWidth = source.width;
obj.sHeight = source.height;
obj.spY = spgeo.y;
obj.tX = target.x;
obj.tY = target.y;
obj.tWidth = target.width;
obj.tHeight = target.height;
obj.tpY = tpgeo.y;
var trgSpace = model.getGeometry(view.getVisibleTerminal(state.cell, false)).space;
var start = 0;
obj.trgSpace = trgSpace;
var x2 = null;
var y2 = null;
function intervalSpace(sourceLength, index, space){
var resultNum = 0;
if(index){
if(index %2 ==0){
resultNum = intervalSpace(sourceLength, index-1, space) + space * index;
}else{
resultNum = intervalSpace(sourceLength, index-1, space) - space * index;
}
}else{
resultNum = sourceLength/2;
}
return resultNum;
}
function calculateCoords(){
var heightNum = intervalSpace(obj.tHeight, start, obj.trgSpace);
var widthNum = intervalSpace(obj.tWidth, start, obj.trgSpace);
x2 = obj.tX + Math.floor(widthNum);
y2 = obj.tY + Math.floor(heightNum);
if(theta < -90 || theta > 0 && theta < 90){
x2 = obj.tX + obj.tWidth - widthNum;
}
var leftLine = mxUtils.intersection(sourceCX, sourceCY, x2, y2, obj.tX, obj.tY, obj.tX, obj.tY+obj.tHeight);
var topLine = mxUtils.intersection(sourceCX, sourceCY, x2, y2, obj.tX, obj.tY, obj.tX+obj.tWidth, obj.tY);
var rightLine = mxUtils.intersection(sourceCX, sourceCY, x2, y2, obj.tX+obj.tWidth, obj.tY, obj.tX+obj.tWidth, obj.tY+obj.tHeight);
var bottomLine = mxUtils.intersection(sourceCX, sourceCY, x2, y2, obj.tX, obj.tY+obj.tHeight, obj.tX+obj.tWidth, obj.tY+obj.tHeight);
return leftLine || topLine || rightLine || bottomLine;
}
var intersection = calculateCoords();
function compareCoords (){
for (var i=0;i<trg.edges.length;i++){
var stateCellGeo = model.getGeometry(trg.edges[i]);
if(stateCellGeo.intersection){
if(intersection &&
((Math.ceil(intersection.x) == stateCellGeo.intersection.x && Math.ceil(intersection.y) == stateCellGeo.intersection.y) ||
((Math.floor(intersection.x) > stateCellGeo.intersection.x -1 && Math.floor(intersection.x) < stateCellGeo.intersection.x +1 ) &&
(Math.floor(intersection.y) > stateCellGeo.intersection.y-1 && Math.floor(intersection.y) < stateCellGeo.intersection.y+1)))
){
start ++;
intersection = calculateCoords();
compareCoords();
}
}
if(view.getVisibleTerminal(trg.edges[i], false) == src){
if(stateCellGeo.fintersection){
if(intersection &&
((Math.ceil(intersection.x) == stateCellGeo.fintersection.x && Math.ceil(intersection.y) == stateCellGeo.fintersection.y) ||
((Math.floor(intersection.x) > stateCellGeo.fintersection.x -1 && Math.floor(intersection.x) < stateCellGeo.fintersection.x +1 ) &&
(Math.floor(intersection.y) > stateCellGeo.fintersection.y-1 && Math.floor(intersection.y) < stateCellGeo.fintersection.y+1)))
){
start ++;
intersection = calculateCoords();
compareCoords();
}
}
}
}
}
compareCoords();
function getFromCoords(){
var fLeftLine = mxUtils.intersection( x2, y2, sourceCX, sourceCY, obj.sX, obj.sY, obj.sX, obj.sY+obj.sHeight);
var ftopLine = mxUtils.intersection(x2, y2, sourceCX, sourceCY, obj.sX, obj.sY, obj.sX+obj.sWidth, obj.sY);
var frightLine = mxUtils.intersection(x2, y2, sourceCX, sourceCY, obj.sX+obj.sWidth, obj.sY, obj.sX+obj.sWidth, obj.sY+obj.sHeight);
var fbottomLine = mxUtils.intersection(x2, y2, sourceCX, sourceCY, obj.sX, obj.sY+obj.sHeight, obj.sX+obj.sWidth, obj.sY+obj.sHeight);
return fLeftLine || ftopLine || frightLine || fbottomLine;
}
if(intersection){
var resultCoords = new mxPoint(Math.ceil(intersection.x), Math.ceil(intersection.y));
result.push(resultCoords);
stateCellClone.intersection = resultCoords;
stateCellClone.fintersection = getFromCoords();
model.setGeometry(state.cell, stateCellClone);
}
return result;
},
路径:javascript\src\js\view\mxGraph.js
// 添加线是否可移动初始化参数
mxGraph.prototype.isEdgeSelected = true;
// 设置线是否可移动
mxGraph.prototype.isSelectedEdge = function(val){
this.isEdgeSelected = val;
}
// 修改此方法,设置线及父节点不可选中且不可移动
mxGraph.prototype.setSelectionCell = function(cell)
{
// this.getSelectionModel().setCell(cell);
var model = this.view.graph.getModel();
var edgeIsSelected = cell.getAttribute('isSelected');
if((!this.isEdgeSelected && model.isEdge(cell)) || edgeIsSelected == 'false'){
this.clearSelection(); // 清除已选中的节点
this.removeSelectionCell(cell); // 不允许选中当前节点
this.cellsLocked = true; // 上锁
}else{
this.getSelectionModel().setCell(cell);
this.cellsLocked = false;
}
};
// 修改此方法
mxGraphView.prototype.getPoint = function(state, geometry)
{
var that = this;
var x = state.getCenterX();
var y = state.getCenterY();
var srcId = state.cell.source.id;
var trgId = state.cell.target.id;
var id = srcId+'+'+trgId;
var reversId = trgId+'+'+srcId;
var p0y = null;
var pey = null;
var p0x = null;
var pex = null;
var maxPY = null;
var minPY = null;
var maxPX = null;
var minPX = null;
// 直线需要重新判断当前id,把双向变成单向
if(that.graph.lineType == 'straightLine'){
if(window.edgesLabelCountMap && window.edgesLabelCountMap[id] != null){
id = id;
}
if(window.edgesLabelCountMap && window.edgesLabelCountMap[reversId] != null){
id = reversId;
}
}
// 折线
if(that.graph.lineType == 'brokenLine'){
if(window.edgesLabelMap && window.edgesLabelMap[id] != null){
id = id;
}
if(window.edgesLabelMap && window.edgesLabelMap[reversId] != null){
id = reversId;
}
}
// 判断是否为空对象
function isEmptyObject(obj){
for(var val in obj){
return false;
}
return true;
}
// 折线
if(that.graph.lineType == 'brokenLine'){
if(!window.edgesLabelMap){
window.edgesLabelMap = {};
window.edgesLabelMap[id] = {
counted: 1
}
}else{
if(window.edgesLabelMap[id] != null){
window.edgesLabelMap[id].counted ++;
}else{
window.edgesLabelMap[id] = {
counted: 1
}
}
}
}
// 直线
if(that.graph.lineType == 'straightLine'){
if(!window.edgesLabelCountMap){
window.edgesLabelCountMap = {};
window.edgesLabelCountMap[id] = {
counted : 0
}
}else{
if(window.edgesLabelCountMap[id] != null){
window.edgesLabelCountMap[id],counted ++;
}else{
window.edgesLabelCountMap[id] = {
counted : 0
}
}
}
}
if (state.segments != null && (geometry == null || geometry.relative))
{
var gx = (geometry != null) ? geometry.x / 2 : 0;
var pointCount = state.absolutePoints.length;
var dist = Math.round((gx + 0.5) * state.length);
var segment = state.segments[0];
var length = 0;
var index = 1;
while (dist >= Math.round(length + segment) && index < pointCount - 1)
{
length += segment;
segment = state.segments[index++];
}
var factor = (segment == 0) ? 0 : (dist - length) / segment;
var p0 = state.absolutePoints[index-1];
var pe = state.absolutePoints[index];
if (p0 != null && pe != null)
{
var gy = 0;
var offsetX = 0;
var offsetY = 0;
p0y = p0.y;
pey = pe.y;
p0x = p0.x;
pex = pe.x;
maxPY = Math.max(p0y, pey);
minPY = Math.min(p0y, pey);
maxPX = Math.max(p0x, pex);
minPX = Math.min(p0x, pex);
if (geometry != null)
{
gy = geometry.y;
var offset = geometry.offset;
if (offset != null)
{
offsetX = offset.x;
offsetY = offset.y;
}
}
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
var nx = (segment == 0) ? 0 : dy / segment;
var ny = (segment == 0) ? 0 : dx / segment;
x = p0.x + dx * factor + (nx * gy + offsetX) * this.scale;
y = p0.y + dy * factor - (ny * gy - offsetY) * this.scale;
}
if(that.graph.lineType=='brokenLine'){
if(!isEmptyObject(window.edgesLabelMap)){
function compareEdgeLabelPositionBL(){
if(window.edgesLabelMap[id].counted %2 == 0){
y = p0.y + (pe.y-p0.y) / 2 - 5*window.edgesLabelMap[id].counted;
}else{
y = p0.y + (pe.y-p0.y) / 2 + 5*window.edgesLabelMap[id].counted;
}
if(maxPY != null && minPY != null){
if(y<minPY || y>maxPY){
window.edgesLabelMap[id].counted = 1;
compareEdgeLabelPositionBL();
}
}
}
if(p0.x == pe.x && Math.abs(pe.y-p0.y) > 20){
compareEdgeLabelPositionBL();
}
}
}
if(that.graph.lineType=='straightLine'){
function compareEdgeLabelPositionSL(){
if(window.edgesLabelCountMap[id].counted % 2 == 0){
factor = (dist-10*window.edgesLabelCountMap[id].counted) / segment;
}else{
factor = (dist+10*window.edgesLabelCountMap[id].counted) / segment;
}
x = p0.x + dx * factor.toFixed(2) + (nx*gy+offsetX) * that.scale;
y = p0.y + dy * factor.toFixed(2) + (ny*gy+offsetY) * that.scale;
if(maxPY != null && minPY!=null && maxPX != null && minPX != null){
// 当最后坐标x大于当前线最大的x坐标||当最后坐标x小于当前线最小的x坐标||
// 当最后坐标y大于当前线最大的y坐标||当最后坐标y小于当前线最小的y坐标
if(y<minPY||y>maxPY || x<minPX || x > maxPX){
window.edgesLabelCountMap[id].counted = 0;
compareEdgeLabelPositionSL();
}
}
}
compareEdgeLabelPositionSL();
}
}
else if (geometry != null)
{
var offset = geometry.offset;
if (offset != null)
{
x += offset.x;
y += offset.y;
}
}
return new mxPoint(x, y);
};