hookehuyr

自定义边操作

1 /* 1 /*
2 * @Date: 2025-03-10 13:15:30 2 * @Date: 2025-03-10 13:15:30
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-03-11 17:45:38 4 + * @LastEditTime: 2025-03-12 11:06:26
5 * @FilePath: /logic-flow2/src/router/index.js 5 * @FilePath: /logic-flow2/src/router/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -44,7 +44,27 @@ const router = createRouter({ ...@@ -44,7 +44,27 @@ const router = createRouter({
44 path: '/node-vue', 44 path: '/node-vue',
45 name: 'node-vue', 45 name: 'node-vue',
46 component: () => import('../views/node-vue/index.vue') 46 component: () => import('../views/node-vue/index.vue')
47 - } 47 + },
48 + {
49 + path: '/edge',
50 + name: 'edge',
51 + component: () => import('../views/edge/index.vue')
52 + },
53 + {
54 + path: '/edge-custom',
55 + name: 'edge-custom',
56 + component: () => import('../views/edge/custom.vue')
57 + },
58 + {
59 + path: '/edge-text',
60 + name: 'edge-text',
61 + component: () => import('../views/edge/text.vue')
62 + },
63 + {
64 + path: '/edge-arrow',
65 + name: 'edge-arrow',
66 + component: () => import('../views/edge/arrow.vue')
67 + },
48 ] 68 ]
49 }) 69 })
50 70
......
1 +<!--
2 + * @Date: 2025-03-10 16:52:35
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 16:16:06
5 + * @FilePath: /logic-flow2/src/views/edge/arrow.vue
6 + * @Description: 自定义箭头
7 +-->
8 +<template>
9 + <div class="container">
10 + <div ref="container" class="flow-container"></div>
11 + </div>
12 +</template>
13 +
14 +<script setup>
15 +import LogicFlow from "@logicflow/core";
16 +import CustomArrow from "./customArrow";
17 +import data from "./data4";
18 +
19 +const container = ref(null);
20 +let lf = null;
21 +
22 +onMounted(() => {
23 + lf = new LogicFlow({
24 + container: container.value,
25 + grid: true,
26 + edgeType: 'custom-arrow',
27 + adjustEdge: true, // 开启边的调整功能
28 + adjustEdgeStartAndEnd: true, // 允许调整边的起终点
29 + });
30 +
31 + lf.register(CustomArrow);
32 + lf.render(data);
33 + lf.translateCenter();
34 +});
35 +</script>
36 +
37 +<style scoped>
38 +.container {
39 + width: 100vw;
40 + height: 100vh;
41 + display: flex;
42 + flex-direction: column;
43 +}
44 +
45 +.flow-container {
46 + flex: 1;
47 + width: 100%;
48 + height: 100%;
49 +}
50 +</style>
1 +<!--
2 + * @Date: 2025-03-10 16:52:35
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 14:13:59
5 + * @FilePath: /logic-flow2/src/views/edge/custom.vue
6 + * @Description: 自定义边
7 +-->
8 +<template>
9 + <div class="container">
10 + <div ref="container" class="flow-container"></div>
11 + </div>
12 +</template>
13 +
14 +<script setup>
15 +import LogicFlow from "@logicflow/core";
16 +import sequence from "./sequence";
17 +import data from "./data2";
18 +
19 +const container = ref(null);
20 +let lf = null;
21 +
22 +onMounted(() => {
23 + lf = new LogicFlow({
24 + container: container.value,
25 + grid: true,
26 + });
27 +
28 + lf.register(sequence);
29 + // 设置当节点直接由用户手动连接的默认边类型
30 + lf.setDefaultEdgeType("sequence");
31 +
32 + lf.render(data);
33 + lf.translateCenter();
34 +
35 + lf.on("edge:click", ({ data }) => {
36 + lf.getEdgeModelById(data.id).setText({
37 + // draggable: true,
38 + });
39 + });
40 +});
41 +</script>
42 +
43 +<style scoped>
44 +.container {
45 + width: 100vw;
46 + height: 100vh;
47 + display: flex;
48 + flex-direction: column;
49 +}
50 +
51 +.flow-container {
52 + flex: 1;
53 + width: 100%;
54 + height: 100%;
55 +}
56 +</style>
1 +/*
2 + * @Date: 2025-03-12 15:30:18
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 16:19:06
5 + * @FilePath: /logic-flow2/src/views/edge/customArrow.js
6 + * @Description: 文件描述
7 + */
8 +import { PolylineEdge, PolylineEdgeModel, h } from '@logicflow/core';
9 +
10 +class CustomEdgeModel extends PolylineEdgeModel {
11 + // customTextPosition = true;
12 + initEdgeData(data) {
13 + super.initEdgeData(data);
14 + this.customTextPosition = true;
15 + this.adjustEdgeMiddle = true; // 允许调整边中间的点
16 + }
17 + setAttributes() {
18 + this.isAnimation = true;
19 + }
20 + // setHovered(isHovered) {
21 + // super.setHovered(isHovered);
22 + // this.isAnimation = isHovered;
23 + // }
24 + getEdgeAnimationStyle() {
25 + const style = super.getEdgeAnimationStyle();
26 + style.strokeDasharray = "5 5";
27 + style.strokeDashoffset = "100%";
28 + style.animationDuration = "10s";
29 + return style;
30 + }
31 +}
32 +
33 +class CustomArrow extends PolylineEdge {
34 + getAdjustPointShape(x, y) {
35 + return h("g", {}, [
36 + h("image", {
37 + x: x - 9,
38 + y: y - 9,
39 + width: 18,
40 + height: 18,
41 + cursor: "move",
42 + href:
43 + "data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIyMnB4IiBoZWlnaHQ9IjIycHgiIHZlcnNpb249IjEuMSI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iNyIgc3Ryb2tlPSIjZmZmIiBmaWxsPSIjMjliNmYyIi8+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iMyIgc3Ryb2tlPSIjZmZmIiBmaWxsPSJ0cmFuc3BhcmVudCIvPjwvc3ZnPg=="
44 + })
45 + ]);
46 + }
47 +
48 + getEndArrow() {
49 + const { model } = this.props;
50 + const {
51 + properties: { arrowType },
52 + } = model;
53 +
54 + const { stroke, strokeWidth } = model.getArrowStyle();
55 + const pathAttr = {
56 + stroke,
57 + strokeWidth,
58 + };
59 +
60 + if (arrowType === 'empty') {
61 + // 空心箭头
62 + return h('path', {
63 + ...pathAttr,
64 + fill: '#FFF',
65 + d: 'M 0 0 -20 -5 -30 0 -20 5 z',
66 + });
67 + } else if (arrowType === 'half') {
68 + // 半箭头
69 + return h('path', {
70 + ...pathAttr,
71 + d: 'M 0 0 -10 5',
72 + });
73 + }
74 + return h('path', {
75 + ...pathAttr,
76 + d: 'M 0 0 -10 -5 -10 5 z',
77 + });
78 + }
79 +}
80 +
81 +export default {
82 + type: 'custom-arrow',
83 + model: CustomEdgeModel,
84 + view: CustomArrow,
85 +};
1 +/*
2 + * @Date: 2025-03-12 14:33:32
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 16:04:26
5 + * @FilePath: /logic-flow2/src/views/edge/customEdge.js
6 + * @Description: 文件描述
7 + */
8 +/*
9 + * @Date: 2025-03-12 14:33:32
10 + * @LastEditors: hookehuyr hookehuyr@gmail.com
11 + * @LastEditTime: 2025-03-12 15:14:53
12 + * @FilePath: /logic-flow2/src/views/edge/customEdge.js
13 + * @Description: 文件描述
14 + */
15 +import { PolylineEdge, PolylineEdgeModel } from '@logicflow/core'
16 +
17 +class CustomEdgeModel extends PolylineEdgeModel {
18 + customTextPosition = true
19 +
20 + getTextStyle() {
21 + const style = super.getTextStyle()
22 + // const { x: x1 } = this.pointsList[0];
23 + // const { x: x2 } = this.pointsList[1];
24 + // if (x1 === x2) {
25 + // // 垂直
26 + // style.textWidth = 20;
27 + // } else {
28 + // style.textWidth = 200;
29 + // }
30 + style.className = 'custom-text'
31 + return style
32 + }
33 +
34 + getTextPosition() {
35 + const position = super.getTextPosition()
36 +
37 + const currentPositionList = this.points.split(' ') // 点位信息是以空格分隔的字符串, 例如点位可能是这样的格式:"100,200 150,200 150,300"
38 +
39 + // const pointsList = []
40 + // currentPositionList &&
41 + // currentPositionList.forEach((item) => {
42 + // const [x, y] = item.split(',') // 每个点的x,y坐标是以逗号分隔的
43 + // pointsList.push({ x: Number(x), y: Number(y) })
44 + // })
45 +
46 + if (currentPositionList.length > 1) { // 确保至少有两个点
47 + const [x1, y1] = currentPositionList[0].split(',') // 第一个点的坐标
48 + const [x2, y2] = currentPositionList[1].split(',') // 第二个点的坐标
49 + let distance = 50 // 默认偏移距离
50 +
51 + if (Number(x1) === Number(x2)) { // 如果是垂直线
52 + if (Number(y2) < Number(y1)) { // 如果是向上的线
53 + distance = -50 // 偏移方向改为向上
54 + }
55 + position.y = Number(y1) + distance // 在y方向上偏移
56 + position.x = Number(x1) // x保持不变
57 + } else { // 如果是水平线或斜线
58 + if (Number(x2) < Number(x1)) { // 如果是向左的线
59 + distance = -50 // 偏移方向改为向左
60 + }
61 + position.x = Number(x1) + distance // 在x方向上偏移
62 + position.y = Number(y1) - 10 // y方向略微上移
63 + }
64 + }
65 + return position
66 + }
67 +}
68 +
69 +class CustomEdge extends PolylineEdge {}
70 +
71 +export default {
72 + type: 'custom-edge',
73 + model: CustomEdgeModel,
74 + view: CustomEdge,
75 +}
1 +/*
2 + * @Date: 2025-03-12 11:04:21
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 11:04:43
5 + * @FilePath: /logic-flow2/src/views/edge/data.js
6 + * @Description: 文件描述
7 + */
8 +const data = {
9 + nodes: [
10 + {
11 + id: '1',
12 + type: 'rect',
13 + x: 100,
14 + y: 100,
15 + text: '矩形1',
16 + },
17 + {
18 + id: '2',
19 + type: 'ellipse',
20 + x: 500,
21 + y: 100,
22 + text: '椭圆2',
23 + },
24 + {
25 + id: '3',
26 + type: 'polygon',
27 + x: 100,
28 + y: 250,
29 + text: '多边形3',
30 + },
31 + {
32 + id: '4',
33 + type: 'diamond',
34 + x: 300,
35 + y: 250,
36 + text: '菱形4',
37 + },
38 + ],
39 + edges: [
40 + {
41 + sourceNodeId: '1',
42 + targetNodeId: '2',
43 + startPoint: {
44 + // 起始点
45 + x: 100,
46 + y: 60,
47 + },
48 + endPoint: {
49 + // 结束点
50 + x: 500,
51 + y: 50,
52 + },
53 + type: 'polyline',
54 + text: 'polyline',
55 + },
56 + {
57 + sourceNodeId: '2',
58 + targetNodeId: '3',
59 + type: 'line',
60 + text: 'line',
61 + },
62 + {
63 + sourceNodeId: '2',
64 + targetNodeId: '4',
65 + type: 'bezier',
66 + text: 'bezier',
67 + },
68 + ],
69 +};
70 +
71 +export default data;
1 +/*
2 + * @Date: 2025-03-12 12:02:21
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 12:02:27
5 + * @FilePath: /logic-flow2/src/views/edge/data2.js
6 + * @Description: 文件描述
7 + */
8 +const data = {
9 + nodes: [
10 + {
11 + id: '1',
12 + type: 'rect',
13 + x: 100,
14 + y: 100,
15 + text: '矩形',
16 + },
17 + {
18 + id: '2',
19 + type: 'circle',
20 + x: 300,
21 + y: 100,
22 + text: '圆形',
23 + },
24 + {
25 + id: '3',
26 + type: 'ellipse',
27 + x: 500,
28 + y: 100,
29 + text: '椭圆',
30 + },
31 + {
32 + id: '4',
33 + type: 'polygon',
34 + x: 100,
35 + y: 250,
36 + text: '多边形',
37 + },
38 + {
39 + id: '5',
40 + type: 'diamond',
41 + x: 300,
42 + y: 250,
43 + text: '菱形',
44 + },
45 + {
46 + id: '6',
47 + type: 'text',
48 + x: 500,
49 + y: 250,
50 + text: '纯文本节点',
51 + },
52 + ],
53 + edges: [
54 + {
55 + id: '10',
56 + sourceNodeId: '1',
57 + targetNodeId: '3',
58 + startPoint: {
59 + x: 100,
60 + y: 60,
61 + },
62 + endPoint: {
63 + x: 500,
64 + y: 50,
65 + },
66 + text: 'sequence',
67 + type: 'sequence',
68 + properties: {
69 + isStrokeDashed: true, // 是否虚线
70 + },
71 + },
72 + {
73 + sourceNodeId: '3',
74 + targetNodeId: '4',
75 + type: 'line',
76 + },
77 + {
78 + sourceNodeId: '3',
79 + targetNodeId: '5',
80 + type: 'line',
81 + },
82 + ],
83 +};
84 +
85 +export default data;
1 +/*
2 + * @Date: 2025-03-12 14:36:57
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 15:22:29
5 + * @FilePath: /logic-flow2/src/views/edge/data3.js
6 + * @Description: 文件描述
7 + */
8 +const data = {
9 + nodes: [
10 + {
11 + id: 'rect_1',
12 + type: 'rect',
13 + x: 150,
14 + y: 100,
15 + text: 'rect',
16 + },
17 + {
18 + id: 'circle_1',
19 + type: 'circle',
20 + x: 450,
21 + y: 300,
22 + text: 'circle',
23 + },
24 + {
25 + id: '3',
26 + type: 'ellipse',
27 + x: 500,
28 + y: 100,
29 + text: '椭圆',
30 + },
31 + {
32 + id: '4',
33 + type: 'polygon',
34 + x: 100,
35 + y: 250,
36 + text: '多边形',
37 + },
38 + {
39 + id: '5',
40 + type: 'diamond',
41 + x: 300,
42 + y: 250,
43 + text: '菱形',
44 + },
45 + ],
46 + edges: [
47 + {
48 + sourceNodeId: 'rect_1',
49 + targetNodeId: 'circle_1',
50 + type: 'custom-edge',
51 + text: '连线文本',
52 + },
53 + ],
54 +};
55 +
56 +export default data;
1 +/*
2 + * @Date: 2025-03-12 15:30:01
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 15:30:10
5 + * @FilePath: /logic-flow2/src/views/edge/data4.js
6 + * @Description: 文件描述
7 + */
8 +export default {
9 + nodes: [
10 + {
11 + id: 'rect1',
12 + type: 'rect',
13 + x: 100,
14 + y: 100,
15 + text: 'rect1',
16 + },
17 + {
18 + id: 'rect2',
19 + type: 'rect',
20 + x: 500,
21 + y: 100,
22 + text: 'rect2',
23 + },
24 + {
25 + id: 'rect3',
26 + type: 'rect',
27 + x: 100,
28 + y: 300,
29 + text: 'rect3',
30 + },
31 + {
32 + id: 'rect4',
33 + type: 'rect',
34 + x: 500,
35 + y: 300,
36 + text: 'rect4',
37 + },
38 + ],
39 + edges: [
40 + {
41 + id: 'customArrow1',
42 + type: 'custom-arrow',
43 + sourceNodeId: 'rect1',
44 + targetNodeId: 'rect2',
45 + properties: {
46 + arrowType: 'empty',
47 + },
48 + text: '空心箭头',
49 + },
50 + {
51 + id: 'customArrow2',
52 + type: 'custom-arrow',
53 + sourceNodeId: 'rect3',
54 + targetNodeId: 'rect4',
55 + properties: {
56 + arrowType: 'half',
57 + },
58 + text: '半箭头',
59 + },
60 + ],
61 +};
1 +.helloworld-app {
2 + width: 100%;
3 +
4 + .app-content {
5 + height: 380px;
6 + }
7 +}
8 +
9 +.viewport {
10 + position: relative;
11 + height: 80vh;
12 + overflow: hidden;
13 +}
1 +<!--
2 + * @Date: 2025-03-10 16:52:35
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 11:05:27
5 + * @FilePath: /logic-flow2/src/views/edge/index.vue
6 + * @Description: 拖拽面板
7 +-->
8 +<template>
9 + <div class="container">
10 + <div ref="container" class="flow-container"></div>
11 + </div>
12 +</template>
13 +
14 +<script setup>
15 +import LogicFlow from '@logicflow/core';
16 +import data from './data';
17 +import './index.less';
18 +
19 +const SilentConfig = {
20 + stopScrollGraph: true,
21 + stopMoveGraph: true,
22 + stopZoomGraph: true,
23 +};
24 +
25 +const container = ref(null);
26 +let lf = null;
27 +
28 +onMounted(() => {
29 + lf = new LogicFlow({
30 + container: container.value,
31 + grid: true,
32 + });
33 +
34 + lf.render(data);
35 + lf.translateCenter();
36 +});
37 +</script>
38 +
39 +
40 +<style scoped>
41 +.container {
42 + width: 100vw;
43 + height: 100vh;
44 + display: flex;
45 + flex-direction: column;
46 +}
47 +
48 +.flow-container {
49 + flex: 1;
50 + width: 100%;
51 + height: 100%;
52 +}
53 +</style>
1 +/*
2 + * @Date: 2025-03-12 11:59:15
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 12:01:40
5 + * @FilePath: /logic-flow2/src/views/edge/sequence.js
6 + * @Description: 文件描述
7 + */
8 +import { PolylineEdge, PolylineEdgeModel } from '@logicflow/core'
9 +
10 +class SequenceModel extends PolylineEdgeModel {
11 + // 设置边样式
12 + getEdgeStyle() {
13 + const style = super.getEdgeStyle()
14 + const { properties } = this
15 + if (properties.isStrokeDashed) {
16 + style.strokeDasharray = '4, 4'
17 + }
18 + style.stroke = 'orange'
19 + return style
20 + }
21 +
22 + // 设置边文本样式
23 + getTextStyle() {
24 + const style = super.getTextStyle()
25 + style.color = '#3451F1'
26 + style.fontSize = 20
27 + style.background = Object.assign({}, style.background, {
28 + fill: '#F2F131',
29 + })
30 + return style
31 + }
32 +
33 + // 设置 hover 轮廓样式
34 + getOutlineStyle() {
35 + const style = super.getOutlineStyle()
36 + style.stroke = 'blue'
37 + return style
38 + }
39 +}
40 +
41 +export default {
42 + type: 'sequence',
43 + view: PolylineEdge,
44 + model: SequenceModel,
45 +}
1 +<!--
2 + * @Date: 2025-03-10 16:52:35
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-12 15:25:22
5 + * @FilePath: /logic-flow2/src/views/edge/text.vue
6 + * @Description: 自定义边文本位置
7 +-->
8 +<template>
9 + <div class="container">
10 + <div ref="container" class="flow-container"></div>
11 + </div>
12 +</template>
13 +
14 +<script setup>
15 +import LogicFlow from "@logicflow/core";
16 +import customEdge from "./customEdge";
17 +import data from "./data3";
18 +
19 +const SilentConfig = {
20 + stopScrollGraph: true,
21 + stopMoveGraph: true,
22 + stopZoomGraph: true,
23 +};
24 +
25 +const container = ref(null);
26 +let lf = null;
27 +
28 +onMounted(() => {
29 + lf = new LogicFlow({
30 + container: container.value,
31 + grid: true,
32 + ...SilentConfig,
33 + // 手动设置默认边
34 + edgeType: "bezier",
35 + // 移动已有边时会有 currentEdge 信息, 否则为空
36 + edgeGenerator: (sourceNode, targetNode, currentEdge) => {
37 + // 起始节点类型 rect 时使用 自定义的边 custom-edge
38 + if (sourceNode.type === "rect") return "custom-edge";
39 + },
40 + });
41 +
42 + lf.register(customEdge);
43 + lf.setDefaultEdgeType("custom-edge");
44 +
45 + lf.setTheme({
46 + edgeText: {
47 + textWidth: 100,
48 + overflowMode: "autoWrap",
49 + fontSize: 14,
50 + background: {
51 + fill: "red",
52 + },
53 + },
54 + arrow: {
55 + offset: 4, // 箭头垂线长度
56 + verticalLength: 2, // 箭头底线长度
57 + },
58 + });
59 +
60 + lf.render(data);
61 + lf.translateCenter();
62 +});
63 +</script>
64 +
65 +<style>
66 +.container {
67 + width: 100vw;
68 + height: 100vh;
69 + display: flex;
70 + flex-direction: column;
71 +}
72 +
73 +.flow-container {
74 + flex: 1;
75 + width: 100%;
76 + height: 100%;
77 +}
78 +
79 +:deep(.custom-text) {
80 + font-size: 14px !important;
81 + fill: #333 !important; /* 使用 fill 替代 color */
82 + background-color: #fff !important;
83 + padding: 4px 8px !important;
84 + border-radius: 2px !important;
85 +}
86 +</style>
1 <!-- 1 <!--
2 * @Date: 2025-03-10 14:37:31 2 * @Date: 2025-03-10 14:37:31
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-03-11 17:46:33 4 + * @LastEditTime: 2025-03-12 15:31:05
5 * @FilePath: /logic-flow2/src/views/home.vue 5 * @FilePath: /logic-flow2/src/views/home.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
13 <el-button type="primary" @click="goTo('node-model')">node-model</el-button> 13 <el-button type="primary" @click="goTo('node-model')">node-model</el-button>
14 <el-button type="primary" @click="goTo('node-view')">node-view</el-button> 14 <el-button type="primary" @click="goTo('node-view')">node-view</el-button>
15 <el-button type="primary" @click="goTo('node-vue')">node-vue</el-button> 15 <el-button type="primary" @click="goTo('node-vue')">node-vue</el-button>
16 + <el-button type="primary" @click="goTo('edge')">edge</el-button>
17 + <el-button type="primary" @click="goTo('edge-custom')">edge-custom</el-button>
18 + <el-button type="primary" @click="goTo('edge-text')">edge-text</el-button>
19 + <el-button type="primary" @click="goTo('edge-arrow')">edge-arrow</el-button>
16 </template> 20 </template>
17 21
18 <script setup> 22 <script setup>
......