@mx-sose-front/mx-sose-graph 1.1.8 → 1.1.9

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.
Files changed (52) hide show
  1. package/dist/assets/edgeWorker-b57ca007.js +2 -0
  2. package/dist/assets/edgeWorker-b57ca007.js.map +1 -0
  3. package/dist/index.d.ts +633 -30
  4. package/dist/index.esm.js +8728 -4734
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/index.umd.js +1 -1
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/style.css +1 -1
  9. package/package.json +1 -1
  10. package/src/components/Common/Tree.vue +451 -0
  11. package/src/components/Common/index.ts +2 -0
  12. package/src/components/DiagramListTooltip/DiagramListTooltip.vue +1 -2
  13. package/src/components/Edge/Edge.vue +172 -169
  14. package/src/components/Gantt/Gantt.vue +1544 -0
  15. package/src/components/GanttContextMenu/GanttContextMenu.vue +304 -0
  16. package/src/components/InteractionLayer.vue +343 -147
  17. package/src/components/Matrix/Matrix.vue +828 -0
  18. package/src/components/Matrix/index.ts +168 -0
  19. package/src/components/Shape/ConceptualRole.vue +2 -34
  20. package/src/components/Table/Table.vue +970 -0
  21. package/src/constants/edgeShapeKeys.ts +8 -5
  22. package/src/constants/index.ts +259 -45
  23. package/src/hooks/index.ts +2 -0
  24. package/src/hooks/useChartRowSelection.ts +456 -0
  25. package/src/hooks/useResize.ts +2 -2
  26. package/src/hooks/useVirtualScroll.ts +258 -0
  27. package/src/index.ts +1 -1
  28. package/src/render/shape-renderer.ts +62 -2
  29. package/src/statics/icons/childIcons//345/221/275/344/273/244@3x.png +0 -0
  30. package/src/statics/icons/childIcons//346/210/230/347/225/245/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  31. package/src/statics/icons/childIcons//346/216/247/345/210/266@3x.png +0 -0
  32. package/src/statics/icons/createMenu/down.png +0 -0
  33. package/src/statics/icons/createMenu/remove.png +0 -0
  34. package/src/statics/icons/createMenu/up.png +0 -0
  35. package/src/store/graphStore.ts +217 -44
  36. package/src/types/index.ts +86 -4
  37. package/src/utils/batchAutoExpand.ts +9 -10
  38. package/src/utils/containers.ts +72 -17
  39. package/src/utils/contextMenuUtils.ts +7 -7
  40. package/src/utils/dateUtils.ts +160 -0
  41. package/src/utils/diagram.ts +10 -8
  42. package/src/utils/drag.ts +6 -5
  43. package/src/utils/edgeUtils.ts +344 -427
  44. package/src/utils/edgeWorker.ts +471 -0
  45. package/src/utils/hittest.ts +37 -38
  46. package/src/utils/index.ts +3 -0
  47. package/src/utils/keyboardUtils.ts +5 -5
  48. package/src/utils/packageOutline.ts +96 -0
  49. package/src/utils/rafThrottle.ts +162 -0
  50. package/src/utils/workerManager.ts +335 -0
  51. package/src/view/graph.vue +47 -33
  52. /package/src/statics/icons/childIcons//346/210/230/347/225/{245@3x.png" → 245/345/261/202@3x.png"} +0 -0
@@ -5,40 +5,77 @@
5
5
  zIndex: props.shape.style?.zIndex
6
6
  }" @click.stop="handleClick($event)">
7
7
  <svg class="edge-svg" :viewBox="svgViewBox" :width="containerWidth" :height="containerHeight">
8
- <!-- 引入线条样式标记组件 -->
9
8
  <LineStyleMarker :shape-key="shapeKey" />
10
9
 
11
- <polyline :points="linePoints" :stroke="edgeColor" :stroke-width="strokeWidth" :stroke-dasharray="strokeDashArray"
12
- fill="none" @click.stop="handleClick($event)" :marker-start="getMarkerStart()" :marker-end="getMarkerEnd()" />
10
+ <polyline
11
+ :points="linePoints"
12
+ :stroke="edgeColor"
13
+ :stroke-width="strokeWidth"
14
+ :stroke-dasharray="strokeDashArray"
15
+ fill="none"
16
+ @click.stop="handleClick($event)"
17
+ :marker-start="getMarkerStart()"
18
+ :marker-end="getMarkerEnd()"
19
+ />
13
20
 
