如何使用 mxGraph 将一条边分成两条?
How to branch one edge into two using mxGraph?
我没有找到将一条边连接到另一条边的支持,因此现在我添加了一个 T 形件作为顶点,用于将一条边分支成两条边:
现在我希望能够将一个边的终端拖放到另一个边上,然后自动创建并连接一个 T 型件。作为第一步,我考虑在 mxEdgeHandler
中编辑(或者更确切地说是扩展)getPreviewTerminalState
,以便在将终点拖过目标边缘时突出显示目标边缘。然而,这感觉很老套,因为我自然不想干扰库本身深处的功能。
无论如何,这是正确的起点吗?我只需要一点指导。谢谢!
好吧,现在我已经找到了一个我可以接受的解决方案,它使 T 型件过时了。如果有人也偶然发现了这个问题,我的解决方案如下所示:
// set edges as valid targets
var graphIsValidTarget = mxGraph.prototype.isValidTarget;
Graph.prototype.isValidTarget = function(cell) {
return (cell && cell.edge) || graphIsValidTarget.apply(this, arguments);
};
// mark edge if another edge's terminal point is dragged over it
var edgeHandlerGetPreviewTerminalState = mxEdgeHandler.prototype.getPreviewTerminalState;
mxEdgeHandler.prototype.getPreviewTerminalState = function(me) {
let ret = edgeHandlerGetPreviewTerminalState.apply(this, arguments);
let edge = me.getCell();
if (edge && edge.edge && this.graph.getSelectionCell() !== edge) {
let state = this.graph.view.getState(edge);
this.marker.setCurrentState(state, me, this.marker.validColor);
ret = state;
} else if (ret == null && this.marker && (!this.error || (this.error && this.error === ''))) {
this.marker.reset();
}
return ret;
};
// snap to edge's midpoint
var graphViewGetFloatingTerminalPoint = mxGraphView.prototype.getFloatingTerminalPoint;
mxGraphView.prototype.getFloatingTerminalPoint = function(edge, start, end, source) {
let res = null;
if (start.edge) {
res = this.graph.getEdgeMidPoint(start);
} else {
res = graphViewGetFloatingTerminalPoint.apply(this, arguments);
}
return res;
};
// returns midpoint of an edge
Graph.prototype.getEdgeMidPoint = function(edge) {
let ret = null;
if (edge && edge.edge) {
let points = this.view.getState(edge).absolutePoints;
let minX = points[0].x < points[1].x ? points[0].x : points[1].x;
let maxX = minX === points[0].x ? points[1].x : points[0].x;
let minY = points[0].y < points[1].y ? points[0].y : points[1].y;
let maxY = minY === points[0].y ? points[1].y : points[0].y;
ret = new mxPoint(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2);
}
return ret;
}
我没有找到将一条边连接到另一条边的支持,因此现在我添加了一个 T 形件作为顶点,用于将一条边分支成两条边:
现在我希望能够将一个边的终端拖放到另一个边上,然后自动创建并连接一个 T 型件。作为第一步,我考虑在 mxEdgeHandler
中编辑(或者更确切地说是扩展)getPreviewTerminalState
,以便在将终点拖过目标边缘时突出显示目标边缘。然而,这感觉很老套,因为我自然不想干扰库本身深处的功能。
无论如何,这是正确的起点吗?我只需要一点指导。谢谢!
好吧,现在我已经找到了一个我可以接受的解决方案,它使 T 型件过时了。如果有人也偶然发现了这个问题,我的解决方案如下所示:
// set edges as valid targets
var graphIsValidTarget = mxGraph.prototype.isValidTarget;
Graph.prototype.isValidTarget = function(cell) {
return (cell && cell.edge) || graphIsValidTarget.apply(this, arguments);
};
// mark edge if another edge's terminal point is dragged over it
var edgeHandlerGetPreviewTerminalState = mxEdgeHandler.prototype.getPreviewTerminalState;
mxEdgeHandler.prototype.getPreviewTerminalState = function(me) {
let ret = edgeHandlerGetPreviewTerminalState.apply(this, arguments);
let edge = me.getCell();
if (edge && edge.edge && this.graph.getSelectionCell() !== edge) {
let state = this.graph.view.getState(edge);
this.marker.setCurrentState(state, me, this.marker.validColor);
ret = state;
} else if (ret == null && this.marker && (!this.error || (this.error && this.error === ''))) {
this.marker.reset();
}
return ret;
};
// snap to edge's midpoint
var graphViewGetFloatingTerminalPoint = mxGraphView.prototype.getFloatingTerminalPoint;
mxGraphView.prototype.getFloatingTerminalPoint = function(edge, start, end, source) {
let res = null;
if (start.edge) {
res = this.graph.getEdgeMidPoint(start);
} else {
res = graphViewGetFloatingTerminalPoint.apply(this, arguments);
}
return res;
};
// returns midpoint of an edge
Graph.prototype.getEdgeMidPoint = function(edge) {
let ret = null;
if (edge && edge.edge) {
let points = this.view.getState(edge).absolutePoints;
let minX = points[0].x < points[1].x ? points[0].x : points[1].x;
let maxX = minX === points[0].x ? points[1].x : points[0].x;
let minY = points[0].y < points[1].y ? points[0].y : points[1].y;
let maxY = minY === points[0].y ? points[1].y : points[0].y;
ret = new mxPoint(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2);
}
return ret;
}