@logicflow/extension 2.0.16 → 2.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logicflow/extension",
3
- "version": "2.0.16",
3
+ "version": "2.0.18",
4
4
  "description": "LogicFlow Extensions",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -20,7 +20,7 @@
20
20
  "author": "Logicflow-Team",
21
21
  "license": "Apache-2.0",
22
22
  "peerDependencies": {
23
- "@logicflow/core": "2.0.12"
23
+ "@logicflow/core": "2.0.13"
24
24
  },
25
25
  "dependencies": {
26
26
  "@antv/hierarchy": "^0.6.11",
@@ -31,7 +31,7 @@
31
31
  "preact": "^10.17.1",
32
32
  "rangy": "^1.3.1",
33
33
  "vanilla-picker": "^2.12.3",
34
- "@logicflow/core": "2.0.12"
34
+ "@logicflow/core": "2.0.13"
35
35
  },
36
36
  "devDependencies": {
37
37
  "less": "^4.1.1",
@@ -1,5 +1,5 @@
1
- import LogicFlow, { BaseNodeModel } from '@logicflow/core'
2
- import { concat } from 'lodash-es'
1
+ import LogicFlow, { BaseEdgeModel, BaseNodeModel } from '@logicflow/core'
2
+ import { uniqBy, concat } from 'lodash-es'
3
3
 
4
4
  // 后续并入FlowPath
5
5
  const getPath = (id: string, lf: LogicFlow) => {
@@ -99,7 +99,7 @@ export class Highlight {
99
99
  this.enable = enable
100
100
  }
101
101
 
102
- setMode(mode: IMode) {
102
+ public setMode(mode: IMode) {
103
103
  this.mode = mode
104
104
  }
105
105
 
@@ -119,11 +119,14 @@ export class Highlight {
119
119
  model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id])
120
120
  model.targetNode.updateStyles(this.tempStyles[model.targetNode.id])
121
121
  }
122
+ this.lf.emit('highlight:single', {
123
+ data: model,
124
+ })
122
125
  }
123
126
 
124
127
  private highlightNeighbours(id: string) {
125
128
  const model = this.lf.getModelById(id)
126
-
129
+ let relateElements: (BaseNodeModel | BaseEdgeModel)[] = []
127
130
  if (model?.BaseType === 'node') {
128
131
  // 高亮节点
129
132
  model.updateStyles(this.tempStyles[id])
@@ -135,19 +138,41 @@ export class Highlight {
135
138
  concat(incomingEdges, outgoingEdges).forEach((edge) => {
136
139
  edge.updateStyles(this.tempStyles[edge.id])
137
140
  })
141
+ relateElements = uniqBy(
142
+ concat(
143
+ relateElements,
144
+ incomingNodes,
145
+ outgoingNodes,
146
+ incomingEdges,
147
+ outgoingEdges,
148
+ ),
149
+ 'id',
150
+ )
138
151
  } else if (model?.BaseType === 'edge') {
139
152
  // 高亮边及对应的节点
140
153
  model.updateStyles(this.tempStyles[id])
141
154
  model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id])
142
155
  model.targetNode.updateStyles(this.tempStyles[model.targetNode.id])
156
+ relateElements = [model.sourceNode, model.targetNode]
143
157
  }
158
+ this.lf.emit('highlight:neighbours', {
159
+ data: model,
160
+ relateElements,
161
+ })
144
162
  }
145
163
 
146
164
  private highlightPath(id: string) {
147
165
  const path = getPath(id, this.lf)
166
+ const relateElements: any[] = []
148
167
  path.forEach((_id) => {
168
+ const elementModel = this.lf.getModelById(_id)
149
169
  // 高亮路径上所有的边和节点
150
- this.lf.getModelById(_id)?.updateStyles(this.tempStyles[_id])
170
+ elementModel?.updateStyles(this.tempStyles[_id])
171
+ relateElements.push(elementModel)
172
+ })
173
+ this.lf.emit('highlight:path', {
174
+ data: this.lf.getModelById(id),
175
+ relateElements,
151
176
  })
152
177
  }