14
- <!-- 选中状态显示端点黑色圆圈 -->
15
21
  <g v-if="props.isSelected">
16
- <!-- 起点圆圈 -->
17
- <circle v-if="waypoints.length > 0" :cx="waypoints[0].x - bounds.minX + padding"
18
- :cy="waypoints[0].y - bounds.minY + padding" r="4" fill="#000000" stroke="#FFFFFF" stroke-width="1" />
19
-
20
- <!-- 终点圆圈 -->
21
- <circle v-if="waypoints.length > 1" :cx="waypoints[waypoints.length - 1].x - bounds.minX + padding"
22
- :cy="waypoints[waypoints.length - 1].y - bounds.minY + padding" r="4" fill="#000000" stroke="#FFFFFF"
23
- stroke-width="1" />
22
+ <circle
23
+ v-if="adjustedWaypoints.length > 0"
24
+ :cx="adjustedWaypoints[0].x - bounds.minX + padding"
25
+ :cy="adjustedWaypoints[0].y - bounds.minY + padding"
26
+ r="4"
27
+ fill="#000000"
28
+ stroke="#FFFFFF"
29
+ stroke-width="1"
30
+ />
31
+ <circle
32
+ v-if="adjustedWaypoints.length > 1"
33
+ :cx="adjustedWaypoints[adjustedWaypoints.length - 1].x - bounds.minX + padding"
34
+ :cy="adjustedWaypoints[adjustedWaypoints.length - 1].y - bounds.minY + padding"
35
+ r="4"
36
+ fill="#000000"
37
+ stroke="#FFFFFF"
38
+ stroke-width="1"
39
+ />
24
40
  </g>
25
41
 
26
- <!-- 线条上方显示描述 -->
27
- <!-- lineName有值且符合特定shapeKey时,显示keywords和lineName -->
28
- <text v-if="lineName && lineName !== '' && EDGES_WITH_KEYWORDS.includes(shapeKey)" :x="textPosition.x"
29
- :y="textPosition.y" text-anchor="middle" dominant-baseline="middle" font-family="思源黑体" font-size="12"
30
- fill="#5E5E5E" style="pointer-events: none;">
42
+ <text
43
+ v-if="lineName && lineName !== '' && EDGES_WITH_KEYWORDS.includes(shapeKey)"
44
+ :x="textPosition.x"
45
+ :y="textPosition.y"
46
+ text-anchor="middle"
47
+ dominant-baseline="middle"
48
+ font-family="思源黑体"
49
+ font-size="12"
50
+ fill="#5E5E5E"
51
+ style="pointer-events: none;"
52
+ >
31
53
  {{ keywords }}{{ lineName }}
32
54
  </text>
33
- <!-- 当lineName有值但不符合特定shapeKey时,单独显示lineName -->
34
- <text v-else-if="lineName && lineName !== ''" :x="textPosition.x" :y="textPosition.y" text-anchor="middle"
35
- dominant-baseline="middle" font-family="思源黑体" font-size="12" fill="#5E5E5E" style="pointer-events: none;">
55
+ <text
56
+ v-else-if="lineName && lineName !== ''"
57
+ :x="textPosition.x"
58
+ :y="textPosition.y"
59
+ text-anchor="middle"
60
+ dominant-baseline="middle"
61
+ font-family="思源黑体"
62
+ font-size="12"
63
+ fill="#5E5E5E"
64
+ style="pointer-events: none;"
65
+ >
36
66
  {{ lineName }}
37
67
  </text>
38
- <!-- 当lineName无值但符合特定shapeKey时,单独显示keywords -->
39
- <text v-else-if="EDGES_WITH_KEYWORDS.includes(shapeKey)" :x="textPosition.x" :y="textPosition.y"
40
- text-anchor="middle" dominant-baseline="middle" font-family="思源黑体" font-size="12" fill="#5E5E5E"
41
- style="pointer-events: none;">
68
+ <text
69
+ v-else-if="EDGES_WITH_KEYWORDS.includes(shapeKey)"
70
+ :x="textPosition.x"
71
+ :y="textPosition.y"
72
+ text-anchor="middle"
73
+ dominant-baseline="middle"
74
+ font-family="思源黑体"
75
+ font-size="12"
76
+ fill="#5E5E5E"
77
+ style="pointer-events: none;"
78
+ >
42
79
  {{ keywords }}
