@mx-sose-front/mx-sose-graph 1.1.1 → 1.1.2
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/dist/index.d.ts +103 -10
- package/dist/index.esm.js +6618 -5593
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +7 -7
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/{ContextMenu.vue → ContextMenu/ContextMenu.vue} +243 -70
- package/src/components/DiagramListTooltip/DiagramListTooltip.vue +138 -0
- package/src/components/Edge/Edge.vue +38 -49
- package/src/components/InteractionLayer.vue +432 -838
- package/src/components/Shape/Block.vue +8 -8
- package/src/components/ZoomSlider/ZoomSlider.vue +229 -0
- package/src/constants/index.ts +12 -0
- package/src/statics/icons/childIcons//351/241/271/347/233/256/351/241/272/345/272/217@3x.png +0 -0
- package/src/store/graphStore.ts +98 -21
- package/src/types/index.ts +14 -1
- package/src/types/interactionLayer.ts +35 -0
- package/src/utils/contextMenuUtils.ts +264 -0
- package/src/utils/diagram.ts +93 -4
- package/src/utils/edgeUtils.ts +228 -0
- package/src/utils/geom.ts +34 -0
- package/src/utils/graphDragService.ts +14 -17
- package/src/utils/keyboardUtils.ts +229 -0
- package/src/utils/license-guard.ts +50 -0
- package/src/utils/nameEditUtils.ts +132 -0
- package/src/utils/resizeUtils.ts +463 -0
- package/src/view/graph.vue +102 -134
- package/src/components/Label.vue +0 -0
|
@@ -1,56 +1,44 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="edge-component" :style="{
|
|
3
3
|
pointerEvents: 'all',
|
|
4
|
-
cursor: 'pointer'
|
|
4
|
+
cursor: 'pointer',
|
|
5
|
+
zIndex: props.shape.style?.zIndex
|
|
5
6
|
}" @click.stop="handleClick($event)">
|
|
6
7
|
<svg class="edge-svg" :viewBox="svgViewBox" :width="containerWidth" :height="containerHeight">
|
|
7
8
|
<!-- 引入线条样式标记组件 -->
|
|
8
9
|
<LineStyleMarker :shape-key="shapeKey" />
|
|
9
10
|
|
|
10
11
|
<polyline :points="linePoints" :stroke="edgeColor" :stroke-width="strokeWidth" :stroke-dasharray="strokeDashArray"
|
|
11
|
-
fill="none" @click.stop="handleClick($event)" :marker-start="getMarkerStart()" :marker-end="getMarkerEnd()" />
|
|
12
|
-
|
|
12
|
+
fill="none" @click.stop="handleClick($event)" :marker-start="getMarkerStart()" :marker-end="getMarkerEnd()" />
|
|
13
|
+
|
|
13
14
|
<!-- 选中状态显示端点黑色圆圈 -->
|
|
14
15
|
<g v-if="props.isSelected">
|
|
15
16
|
<!-- 起点圆圈 -->
|
|
16
|
-
<circle v-if="waypoints.length > 0"
|
|
17
|
-
:
|
|
18
|
-
|
|
19
|
-
r="4"
|
|
20
|
-
fill="#000000"
|
|
21
|
-
stroke="#FFFFFF"
|
|
22
|
-
stroke-width="1" />
|
|
23
|
-
|
|
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
|
+
|
|
24
20
|
<!-- 终点圆圈 -->
|
|
25
|
-
<circle v-if="waypoints.length > 1"
|
|
26
|
-
:
|
|
27
|
-
:cy="waypoints[waypoints.length - 1].y - bounds.minY + padding"
|
|
28
|
-
r="4"
|
|
29
|
-
fill="#000000"
|
|
30
|
-
stroke="#FFFFFF"
|
|
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"
|
|
31
23
|
stroke-width="1" />
|
|
32
24
|
</g>
|
|
33
|
-
|
|
25
|
+
|
|
34
26
|
<!-- 线条上方显示描述 -->
|
|
35
27
|
<!-- 当lineName有值且符合特定shapeKey时,显示keywords和lineName -->
|
|
36
|
-
<text v-if="lineName && lineName !== '' && EDGES_WITH_KEYWORDS.includes(shapeKey)"
|
|
37
|
-
:
|
|
38
|
-
|
|
39
|
-
font-family="思源黑体" font-size="12" fill="#5E5E5E" style="pointer-events: none;">
|
|
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;">
|
|
40
31
|
{{ keywords }}{{ lineName }}
|
|
41
32
|
</text>
|
|
42
33
|
<!-- 当lineName有值但不符合特定shapeKey时,单独显示lineName -->
|
|
43
|
-
<text v-else-if="lineName && lineName !== ''"
|
|
44
|
-
|
|
45
|
-
text-anchor="middle" dominant-baseline="middle"
|
|
46
|
-
font-family="思源黑体" font-size="12" fill="#5E5E5E" style="pointer-events: none;">
|
|
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;">
|
|
47
36
|
{{ lineName }}
|
|
48
37
|
</text>
|
|
49
38
|
<!-- 当lineName无值但符合特定shapeKey时,单独显示keywords -->
|
|
50
|
-
<text v-else-if="EDGES_WITH_KEYWORDS.includes(shapeKey)"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
font-family="思源黑体" font-size="12" fill="#5E5E5E" style="pointer-events: none;">
|
|
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;">
|
|
54
42
|
{{ keywords }}
|
|
55
43
|
</text>
|
|
56
44
|
</svg>
|
|
@@ -58,7 +46,7 @@
|
|
|
58
46
|
</template>
|
|
59
47
|
|
|
60
48
|
<script setup lang="ts">
|
|
61
|
-
import { computed } from 'vue'
|
|
49
|
+
import { computed, nextTick, onMounted } from 'vue'
|
|
62
50
|
import type { Shape, Waypoint } from '../../types'
|
|
63
51
|
import LineStyleMarker from '../LineStyle/LineStyleMarker.vue'
|
|
64
52
|
import { DASHED_EDGE_SHAPES, EDGES_WITH_KEYWORDS, EDGES_WITH_ARROWHEADS, DIAMOND_MARKER_SHAPES, SPECIAL_END_POINT_SHAPES, EDGE_TYPE } from '../../constants/edgeShapeKeys'
|
|
@@ -158,22 +146,22 @@ const linePoints = computed(() => {
|
|
|
158
146
|
};
|
|
159
147
|
}
|
|
160
148
|
}
|
|
161
|
-
|
|
149
|
+
|
|
162
150
|
// 需要特殊终点处理的边类型,避免线条穿过箭头
|
|
163
151
|
if (SPECIAL_END_POINT_SHAPES.includes(shapeKey.value) && adjustedWaypoints.length >= 2) {
|
|
164
152
|
const endPoint = adjustedWaypoints[adjustedWaypoints.length - 1];
|
|
165
153
|
const prevPoint = adjustedWaypoints[adjustedWaypoints.length - 2];
|
|
166
|
-
|
|
154
|
+
|
|
167
155
|
// 计算方向向量(从终点指向倒数第二点,即反向向量)
|
|
168
156
|
const dx = prevPoint.x - endPoint.x;
|
|
169
157
|
const dy = prevPoint.y - endPoint.y;
|
|
170
158
|
const length = Math.sqrt(dx * dx + dy * dy);
|
|
171
|
-
|
|
159
|
+
|
|
172
160
|
if (length > 0) {
|
|
173
161
|
// 计算缩短距离
|
|
174
162
|
const shortenDistance = 14;
|
|
175
163
|
const ratio = shortenDistance / length;
|
|
176
|
-
|
|
164
|
+
|
|
177
165
|
// 调整终点位置,向相反方向移动
|
|
178
166
|
adjustedWaypoints[adjustedWaypoints.length - 1] = {
|
|
179
167
|
...endPoint,
|
|
@@ -194,7 +182,7 @@ const shapeKey = computed(() => props.shape.shapeKey || '')
|
|
|
194
182
|
const keywords = computed(() => props.shape.keywords || '')
|
|
195
183
|
|
|
196
184
|
//获取线的名称
|
|
197
|
-
const lineName = computed(()=>props.shape.modelName || '')
|
|
185
|
+
const lineName = computed(() => props.shape.modelName || '')
|
|
198
186
|
|
|
199
187
|
|
|
200
188
|
// 样式相关
|
|
@@ -225,7 +213,7 @@ const textPosition = computed(() => {
|
|
|
225
213
|
// 当没有路径点时,返回一个默认位置
|
|
226
214
|
return { x: 120, y: 40 };
|
|
227
215
|
}
|
|
228
|
-
|
|
216
|
+
|
|
229
217
|
if (waypoints.value.length === 1) {
|
|
230
218
|
// 当只有一个路径点时,使用默认的向上偏移
|
|
231
219
|
return {
|
|
@@ -233,29 +221,29 @@ const textPosition = computed(() => {
|
|
|
233
221
|
y: waypoints.value[0].y - bounds.value.minY + padding - 10
|
|
234
222
|
};
|
|
235
223
|
}
|
|
236
|
-
|
|
224
|
+
|
|
237
225
|
// 计算线条中点和方向
|
|
238
226
|
let midPoint, normalVector;
|
|
239
|
-
|
|
227
|
+
|
|
240
228
|
if (waypoints.value.length > 2) {
|
|
241
229
|
// 对于多段线,找到中间线段
|
|
242
230
|
const segmentIndex = Math.floor((waypoints.value.length - 1) / 2);
|
|
243
231
|
const p1 = waypoints.value[segmentIndex];
|
|
244
232
|
const p2 = waypoints.value[segmentIndex + 1];
|
|
245
|
-
|
|
233
|
+
|
|
246
234
|
// 计算中间线段的中点
|
|
247
235
|
midPoint = {
|
|
248
236
|
x: (p1.x + p2.x) / 2,
|
|
249
237
|
y: (p1.y + p2.y) / 2
|
|
250
238
|
};
|
|
251
|
-
|
|
239
|
+
|
|
252
240
|
// 计算线段的方向向量
|
|
253
241
|
const dx = p2.x - p1.x;
|
|
254
242
|
const dy = p2.y - p1.y;
|
|
255
|
-
|
|
243
|
+
|
|
256
244
|
// 计算线段长度
|
|
257
245
|
const length = Math.sqrt(dx * dx + dy * dy);
|
|
258
|
-
|
|
246
|
+
|
|
259
247
|
// 计算单位法线向量(向左旋转90度)
|
|
260
248
|
if (length > 0) {
|
|
261
249
|
normalVector = {
|
|
@@ -270,20 +258,20 @@ const textPosition = computed(() => {
|
|
|
270
258
|
// 对于两段线,使用两个端点
|
|
271
259
|
const p1 = waypoints.value[0];
|
|
272
260
|
const p2 = waypoints.value[1];
|
|
273
|
-
|
|
261
|
+
|
|
274
262
|
// 计算中点
|
|
275
263
|
midPoint = {
|
|
276
264
|
x: (p1.x + p2.x) / 2,
|
|
277
265
|
y: (p1.y + p2.y) / 2
|
|
278
266
|
};
|
|
279
|
-
|
|
267
|
+
|
|
280
268
|
// 计算方向向量
|
|
281
269
|
const dx = p2.x - p1.x;
|
|
282
270
|
const dy = p2.y - p1.y;
|
|
283
|
-
|
|
271
|
+
|
|
284
272
|
// 计算长度
|
|
285
273
|
const length = Math.sqrt(dx * dx + dy * dy);
|
|
286
|
-
|
|
274
|
+
|
|
287
275
|
// 计算单位法线向量
|
|
288
276
|
if (length > 0) {
|
|
289
277
|
normalVector = {
|
|
@@ -294,12 +282,12 @@ const textPosition = computed(() => {
|
|
|
294
282
|
normalVector = { x: 0, y: -1 };
|
|
295
283
|
}
|
|
296
284
|
}
|
|
297
|
-
|
|
285
|
+
|
|
298
286
|
// 计算文本位置:中点加上法线方向的偏移(在线条正上方10px)
|
|
299
287
|
const offsetDistance = 10;
|
|
300
288
|
const adjustedX = midPoint.x + normalVector.x * offsetDistance;
|
|
301
289
|
const adjustedY = midPoint.y + normalVector.y * offsetDistance;
|
|
302
|
-
|
|
290
|
+
|
|
303
291
|
// 转换为相对坐标
|
|
304
292
|
return {
|
|
305
293
|
x: adjustedX - bounds.value.minX + padding,
|
|
@@ -339,6 +327,7 @@ const handleClick = (event: MouseEvent) => {
|
|
|
339
327
|
};
|
|
340
328
|
emit('edge-click', shapeWithCorrectType, event)
|
|
341
329
|
}
|
|
330
|
+
|
|
342
331
|
</script>
|
|
343
332
|
|
|
344
333
|
<style scoped>
|