153
178
 
@@ -1,8 +1,13 @@
1
1
  import LogicFlow from '@logicflow/core'
2
+ import { cloneDeep } from 'lodash-es'
2
3
 
3
4
  import Position = LogicFlow.Position
4
5
  import PointTuple = LogicFlow.PointTuple
5
6
 
7
+ export interface SelectionConfig {
8
+ exclusiveMode?: boolean
9
+ }
10
+
6
11
  export class SelectionSelect {
7
12
  static pluginName = 'selectionSelect'
8
13
  private container?: HTMLElement
@@ -13,15 +18,25 @@ export class SelectionSelect {
13
18
  private disabled = true
14
19
  private isWholeNode = true
15
20
  private isWholeEdge = true
21
+ exclusiveMode = false // 框选独占模式:true 表示只能进行框选操作,false 表示可以同时进行其他画布操作
16
22
  // 用于区分选区和点击事件
17
23
  private mouseDownInfo: {
18
24
  x: number
19
25
  y: number
20
26
  time: number
21
27
  } | null = null
28
+ // 记录原始的 stopMoveGraph 设置
29
+ private originalStopMoveGraph:
30
+ | boolean
31
+ | 'horizontal'
32
+ | 'vertical'
33
+ | [number, number, number, number] = false
22
34
 
23
- constructor({ lf }: LogicFlow.IExtensionProps) {
35
+ constructor({ lf, options }: LogicFlow.IExtensionProps) {
24
36
  this.lf = lf
37
+
38
+ this.exclusiveMode = (options?.exclusiveMode as boolean) ?? false
39
+
25
40
  // TODO: 有没有既能将方法挂载到lf上,又能提供类型提示的方法?
26
41
  lf.openSelectionSelect = () => {
27
42
  this.openSelectionSelect()
@@ -29,46 +44,119 @@ export class SelectionSelect {
29
44
  lf.closeSelectionSelect = () => {
30
45
  this.closeSelectionSelect()
31
46
  }
47
+ // 新增切换独占模式的方法
48
+ lf.setSelectionSelectMode = (exclusive: boolean) => {
49
+ this.setExclusiveMode(exclusive)
50
+ }
51
+ // 绑定方法的 this 上下文
52
+ this.handleMouseDown = this.handleMouseDown.bind(this)
53
+ this.draw = this.draw.bind(this)
54
+ this.drawOff = this.drawOff.bind(this)
32
55
  }
33
56
 
34
57
  render(_: LogicFlow, domContainer: HTMLElement) {
35
58
  this.container = domContainer
36
59
  }
37
60
 
38
- onToolContainerMouseDown = (e: MouseEvent) => {
39
- // 避免在其他插件元素上点击时开启选区
40
- if (e.target !== this.container) {
41
- return
61
+ /**
62
+ * 清理选区状态
63
+ */
64
+ private cleanupSelectionState() {
65
+ // 清理当前的选区状态
66
+ if (this.wrapper) {
67
+ this.wrapper.oncontextmenu = null
68
+ if (this.container && this.wrapper.parentNode === this.container) {
69
+ this.container.removeChild(this.wrapper)
70
+ }
71
+ this.wrapper = undefined
42
72
  }
43
- this.mouseDownInfo = {
44
- x: e.clientX,
45
- y: e.clientY,
46
- time: Date.now(),
73
+ this.startPoint = undefined
74
+ this.endPoint = undefined
75
+ this.mouseDownInfo = null
76
+
77
+ // 移除事件监听
78
+ document.removeEventListener('mousemove', this.draw)
79
+ document.removeEventListener('mouseup', this.drawOff)
80
+ }
81
+
82
+ /**
83
+ * 切换框选模式
84
+ * @param exclusive 是否为独占模式。true 表示只能进行框选操作,false 表示可以同时进行其他画布操作
85
+ */
86
+ setExclusiveMode(exclusive: boolean = false) {
87
+ if (this.exclusiveMode === exclusive) return
88
+
89
+ this.cleanupSelectionState()
90
+ this.exclusiveMode = exclusive
91
+ if (this.container && !this.disabled) {
92
+ // 切换事件监听方式
93
+ this.removeEventListeners()
94
+ this.addEventListeners()
47
95
  }
48
- const lf = this.lf
49
- const domContainer = this.container
50
- if (!domContainer) {
51
- return
96
+ }
97
+
98
+ private addEventListeners() {
99
+ if (!this.container) return
100
+
101
+ if (this.exclusiveMode) {
102
+ // 独占模式:监听 container 的 mousedown 事件
103
+ this.container.style.pointerEvents = 'auto'
104
+ this.container.addEventListener('mousedown', this.handleMouseDown)
105
+ } else {
106
+ // 非独占模式:监听画布的 blank:mousedown 事件
107
+ this.container.style.pointerEvents = 'none'
108
+ // 使用实例方法而不是箭头函数,这样可以正确移除事件监听
109
+ this.lf.on('blank:mousedown', this.handleBlankMouseDown)
52
110
  }
53
- if (this.disabled) {
54
- return
111
+ }
112
+
113
+ private removeEventListeners() {
114
+ if (this.container) {
115
+ this.container.style.pointerEvents = 'none'
116
+ this.container.removeEventListener('mousedown', this.handleMouseDown)
55
117
  }
56
- // 禁用右键框选,修复可能导致画布出现多个框选框不消失的问题,见https://github.com/didi/LogicFlow/issues/985
118
+ // 移除 blank:mousedown 事件监听
119
+ this.lf.off('blank:mousedown', this.handleBlankMouseDown)
120
+ }
121
+
122
+ /**
123
+ * 处理画布空白处鼠标按下事件(非独占模式)
124
+ */
125
+ private handleBlankMouseDown = ({ e }: { e: MouseEvent }) => {
126
+ this.handleMouseDown(e)
127
+ }
128
+
129
+ /**
130
+ * 处理鼠标按下事件
131
+ */
132
+ private handleMouseDown(e: MouseEvent) {
133
+ if (!this.container || this.disabled) return
134
+
135
+ // 禁用右键框选
57
136
  const isRightClick = e.button === 2
58
- if (isRightClick) {
59
- return
137
+ if (isRightClick) return
138
+ // 清理之前可能存在的选区状态
139
+ this.cleanupSelectionState()
140
+ // 记录鼠标按下时的位置和时间
141
+ this.mouseDownInfo = {
142
+ x: e.clientX,
143
+ y: e.clientY,
144
+ time: Date.now(),
60
145
  }
146
+
147
+ // 记录原始设置并临时禁止画布移动
148
+ this.originalStopMoveGraph = this.lf.getEditConfig().stopMoveGraph!
149
+ this.lf.updateEditConfig({
150
+ stopMoveGraph: true,
151
+ })
152
+
61
153
  const {
62
154
  domOverlayPosition: { x, y },
63
- } = lf.getPointByClient(e.clientX, e.clientY)
64
- this.startPoint = {
65
- x,
66
- y,
67
- }
68
- this.endPoint = {
69
- x,
70
- y,
71
- }
155
+ } = this.lf.getPointByClient(e.clientX, e.clientY)
156
+
157
+ this.startPoint = { x, y }
158
+ this.endPoint = { x, y }
159
+
72
160
  const wrapper = document.createElement('div')
73
161
  wrapper.className = 'lf-selection-select'
74
162
  wrapper.oncontextmenu = function prevent(ev: MouseEvent) {
@@ -76,28 +164,13 @@ export class SelectionSelect {
76
164
  }
77
165
  wrapper.style.top = `${this.startPoint.y}px`
78
166
  wrapper.style.left = `${this.startPoint.x}px`
79
- domContainer.appendChild(wrapper)
167
+ this.container?.appendChild(wrapper)
80
168
  this.wrapper = wrapper
169
+
81
170
  document.addEventListener('mousemove', this.draw)
82
171
  document.addEventListener('mouseup', this.drawOff)
83
172
  }
84
173
 
85
- onToolContainerMouseUp = (e: MouseEvent) => {
86
- if (this.mouseDownInfo) {
87
- const { x, y, time } = this.mouseDownInfo
88
- const now = Date.now()
89
- // 用 mouseDown 和 mouseUp 的位置偏移及时间间隔来判断是否是点击事件
90
- const isClickEvent =
91
- Math.abs(e.clientX - x) < 10 &&
92
- Math.abs(e.clientY - y) < 10 &&
93
- now - time < 100
94
- if (isClickEvent) {
95
- this.lf.clearSelectElements()
96
- }
97
- this.mouseDownInfo = null
98
- }
99
- }
100
-
101
174
  /**
102
175
  * 设置选中的灵敏度
103
176
  * @param isWholeEdge 是否要边的起点终点都在选区范围才算选中。默认true
@@ -118,11 +191,8 @@ export class SelectionSelect {
118
191
  if (!this.container) {
119
192
  return
120
193
  }
121
- this.mouseDownInfo = null
122
- this.container.addEventListener('mousedown', this.onToolContainerMouseDown)
123
- this.container.addEventListener('mouseup', this.onToolContainerMouseUp)
124
- // 取消点击事件的穿透,只让 ToolOverlay 接收事件,避免与图形元素的事件冲突
125
- this.container.style.pointerEvents = 'auto'
194
+ this.cleanupSelectionState()
195
+ this.addEventListeners()
126
196
  this.open()
127
197
  }
128
198
 
@@ -133,13 +203,18 @@ export class SelectionSelect {
133
203
  if (!this.container) {
134
204
  return
135
205
  }
136
- this.container.style.pointerEvents = 'none'
137
- this.mouseDownInfo = null
138
- this.container.removeEventListener(
139
- 'mousedown',
140
- this.onToolContainerMouseDown,
141
- )
142
- this.container.removeEventListener('mouseup', this.onToolContainerMouseUp)
206
+ // 如果还有未完成的框选,先触发 drawOff 完成框选
207
+ if (this.wrapper && this.startPoint && this.endPoint) {
208
+ // 记录上一次的结束点,用于触发 mouseup 事件
209
+ const lastEndPoint = cloneDeep(this.endPoint)
210
+ const lastEvent = new MouseEvent('mouseup', {
211
+ clientX: lastEndPoint.x,
212
+ clientY: lastEndPoint.y,
213
+ })
214
+ this.drawOff(lastEvent)
215
+ }
216
+ this.cleanupSelectionState()
217
+ this.removeEventListeners()
143
218
  this.close()
144
219
  }
145
220
 
@@ -173,16 +248,37 @@ export class SelectionSelect {
173
248
  }
174
249
  }
175
250
  }
176
- private drawOff = () => {
251
+ private drawOff = (e: MouseEvent) => {
252
+ // 处理鼠标抬起事件
253
+ // 首先判断是否是点击,如果是,则清空框选
254
+ if (this.mouseDownInfo) {
255
+ const { x, y, time } = this.mouseDownInfo
256
+ const isClick =
257
+ Math.abs(e.clientX - x) < 5 &&
258
+ Math.abs(e.clientY - y) < 5 &&
259
+ Date.now() - time < 200
260
+ if (isClick) {
261
+ this.lf.clearSelectElements()
262
+ this.cleanupSelectionState()
263
+ return
264
+ }
265
+ }
266
+
267
+ const curStartPoint = cloneDeep(this.startPoint)
268
+ const curEndPoint = cloneDeep(this.endPoint)
177
269
  document.removeEventListener('mousemove', this.draw)
178
- document.removeEventListener('mouseup', this.drawOff)
179
- if (this.wrapper) {
180
- this.wrapper.oncontextmenu = null
181
- this.container?.removeChild(this.wrapper)
270
+ if (!this.exclusiveMode) {
271
+ document.removeEventListener('mouseup', this.drawOff)
182
272
  }
183
- if (this.startPoint && this.endPoint) {
184
- const { x, y } = this.startPoint
185
- const { x: x1, y: y1 } = this.endPoint
273
+
274
+ // 恢复原始的 stopMoveGraph 设置
275
+ this.lf.updateEditConfig({
276
+ stopMoveGraph: this.originalStopMoveGraph,
277
+ })
278
+
279
+ if (curStartPoint && curEndPoint) {
280
+ const { x, y } = curStartPoint
281
+ const { x: x1, y: y1 } = curEndPoint
186
282
  // 返回框选范围,左上角和右下角的坐标
187
283
  const lt: PointTuple = [Math.min(x, x1), Math.min(y, y1)]
188
284
  const rb: PointTuple = [Math.max(x, x1), Math.max(y, y1)]
@@ -192,6 +288,13 @@ export class SelectionSelect {
192
288
  })
193
289
  // 选区太小的情况就忽略
194
290
  if (Math.abs(x1 - x) < 10 && Math.abs(y1 - y) < 10) {
291
+ if (this.wrapper) {
292
+ this.wrapper.oncontextmenu = null
293
+ if (this.container && this.wrapper.parentNode === this.container) {
294
+ this.container.removeChild(this.wrapper)
295
+ }
296
+ this.wrapper = undefined
297
+ }
195
298
  return
196
299
  }
197
300
  const elements = this.lf.graphModel.getAreaElement(
@@ -203,6 +306,13 @@ export class SelectionSelect {
203
306
  )
204
307
  const { dynamicGroup, group } = this.lf.graphModel
205
308
  const nonGroupedElements: typeof elements = []
309
+ const selectedElements = this.lf.getSelectElements()
310
+ // 同时记录节点和边的ID
311
+ const selectedIds = new Set([
312
+ ...selectedElements.nodes.map((node) => node.id),
313
+ ...selectedElements.edges.map((edge) => edge.id),
314
+ ])
315
+
206
316
  elements.forEach((element) => {
207
317
  // 如果节点属于分组,则不选中节点,此处兼容旧版 Group 插件
208
318
  if (group) {
@@ -219,15 +329,39 @@ export class SelectionSelect {
219
329
  return
220
330
  }
221
331
  }
332
+ // 在独占模式下,如果元素已经被选中,则取消选中
333
+ if (this.exclusiveMode && selectedIds.has(element.id)) {
334
+ this.lf.deselectElementById(element.id)
335
+ return
336
+ }
337
+
338
+ // 非独占模式下,或者元素未被选中时,选中元素
222
339
  this.lf.selectElementById(element.id, true)
223
340
  nonGroupedElements.push(element)
224
341
  })
342
+ // 重置起始点和终点
343
+ // 注意:这两个值必须在触发closeSelectionSelect方法前充值,否则会导致独占模式下元素无法选中的问题
344
+ this.startPoint = undefined
345
+ this.endPoint = undefined
346
+ // 如果有选中的元素,触发 selection:drop 事件
347
+ if (nonGroupedElements.length > 0) {
348
+ this.lf.emit('selection:drop', { e })
349
+ }
350
+ // 触发 selection:selected 事件
225
351
  this.lf.emit('selection:selected', {
226
352
  elements: nonGroupedElements,
227
353
  leftTopPoint: lt,
228
354
  rightBottomPoint: rb,
229
355
  })
230
356
  }
357
+
358
+ if (this.wrapper) {
359
+ this.wrapper.oncontextmenu = null
360
+ if (this.container && this.wrapper.parentNode === this.container) {
361
+ this.container.removeChild(this.wrapper)
362
+ }
363
+ this.wrapper = undefined
364
+ }
231
365
  }
232
366
 
233
367
  private open() {
@@ -236,7 +236,6 @@ export class DynamicGroup {
236
236
  const group = this.getGroupByBounds(bounds, node)
237
237
  if (group) {
238
238
  const isAllowAppendIn = group.isAllowAppendIn(node)
239
- console.log('isAllowAppendIn', isAllowAppendIn)
240
239
  if (isAllowAppendIn) {
241
240
  group.addChild(node.id)
242
241
  // 建立节点与 group 的映射关系放在了 group.addChild 触发的事件中,与直接调用 addChild 的行为保持一致
@@ -256,7 +255,6 @@ export class DynamicGroup {
256
255
  data: groupData,
257
256
  childId,
258
257
  }: CallbackArgs<'group:add-node'>) => {
259
- console.log('group:add-node', groupData)
260
258
  this.nodeGroupMap.set(childId, groupData.id)
261
259
  }
262
260
 
@@ -310,7 +308,6 @@ export class DynamicGroup {
310
308
  if (!isAllowAppendIn) return
311
309
 
312
310
  this.activeGroup = targetGroup
313
- console.log('this.activeGroup', this.activeGroup)
314
311
  this.activeGroup.setAllowAppendChild(true)
315
312
  }
316
313
  }
@@ -439,7 +436,6 @@ export class DynamicGroup {
439
436
  }
440
437
 
441
438
  onGraphRendered = ({ data }: CallbackArgs<'graph:rendered'>) => {
442
- console.log('data', data)
443
439
  forEach(data.nodes, (node) => {
444
440
  if (node.children) {
445
441
  forEach(node.children, (childId) => {
@@ -517,9 +513,6 @@ export class DynamicGroup {
517
513
  }
518
514
  })
519
515
 
520
- // TODO: 确认,递归的方式,是否将所有嵌套的边数据都有返回
521
- console.log('allRelatedEdges -->>', allRelatedEdges)
522
-
523
516
  // 1. 判断每一条边的开始节点、目标节点是否在 Group 中
524
517
  const edgesInnerGroup = filter(allRelatedEdges, (edge) => {
525
518
  return (
@@ -684,7 +677,6 @@ export class DynamicGroup {
684
677
  })
685
678
 
686
679
  graphModel.dynamicGroup = this
687
-
688
680
  lf.on('node:add,node:drop,node:dnd-add', this.onNodeAddOrDrop)
689
681
  lf.on('selection:drop', this.onSelectionDrop)
690
682
  lf.on('node:delete', this.removeNodeFromGroup)
@@ -694,8 +686,6 @@ export class DynamicGroup {
694
686
  lf.on('node:mousemove', this.onNodeMove)
695
687
  lf.on('graph:rendered', this.onGraphRendered)
696
688
 
697
- lf.on('graph:updated', ({ data }) => console.log('data', data))
698
-
699
689
  lf.on('group:add-node', this.onGroupAddNode)
700
690
 
701
691
  // https://github.com/didi/LogicFlow/issues/1346
@@ -739,8 +729,6 @@ export class DynamicGroup {
739
729
  forEach(edgesInnerGroup, (edge) => {
740
730
  this.createEdge(edge, nodeIdMap, distance)
741
731
  })
742
-
743
- console.log('selectedEdges --->>>', selectedEdges)
744
732
  forEach(selectedEdges, (edge) => {
745
733
  elements.edges.push(this.createEdge(edge, nodeIdMap, distance))
746
734
  })
@@ -321,7 +321,6 @@ export class GroupNodeModel extends RectResizeModel {
321
321
  getData() {
322
322
  const data = super.getData()
323
323
  data.children = []
324
- console.log('this.children', this.children)
325
324
  this.children.forEach((childId) => {
326
325
  const model = this.graphModel.getNodeModelById(childId)
327
326
  if (model && !model.virtual) {
package/src/style/raw.ts CHANGED
@@ -193,6 +193,10 @@ export const content = `@import url('medium-editor/dist/css/medium-editor.min.cs
193
193
  background: #eaedf2;
194
194
  border: 1px solid #93a3b4;
195
195
  }
196
+ .lf-mini-map .lf-graph {
197
+ width: 100% !important;
198
+ height: 100% !important;
199
+ }
196
200
  .lf-mini-map-graph {
197
201
  position: relative;
198
202
  overflow: hidden;
@@ -3,6 +3,7 @@ import LogicFlow, {
3
3
  twoPointDistance,
4
4
  BaseNodeModel,
5
5
  BaseEdgeModel,
6
+ isInNode,
6
7
  } from '@logicflow/core'
7
8
  import { assign, isEmpty, isEqual, isNil, isFinite, reduce } from 'lodash-es'
8
9
 
@@ -78,10 +79,37 @@ export class ProximityConnect {
78
79
  },
79
80
  )
80
81
  // 节点、锚点拖拽结束事件
81
- this.lf.graphModel.eventCenter.on('node:drop,anchor:dragend', () => {
82
+ this.lf.graphModel.eventCenter.on('node:drop', () => {
82
83
  if (!this.enable) return
83
84
  this.handleDrop()
84
85
  })
86
+ // 锚点拖拽需要单独判断一下当前拖拽终点是否在某个锚点上,如果是,就不触发插件的连线,以免出现创建了两条连线的问题,表现见 issue 2140
87
+ this.lf.graphModel.eventCenter.on('anchor:dragend', ({ e, edgeModel }) => {
88
+ if (!this.enable) return
89
+ const {
90
+ canvasOverlayPosition: { x: eventX, y: eventY },
91
+ } = this.lf.graphModel.getPointByClient({
92
+ x: e.clientX,
93
+ y: e.clientY,
94
+ })
95
+
96
+ if (edgeModel && this.virtualEdge) {
97
+ const { id: virtualEdgeId } = this.virtualEdge as BaseEdgeModel
98
+ const { targetNodeId } = edgeModel as BaseEdgeModel
99
+ const targetNodeModel =
100
+ this.lf.graphModel.getNodeModelById(targetNodeId)
101
+ if (
102
+ targetNodeModel &&
103
+ isInNode({ x: eventX, y: eventY }, targetNodeModel)
104
+ ) {
105
+ // 如果当前拖拽点在锚点上,就不触发插件的连线
106
+ this.lf.deleteEdge(virtualEdgeId)
107
+ return
108
+ }
109
+ }
110
+
111
+ this.handleDrop()
112
+ })
85
113
  }
86
114
 
87
115
  // 节点拖拽动作
@@ -346,6 +374,7 @@ export class ProximityConnect {
346
374
  endPoint,
347
375
  pointsList,
348
376
  } = this.virtualEdge
377
+ this.lf.deleteEdge(this.virtualEdge.id)
349
378
  this.lf.addEdge({
350
379
  type,
351
380
  sourceNodeId,
@@ -356,7 +385,6 @@ export class ProximityConnect {
356
385
  endPoint,
357
386
  pointsList,
358
387
  })
359
- this.lf.deleteEdge(this.virtualEdge.id)
360
388
  }
361
389
 
362
390
  // 设置虚拟边样式
@@ -369,7 +397,6 @@ export class ProximityConnect {
369
397
 
370
398
  // 设置连线阈值
371
399
  public setThresholdDistance(distance: number) {
372
- console.log('distance', distance)
373
400
  if (!isFinite(distance)) return
374
401
  this.thresholdDistance = distance
375
402
  }