43
80
  </text>
44
81
  </svg>
@@ -46,12 +83,17 @@
46
83
  </template>
47
84
 
48
85
  <script setup lang="ts">
49
- import { computed, nextTick, onMounted } from 'vue'
86
+ import { computed } from 'vue'
50
87
  import type { Shape, Waypoint } from '../../types'
51
88
  import LineStyleMarker from '../LineStyle/LineStyleMarker.vue'
52
- import { DASHED_EDGE_SHAPES, EDGES_WITH_KEYWORDS, EDGES_WITH_ARROWHEADS, DIAMOND_MARKER_SHAPES, SPECIAL_END_POINT_SHAPES, EDGE_TYPE } from '../../constants/edgeShapeKeys'
89
+ import {
90
+ DASHED_EDGE_SHAPES,
91
+ EDGES_WITH_KEYWORDS,
92
+ EDGES_WITH_ARROWHEADS,
93
+ DIAMOND_MARKER_SHAPES,
94
+ SPECIAL_END_POINT_SHAPES
95
+ } from '../../constants/edgeShapeKeys'
53
96
 
54
- // Props
55
97
  interface Props {
56
98
  shape: Shape
57
99
  isSelected?: boolean
@@ -61,12 +103,15 @@ const props = withDefaults(defineProps<Props>(), {
61
103
  isSelected: false
62
104
  })
63
105
 
64
- // Events
65
106
  const emit = defineEmits<{
66
107
  'edge-click': [shape: Shape, event: MouseEvent]
67
108
  }>()
68
109
 
69
- // 解析waypoints
110
+ const shapeKey = computed(() => props.shape.shapeKey || '')
111
+ const keywords = computed(() => props.shape.keywords || '')
112
+ const lineName = computed(() => props.shape.modelName || '')
113
+
114
+ // 解析 waypointId,统一转成路径点数组。
70
115
  const waypoints = computed(() => {
71
116
  if (!props.shape.waypointId) return []
72
117
 
@@ -74,7 +119,7 @@ const waypoints = computed(() => {
74
119
  try {
75
120
  return JSON.parse(props.shape.waypointId) as Waypoint[]
76
121
  } catch (error) {
77
- console.error('解析waypointId失败:', error)
122
+ console.error('解析 waypointId 失败:', error)
78
123
  return []
79
124
  }
80
125
  }
@@ -86,14 +131,14 @@ const waypoints = computed(() => {
86
131
  return []
87
132
  })
88
133
 
89
- // 计算边界框
134
+ // 根据路径点计算当前边的包围盒。
90
135
  const bounds = computed(() => {
91
136
  if (waypoints.value.length === 0) {
92
137
  return { minX: 0, minY: 0, maxX: 100, maxY: 100 }
93
138
  }
94
139
 
95
- const xs = waypoints.value.map(wp => wp.x)
96
- const ys = waypoints.value.map(wp => wp.y)
140
+ const xs = waypoints.value.map((wp) => wp.x)
141
+ const ys = waypoints.value.map((wp) => wp.y)
97
142
 
98
143
  return {
99
144
  minX: Math.min(...xs),
@@ -103,231 +148,189 @@ const bounds = computed(() => {
103
148
  }
104
149
  })
105
150
 
106
- // 计算SVG相关属性
151
+ // SVG 容器需要给线头和选中圆点留出额外边距。
107
152
  const padding = 10
108
153
  const containerWidth = computed(() => {
109
154
  const width = bounds.value.maxX - bounds.value.minX + padding * 2
110
- // 如果宽度太小,设置最小宽度
111
155
  return Math.max(width, 20)
112
156
  })
113
157
  const containerHeight = computed(() => bounds.value.maxY - bounds.value.minY + padding * 2)
114
- const svgViewBox = computed(() =>
115
- `0 0 ${containerWidth.value} ${containerHeight.value}`
116
- )
158
+ const svgViewBox = computed(() => `0 0 ${containerWidth.value} ${containerHeight.value}`)
117
159
 
118
- // 计算polyline点(相对坐标)
119
- const linePoints = computed(() => {
120
- if (waypoints.value.length === 0) return '0,0 100,100'
121
-
122
- // 创建新数组以避免修改原始数据
123
- const adjustedWaypoints = [...waypoints.value];
160
+ // 统一调整折点,保证 polyline、path 和选中态端点使用的是同一套坐标。
161
+ const adjustedWaypoints = computed(() => {
162
+ if (waypoints.value.length === 0) return []
124
163
 
125
- // 调整起点位置避免线条穿过菱形
126
- if (DIAMOND_MARKER_SHAPES.includes(shapeKey.value) && adjustedWaypoints.length >= 2) {
127
- const startPoint = adjustedWaypoints[0];
128
- const nextPoint = adjustedWaypoints[1];
164
+ const nextWaypoints = [...waypoints.value]
129
165
 
130
- // 计算方向向量
131
- const dx = nextPoint.x - startPoint.x;
132
- const dy = nextPoint.y - startPoint.y;
133
- const length = Math.sqrt(dx * dx + dy * dy);
166
+ // 调整起点位置,避免菱形起点标记被线条穿过。
167
+ if (DIAMOND_MARKER_SHAPES.includes(shapeKey.value) && nextWaypoints.length >= 2) {
168
+ const startPoint = nextWaypoints[0]
169
+ const nextPoint = nextWaypoints[1]
170
+ const dx = nextPoint.x - startPoint.x
171
+ const dy = nextPoint.y - startPoint.y
172
+ const length = Math.sqrt(dx * dx + dy * dy)
134
173
 
135
174
  if (length > 0) {
136
- // 计算缩短距离,基于菱形的实际高度(6)和宽度(12)
137
- // 使用6*2作为缩短距离,确保菱形紧贴元素边缘
138
- const shortenDistance = 18;
139
- const ratio = shortenDistance / length;
175
+ const shortenDistance = 18
176
+ const ratio = shortenDistance / length
140
177
 
141
- // 调整起点位置
142
- adjustedWaypoints[0] = {
178
+ nextWaypoints[0] = {
143
179
  ...startPoint,
144
180
  x: startPoint.x + dx * ratio,
145
181
  y: startPoint.y + dy * ratio
146
- };
182
+ }
147
183
  }
148
184
  }
149
185
 
150
- // 需要特殊终点处理的边类型,避免线条穿过箭头
151
- if (SPECIAL_END_POINT_SHAPES.includes(shapeKey.value) && adjustedWaypoints.length >= 2) {
152
- const endPoint = adjustedWaypoints[adjustedWaypoints.length - 1];
153
- const prevPoint = adjustedWaypoints[adjustedWaypoints.length - 2];
154
-
155
- // 计算方向向量(从终点指向倒数第二点,即反向向量)
156
- const dx = prevPoint.x - endPoint.x;
157
- const dy = prevPoint.y - endPoint.y;
158
- const length = Math.sqrt(dx * dx + dy * dy);
186
+ // 调整终点位置,避免线条压进箭头或菱形终点里。
187
+ if (SPECIAL_END_POINT_SHAPES.includes(shapeKey.value) && nextWaypoints.length >= 2) {
188
+ const endPoint = nextWaypoints[nextWaypoints.length - 1]
189
+ const prevPoint = nextWaypoints[nextWaypoints.length - 2]
190
+ const dx = prevPoint.x - endPoint.x
191
+ const dy = prevPoint.y - endPoint.y
192
+ const length = Math.sqrt(dx * dx + dy * dy)
159
193
 
160
194
  if (length > 0) {
161
- // 计算缩短距离
162
- const shortenDistance = 14;
163
- const ratio = shortenDistance / length;
195
+ const shortenDistance = 14
196
+ const ratio = shortenDistance / length
164
197
 
165
- // 调整终点位置,向相反方向移动
166
- adjustedWaypoints[adjustedWaypoints.length - 1] = {
198
+ nextWaypoints[nextWaypoints.length - 1] = {
167
199
  ...endPoint,
168
200
  x: endPoint.x + dx * ratio,
169
201
  y: endPoint.y + dy * ratio
170
- };
202
+ }
171
203
  }
172
204
  }
173
205
 
174
- return adjustedWaypoints
175
- .map(wp => `${wp.x - bounds.value.minX + padding},${wp.y - bounds.value.minY + padding}`)
176
- .join(' ')
206
+ return nextWaypoints
177
207
  })
178
208
 
179
- // 获取shapeKey
180
- const shapeKey = computed(() => props.shape.shapeKey || '')
181
- // 获取名称
182
- const keywords = computed(() => props.shape.keywords || '')
183
-
184
- //获取线的名称
185
- const lineName = computed(() => props.shape.modelName || '')
186
-
209
+ // 普通边仍保持 polyline 渲染。
210
+ const linePoints = computed(() => {
211
+ if (adjustedWaypoints.value.length === 0) return '0,0 100,100'
187
212
 
188
- // 样式相关
189
- const edgeColor = computed(() => {
190
- // 选中状态保持黑色
191
- if (props.isSelected) {
192
- return '#000000'
193
- }
194
- // 可以根据不同的形状类型返回不同的颜色
195
- return '#5E5E5E'
196
- })
197
- const strokeWidth = computed(() => {
198
- // 选中状态线条加粗
199
- if (props.isSelected) {
200
- return 2
201
- }
202
- return props.shape.style?.borderWidth || 1.5
203
- })
204
- const strokeDashArray = computed(() => {
205
- if (DASHED_EDGE_SHAPES.includes(shapeKey.value)) {
206
- return '12,11'; // 虚线样式
207
- }
213
+ return adjustedWaypoints.value
214
+ .map((wp) => `${wp.x - bounds.value.minX + padding},${wp.y - bounds.value.minY + padding}`)
215
+ .join(' ')
208
216
  })
209
217
 
210
- // 计算文本位置
218
+ // 计算文本位置,优先取中间线段的法线方向。
211
219
  const textPosition = computed(() => {
212
- if (!waypoints.value || waypoints.value.length === 0) {
213
- // 当没有路径点时,返回一个默认位置
214
- return { x: 120, y: 40 };
220
+ if (!adjustedWaypoints.value || adjustedWaypoints.value.length === 0) {
221
+ return { x: 120, y: 40 }
215
222
  }
216
223
 
217
- if (waypoints.value.length === 1) {
218
- // 当只有一个路径点时,使用默认的向上偏移
224
+ if (adjustedWaypoints.value.length === 1) {
219
225
  return {
220
- x: waypoints.value[0].x - bounds.value.minX + padding,
221
- y: waypoints.value[0].y - bounds.value.minY + padding - 10
222
- };
226
+ x: adjustedWaypoints.value[0].x - bounds.value.minX + padding,
227
+ y: adjustedWaypoints.value[0].y - bounds.value.minY + padding - 10
228
+ }
223
229
  }
224
230
 
225
- // 计算线条中点和方向
226
- let midPoint, normalVector;
231
+ let midPoint: { x: number; y: number }
232
+ let normalVector: { x: number; y: number }
227
233
 
228
- if (waypoints.value.length > 2) {
229
- // 对于多段线,找到中间线段
230
- const segmentIndex = Math.floor((waypoints.value.length - 1) / 2);
231
- const p1 = waypoints.value[segmentIndex];
232
- const p2 = waypoints.value[segmentIndex + 1];
234
+ if (adjustedWaypoints.value.length > 2) {
235
+ const segmentIndex = Math.floor((adjustedWaypoints.value.length - 1) / 2)
236
+ const p1 = adjustedWaypoints.value[segmentIndex]
237
+ const p2 = adjustedWaypoints.value[segmentIndex + 1]
233
238
 
234
- // 计算中间线段的中点
235
239
  midPoint = {
236
240
  x: (p1.x + p2.x) / 2,
237
241
  y: (p1.y + p2.y) / 2
238
- };
239
-
240
- // 计算线段的方向向量
241
- const dx = p2.x - p1.x;
242
- const dy = p2.y - p1.y;
242
+ }
243
243
 
244
- // 计算线段长度
245
- const length = Math.sqrt(dx * dx + dy * dy);
244
+ const dx = p2.x - p1.x
245
+ const dy = p2.y - p1.y
246
+ const length = Math.sqrt(dx * dx + dy * dy)
246
247
 
247
- // 计算单位法线向量(向左旋转90度)
248
248
  if (length > 0) {
249
249
  normalVector = {
250
250
  x: -dy / length,
251
251
  y: dx / length
252
- };
252
+ }
253
253
  } else {
254
- // 避免除以零,使用默认向上的向量
255
- normalVector = { x: 0, y: -1 };
254
+ normalVector = { x: 0, y: -1 }
256
255
  }
257
256
  } else {
258
- // 对于两段线,使用两个端点
259
- const p1 = waypoints.value[0];
260
- const p2 = waypoints.value[1];
257
+ const p1 = adjustedWaypoints.value[0]
258
+ const p2 = adjustedWaypoints.value[1]
261
259
 
262
- // 计算中点
263
260
  midPoint = {
264
261
  x: (p1.x + p2.x) / 2,
265
262
  y: (p1.y + p2.y) / 2
266
- };
267
-
268
- // 计算方向向量
269
- const dx = p2.x - p1.x;
270
- const dy = p2.y - p1.y;
263
+ }
271
264
 
272
- // 计算长度
273
- const length = Math.sqrt(dx * dx + dy * dy);
265
+ const dx = p2.x - p1.x
266
+ const dy = p2.y - p1.y
267
+ const length = Math.sqrt(dx * dx + dy * dy)
274
268
 
275
- // 计算单位法线向量
276
269
  if (length > 0) {
277
270
  normalVector = {
278
271
  x: -dy / length,
279
272
  y: dx / length
280
- };
273
+ }
281
274
  } else {
282
- normalVector = { x: 0, y: -1 };
275
+ normalVector = { x: 0, y: -1 }
283
276
  }
284
277
  }
285
278
 
286
- // 计算文本位置:中点加上法线方向的偏移(在线条正上方10px)
287
- const offsetDistance = 10;
288
- const adjustedX = midPoint.x + normalVector.x * offsetDistance;
289
- const adjustedY = midPoint.y + normalVector.y * offsetDistance;
279
+ const offsetDistance = 10
280
+ const adjustedX = midPoint.x + normalVector.x * offsetDistance
281
+ const adjustedY = midPoint.y + normalVector.y * offsetDistance
290
282
 
291
- // 转换为相对坐标
292
283
  return {
293
284
  x: adjustedX - bounds.value.minX + padding,
294
285
  y: adjustedY - bounds.value.minY + padding
295
- };
296
- });
286
+ }
287
+ })
288
+
289
+ const edgeColor = computed(() => {
290
+ if (props.isSelected) {
291
+ return '#000000'
292
+ }
293
+ return '#5E5E5E'
294
+ })
295
+
296
+ const strokeWidth = computed(() => {
297
+ if (props.isSelected) {
298
+ return 2
299
+ }
300
+ return props.shape.style?.borderWidth || 1.5
301
+ })
302
+
303
+ const strokeDashArray = computed(() => {
304
+ if (DASHED_EDGE_SHAPES.includes(shapeKey.value)) {
305
+ return '12,11'
306
+ }
307
+ })
297
308
 
298
- // 获取起点标记
299
309
  const getMarkerStart = () => {
300
- // 菱形标记
301
310
  if (DIAMOND_MARKER_SHAPES.includes(shapeKey.value)) {
302
- return `url(#diamond-${shapeKey.value})`;
311
+ return `url(#diamond-${shapeKey.value})`
303
312
  }
304
313
  return ''
305
314
  }
306
315
 
307
- // 获取终点标记
308
316
  const getMarkerEnd = () => {
309
- // 空心箭头
310
317
  if (EDGES_WITH_ARROWHEADS.includes(shapeKey.value)) {
311
- return `url(#arrowhead-${shapeKey.value})`;
318
+ return `url(#arrowhead-${shapeKey.value})`
312
319
  }
313
- // 终点有空心三角形箭头(泛化关系)
314
- else if (SPECIAL_END_POINT_SHAPES.includes(shapeKey.value)) {
315
- return `url(#diamond-${shapeKey.value})`;
320
+ if (SPECIAL_END_POINT_SHAPES.includes(shapeKey.value)) {
321
+ return `url(#diamond-${shapeKey.value})`
316
322
  }
317
323
  return ''
318
324
  }
319
325
 
320
- // 事件处理
321
326
  const handleClick = (event: MouseEvent) => {
322
- console.log('Edge组件内部捕获到点击事件:', props.shape.id, props.shape.shapeType);
323
- // 确保shapeType为edge
327
+ console.log('Edge组件内部捕获到点击事件:', props.shape.id, props.shape.shapeType)
324
328
  const shapeWithCorrectType = {
325
329
  ...props.shape,
326
330
  shapeType: 'edge' as const
327
- };
331
+ }
328
332
  emit('edge-click', shapeWithCorrectType, event)
329
333
  }
330
-
331
334
  </script>
332
335
 
333
336
  <style scoped>
@@ -352,4 +355,4 @@ const handleClick = (event: MouseEvent) => {
352
355
  .edge-svg circle {
353
356
  pointer-events: none;
354
357
  }
355
- </style>>
358
+ </style>