shaogen1995 il y a 2 jours
Parent
commit
1db87e47d9

+ 37 - 0
project/package-lock.json

@@ -26,6 +26,7 @@
         "classnames": "^2.5.1",
         "crypto-js": "^4.2.0",
         "d3": "^7.9.0",
+        "dagre": "^0.8.5",
         "media-chrome": "^4.15.1",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
@@ -7457,6 +7458,16 @@
         "node": ">=12"
       }
     },
+    "node_modules/dagre": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmmirror.com/dagre/-/dagre-0.8.5.tgz",
+      "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
+      "license": "MIT",
+      "dependencies": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      }
+    },
     "node_modules/damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -9687,6 +9698,15 @@
       "resolved": "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
       "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
     },
+    "node_modules/graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmmirror.com/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "license": "MIT",
+      "dependencies": {
+        "lodash": "^4.17.15"
+      }
+    },
     "node_modules/gzip-size": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz",
@@ -24573,6 +24593,15 @@
         "d3-transition": "2 - 3"
       }
     },
+    "dagre": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmmirror.com/dagre/-/dagre-0.8.5.tgz",
+      "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
+      "requires": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      }
+    },
     "damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -26298,6 +26327,14 @@
       "resolved": "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
       "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
     },
+    "graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmmirror.com/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "requires": {
+        "lodash": "^4.17.15"
+      }
+    },
     "gzip-size": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz",

+ 1 - 0
project/package.json

@@ -21,6 +21,7 @@
     "classnames": "^2.5.1",
     "crypto-js": "^4.2.0",
     "d3": "^7.9.0",
+    "dagre": "^0.8.5",
     "media-chrome": "^4.15.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",

+ 88 - 18
project/src/pages/A5view/PageSon/A5atlas/index.tsx

@@ -2,10 +2,10 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'
 import styles from './index.module.scss'
 import { infoPageIDGet } from '@/utils/locStore'
 import history from '@/utils/history'
-
 import { baseOssUrl } from '@/utils/http'
 import { urlCanRes } from '@/utils/urlCan'
 import classNames from 'classnames'
