Showing
14 changed files
with
763 additions
and
3 deletions
| 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 | ... | ... |
src/views/edge/arrow.vue
0 → 100644
| 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> |
src/views/edge/custom.vue
0 → 100644
| 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> |
src/views/edge/customArrow.js
0 → 100644
| 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 | +}; |
src/views/edge/customEdge.js
0 → 100644
| 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 | +} |
src/views/edge/data.js
0 → 100644
| 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; |
src/views/edge/data2.js
0 → 100644
| 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; |
src/views/edge/data3.js
0 → 100644
| 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; |
src/views/edge/data4.js
0 → 100644
| 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 | +}; |
src/views/edge/index.less
0 → 100644
src/views/edge/index.vue
0 → 100644
| 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> |
src/views/edge/sequence.js
0 → 100644
| 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 | +} |
src/views/edge/text.vue
0 → 100644
| 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> | ... | ... |
-
Please register or login to post a comment