From 6e10d3ad6e5b26daa6cad865bbca0eb326dfd54b Mon Sep 17 00:00:00 2001 From: wbccb Date: Tue, 7 Nov 2023 20:52:46 +0800 Subject: [PATCH] fix: prevent node without anchors using InsertNodeInPolyline(#1077) --- packages/core/src/model/edge/BaseEdgeModel.ts | 28 ++++++++++++++++--- .../NotAllowConnectRect.mjs | 15 ++++++++++ .../insert-node-in-polyline/index.html | 4 +-- .../examples/insert-node-in-polyline/index.js | 8 +++++- .../src/insert-node-in-polyline/index.ts | 14 ++++++++++ 5 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 packages/extension/examples/insert-node-in-polyline/NotAllowConnectRect.mjs diff --git a/packages/core/src/model/edge/BaseEdgeModel.ts b/packages/core/src/model/edge/BaseEdgeModel.ts index 8fe4db7f3..539675109 100644 --- a/packages/core/src/model/edge/BaseEdgeModel.ts +++ b/packages/core/src/model/edge/BaseEdgeModel.ts @@ -240,8 +240,10 @@ class BaseEdgeModel implements IBaseModel { /** * 内部方法,计算两个节点相连是起点位置 */ - getBeginAnchor(sourceNode, targetNode): Point { - let position; + getBeginAnchor(sourceNode, targetNode): Point | undefined { + // https://github.com/didi/LogicFlow/issues/1077 + // 可能拿到的sourceAnchors为空数组,因此position可能返回为undefined + let position: Point | undefined; let minDistance; const sourceAnchors = getAnchors(sourceNode); sourceAnchors.forEach((anchor) => { @@ -260,8 +262,10 @@ class BaseEdgeModel implements IBaseModel { /** * 内部方法,计算两个节点相连是终点位置 */ - getEndAnchor(targetNode): Point { - let position; + getEndAnchor(targetNode): Point | undefined { + // https://github.com/didi/LogicFlow/issues/1077 + // 可能拿到的targetAnchors为空数组,因此position可能返回为undefined + let position: Point | undefined; let minDistance; const targetAnchors = getAnchors(targetNode); targetAnchors.forEach((anchor) => { @@ -474,6 +478,14 @@ class BaseEdgeModel implements IBaseModel { setAnchors(): void { if (!this.sourceAnchorId || !this.startPoint) { const anchor = this.getBeginAnchor(this.sourceNode, this.targetNode); + if (!anchor && (!this.startPoint || !this.sourceAnchorId)) { + // https://github.com/didi/LogicFlow/issues/1077 + // 当用户自定义getDefaultAnchor(){return []}时,表示:不显示锚点,也不允许其他节点连接到此节点 + // 此时拿到的anchor=undefined,下面会直接报错 + throw new Error( + '无法获取beginAnchor,请检查anchors相关逻辑,anchors不能为空', + ); + } if (!this.startPoint) { this.startPoint = { x: anchor.x, @@ -486,6 +498,14 @@ class BaseEdgeModel implements IBaseModel { } if (!this.targetAnchorId || !this.endPoint) { const anchor = this.getEndAnchor(this.targetNode); + if (!anchor && (!this.endPoint || !this.targetAnchorId)) { + // https://github.com/didi/LogicFlow/issues/1077 + // 当用户自定义getDefaultAnchor(){return []}时,表示:不显示锚点,也不允许其他节点连接到此节点 + // 此时拿到的anchor=undefined,下面会直接报错 + throw new Error( + '无法获取endAnchor,请检查anchors相关逻辑,anchors不能为空', + ); + } if (!this.endPoint) { this.endPoint = { x: anchor.x, diff --git a/packages/extension/examples/insert-node-in-polyline/NotAllowConnectRect.mjs b/packages/extension/examples/insert-node-in-polyline/NotAllowConnectRect.mjs new file mode 100644 index 000000000..246d3d2b5 --- /dev/null +++ b/packages/extension/examples/insert-node-in-polyline/NotAllowConnectRect.mjs @@ -0,0 +1,15 @@ + +class NotAllowConnectRectModel extends RectNodeModel { + getDefaultAnchor () { + return []; + } +} +class NotAllowConnectRectView extends RectNode { + +} + +export default { + type: "not-allow-connect", + view: NotAllowConnectRectView, + model: NotAllowConnectRectModel +}; diff --git a/packages/extension/examples/insert-node-in-polyline/index.html b/packages/extension/examples/insert-node-in-polyline/index.html index 8a0f471f6..d8cfbfae3 100644 --- a/packages/extension/examples/insert-node-in-polyline/index.html +++ b/packages/extension/examples/insert-node-in-polyline/index.html @@ -38,7 +38,7 @@ -
+
不允许连接的rect
@@ -48,6 +48,6 @@ - + diff --git a/packages/extension/examples/insert-node-in-polyline/index.js b/packages/extension/examples/insert-node-in-polyline/index.js index 100f73da1..64ceeebd4 100644 --- a/packages/extension/examples/insert-node-in-polyline/index.js +++ b/packages/extension/examples/insert-node-in-polyline/index.js @@ -1,3 +1,5 @@ +import NotAllowConnectRect from './NotAllowConnectRect.mjs'; + window.onload = function () { const lf = new LogicFlow({ container: document.querySelector('#app'), @@ -6,11 +8,15 @@ window.onload = function () { size: 20, }, }); + lf.register(NotAllowConnectRect); + lf.on('connection:not-allowed', ({ data, msg }) => { + console.error('connection:not-allowed的原因是', msg); + }); lf.render(); // 初始化拖入功能 document.querySelector('#rect').addEventListener('mousedown', () => { lf.dnd.startDrag({ - type: 'rect', + type: 'not-allow-connect', }); }); document.querySelector('#circle').addEventListener('mousedown', () => { diff --git a/packages/extension/src/insert-node-in-polyline/index.ts b/packages/extension/src/insert-node-in-polyline/index.ts index 46544e3ca..28af37bbf 100644 --- a/packages/extension/src/insert-node-in-polyline/index.ts +++ b/packages/extension/src/insert-node-in-polyline/index.ts @@ -97,6 +97,20 @@ class InsertNodeInPolyline { insetNode(nodeData): void { const { edges } = this._lf.graphModel; const nodeModel = this._lf.getNodeModelById(nodeData.id); + + // fix: https://github.com/didi/LogicFlow/issues/1077 + // 参照https://github.com/didi/LogicFlow/issues/454=>当getDefaultAnchor(){return []}表示:不显示锚点,也不允许其他节点连接到此节点 + // 当getDefaultAnchor=[],直接阻止下面进行edges的截断插入node相关逻辑 + const anchorArray = nodeModel.getDefaultAnchor(); + const isNotAllowConnect = !anchorArray || anchorArray.length === 0; + if (isNotAllowConnect) { + this._lf.graphModel.eventCenter.emit(EventType.CONNECTION_NOT_ALLOWED, { + data: nodeData, + msg: '自定义类型节点不显示锚点,也不允许其他节点连接到此节点', + }); + return; + } + for (let i = 0; i < edges.length; i++) { // eslint-disable-next-line max-len const { crossIndex, crossPoints } = isNodeInSegment(