+import dagre from 'dagre'
 
 import {
   ReactFlow,
@@ -18,9 +18,10 @@ import {
 } from '@xyflow/react'
 import '@xyflow/react/dist/style.css'
 
+const layoutDirection = 'TB'
+
 function FlowChart() {
   const { fitView } = useReactFlow() // 获取 fitView 方法
-
   // 每个组件
   const Row = useCallback((item: any) => {
     return (
@@ -33,10 +34,11 @@ function FlowChart() {
     )
   }, [])
 
-  const initnode: any[] = useMemo(() => {
+  // 创建不带位置的初始节点
+  const initialNodesWithoutPosition: any[] = useMemo(() => {
     return cardNames.map(v => ({
       id: v.id + '',
-      position: v.position,
+      // position: v.position,
       data: { label: Row(v) },
       draggable: true
     }))
@@ -69,19 +71,87 @@ function FlowChart() {
   }, [])
 
   // 使用状态管理节点和边
-  const [nodes, setNodes, onNodesChange] = useNodesState(initnode)
-  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges)
-
-  // 重置功能
-  const handleReset = useCallback(() => {
-    // 重置节点和边
-    setNodes(initnode)
-    setEdges(initialEdges)
-    // 重置视图到初始大小和位置
-    setTimeout(() => {
-      fitView({ duration: 300 }) // 添加动画效果,300ms
-    }, 0)
-  }, [setNodes, initnode, setEdges, initialEdges, fitView])
+  const [nodes, setNodes, onNodesChange] = useNodesState([] as any[])
+  const [edges, setEdges, onEdgesChange] = useEdgesState([] as any[])
+
+  // 自动布局函数
+  const applyAutoLayout = useCallback((nodes: any[], edges: any[], direction: string = 'TB') => {
+    // 创建 dagre 图
+    const dagreGraph = new dagre.graphlib.Graph()
+    dagreGraph.setDefaultEdgeLabel(() => ({}))
+
+    // 设置布局选项
+    const nodeWidth = 250
+    const nodeHeight = 295
+
+    // 根据方向设置布局参数
+    const isHorizontal = direction === 'LR' || direction === 'RL'
+    dagreGraph.setGraph({
+      rankdir: direction,
+      nodesep: 100, // 节点间距
+      ranksep: 100, // 层级间距
+      marginx: 20,
+      marginy: 20
+    })
+
+    // 添加节点到 dagre 图
+    nodes.forEach(node => {
+      dagreGraph.setNode(node.id, {
+        width: nodeWidth,
+        height: nodeHeight
+      })
+    })
+
+    // 添加边到 dagre 图
+    edges.forEach(edge => {
+      if (edge.source && edge.target) {
+        dagreGraph.setEdge(edge.source, edge.target)
+      }
+    })
+
+    // 计算布局
+    dagre.layout(dagreGraph)
+
+    // 转换节点位置
+    const layoutedNodes = nodes.map(node => {
+      const nodeWithPosition = dagreGraph.node(node.id)
+
+      return {
+        ...node,
+        targetPosition: isHorizontal ? 'left' : 'top',
+        sourcePosition: isHorizontal ? 'right' : 'bottom',
+        position: {
+          x: nodeWithPosition.x - nodeWidth / 2 + Math.random() * 10,
+          y: nodeWithPosition.y - nodeHeight / 2 + Math.random() * 10
+        }
+      }
+    })
+
+    return layoutedNodes
+  }, [])
+
+  // 初始化布局
+
+  const initFu = useCallback(() => {
+    if (initialNodesWithoutPosition.length > 0) {
+      const layoutedNodes = applyAutoLayout(
+        initialNodesWithoutPosition,
+        initialEdges,
+        layoutDirection
+      )
+      setNodes(layoutedNodes)
+      setEdges(initialEdges)
+
+      // 自适应视图
+      setTimeout(() => {
+        fitView({ duration: 300, padding: 0.1 })
+      }, 100)
+    }
+  }, [applyAutoLayout, fitView, initialEdges, initialNodesWithoutPosition, setEdges, setNodes])
+
+  useEffect(() => {
+    initFu()
+  }, [initFu])
 
   // 处理节点点击
   const onNodeClick = useCallback((event: React.MouseEvent, node: any) => {}, [])
@@ -101,7 +171,7 @@ function FlowChart() {
       </div>
 
       {/* 手动重置按钮 */}
-      <div className='A5Aback A5Aloding' onClick={handleReset}>
+      <div className='A5Aback A5Aloding' onClick={initFu}>
         <img src={require('@/assets/three/Reset.png')} alt='' />
         <div>重置</div>
       </div>

+ 4 - 0
project/src/pages/A5view/初始化组件/index.module.scss

@@ -0,0 +1,4 @@
+  .AAAAA {
+  :global {
+  }
+}

+ 13 - 0
project/src/pages/A5view/初始化组件/index.tsx

@@ -0,0 +1,13 @@
+import React from 'react'
+import styles from './index.module.scss'
+function AAAAA() {
+  return (
+    <div className={styles.AAAAA}>
+      <h1>AAAAA</h1>
+    </div>
+  )
+}
+
+const MemoAAAAA = React.memo(AAAAA)
+
+export default MemoAAAAA

+ 1 - 1
project/src/types/declaration.d.ts

@@ -6,7 +6,7 @@ declare module '*.gif'
 declare module '*.svg'
 declare module 'js-export-excel'
 declare module 'braft-utils'
-declare module 'react-virtualized'
+declare module 'dagre'
 declare const cardNames: any[]
 declare const baseOssUrl1: string
 declare const baseOssUrl2: string

+ 15 - 0
project/yarn.lock

@@ -4595,6 +4595,14 @@ d3@^7.9.0:
     d3-transition "3"
     d3-zoom "3"
 
+dagre@^0.8.5:
+  version "0.8.5"
+  resolved "https://registry.npmmirror.com/dagre/-/dagre-0.8.5.tgz"
+  integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
+  dependencies:
+    graphlib "^2.1.8"
+    lodash "^4.17.15"
+
 damerau-levenshtein@^1.0.8:
   version "1.0.8"
   resolved "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
@@ -5911,6 +5919,13 @@ grapheme-splitter@^1.0.4:
   resolved "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz"
   integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
 
+graphlib@^2.1.8:
+  version "2.1.8"
+  resolved "https://registry.npmmirror.com/graphlib/-/graphlib-2.1.8.tgz"
+  integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
+  dependencies:
+    lodash "^4.17.15"
+
 gzip-size@^6.0.0:
   version "6.0.0"
   resolved "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz"