From 63dfe7e9481dfd20c8381a1094bc5a30d122f220 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 22 Jul 2026 14:32:15 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=E5=B7=A5=E8=89=BA=E8=B7=AF=E7=BA=BF?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E7=BB=9F=E4=B8=80=E5=88=B0Vue=20Flow?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E8=A7=86=E5=9B=BEscFlowViewer,=E4=B8=8E?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E5=85=B1=E7=94=A8MaterialNode?= =?UTF-8?q?=E8=8A=82=E7=82=B9/dagre=E5=B8=83=E5=B1=80;route=5Fshow?= =?UTF-8?q?=E4=B8=8Eroute=E9=A1=B5=E5=BC=83=E7=94=A8dagre-d3=E7=89=88scDeg?= =?UTF-8?q?ra?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- src/components/flow/MaterialNode.vue | 106 +++++++++++++++++++ src/components/flow/dagreLayout.js | 24 +++++ src/components/scFlowEditor.vue | 115 ++------------------- src/components/scFlowViewer.vue | 147 +++++++++++++++++++++++++++ src/views/mtm/route.vue | 14 +-- src/views/mtm/route_show.vue | 19 ++-- 6 files changed, 303 insertions(+), 122 deletions(-) create mode 100644 src/components/flow/MaterialNode.vue create mode 100644 src/components/flow/dagreLayout.js create mode 100644 src/components/scFlowViewer.vue diff --git a/src/components/flow/MaterialNode.vue b/src/components/flow/MaterialNode.vue new file mode 100644 index 00000000..ca8d3cbf --- /dev/null +++ b/src/components/flow/MaterialNode.vue @@ -0,0 +1,106 @@ + + + + + + + diff --git a/src/components/flow/dagreLayout.js b/src/components/flow/dagreLayout.js new file mode 100644 index 00000000..a7275036 --- /dev/null +++ b/src/components/flow/dagreLayout.js @@ -0,0 +1,24 @@ +import dagre from "dagre"; + +export const NODE_W = 150; +export const NODE_H = 54; + +/** + * dagre 自动布局,返回带 position 的 nodes + * @param {Array} nodes Vue Flow 节点(id 必须为字符串) + * @param {Array} edges Vue Flow 边 + * @param {Object} opts { rankdir: TB|BT|LR|RL, nodeW, nodeH } + */ +export function layoutGraph(nodes, edges, opts = {}) { + const { rankdir = "TB", nodeW = NODE_W, nodeH = NODE_H } = opts; + const g = new dagre.graphlib.Graph(); + g.setGraph({ rankdir, nodesep: 30, ranksep: 56, marginx: 20, marginy: 20 }); + g.setDefaultEdgeLabel(() => ({})); + nodes.forEach((n) => g.setNode(n.id, { width: nodeW, height: nodeH })); + edges.forEach((e) => g.setEdge(e.source, e.target)); + dagre.layout(g); + return nodes.map((n) => { + const gn = g.node(n.id); + return { ...n, position: { x: gn.x - nodeW / 2, y: gn.y - nodeH / 2 } }; + }); +} diff --git a/src/components/scFlowEditor.vue b/src/components/scFlowEditor.vue index 668467ef..2c9a8afc 100644 --- a/src/components/scFlowEditor.vue +++ b/src/components/scFlowEditor.vue @@ -72,14 +72,9 @@ @edge-context-menu="onEdgeContextMenu" @node-context-menu="onNodeContextMenu" > - + @@ -105,24 +100,22 @@ + + + + diff --git a/src/views/mtm/route.vue b/src/views/mtm/route.vue index b6fe9275..f733e2bd 100644 --- a/src/views/mtm/route.vue +++ b/src/views/mtm/route.vue @@ -17,14 +17,7 @@ - - + @@ -130,6 +123,9 @@