222
schangxiang@126.com
2025-04-30 9bec4dcae002f36aa23231da11cb03a156b40110
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// @ts-nocheck
import Hierarchy from '@antv/hierarchy'
let NODE_SIZE = 0
let FIRST_ROOT_X = 100
let FIRST_ROOT_Y = 100
export const graphToTree = (graphData: { nodes: any[]; edges: any[] }) => {
  let tree = null
  const nodesMap = new Map()
  graphData.nodes.forEach((node) => {
    const treeNode = {
      ...node,
      children: [],
    }
    nodesMap.set(node.id, treeNode)
    if (node.type === 'ROOT_NODE') {
      tree = treeNode
    }
  })
  graphData.edges.forEach((edge) => {
    const node = nodesMap.get(edge.sourceNodeId)
    node.children.push(nodesMap.get(edge.targetNodeId))
  })
  return tree
}
 
export const dfsTree = (tree, callback) => {
  const newTree = callback(tree)
  if (tree.children && tree.children.length > 0) {
    newTree.children = tree.children.map((treeNode) =>
      dfsTree(treeNode, callback)
    )
  }
  return newTree
}
export const layoutTree = (tree) => {
  if (!tree || !tree.children || tree.children.length === 0) return tree
  const PEM = 20
  tree.isRoot = true
  const rootNode = Hierarchy.compactBox(tree, {
    direction: 'LR',
    getId(d) {
      return d.id
    },
    getHeight(d) {
      if (d.type === 'ROOT_NODE') {
        return NODE_SIZE * 4
      }
      return NODE_SIZE
    },
    getWidth() {
      return 200 + PEM * 1.6
    },
    getHGap() {
      return PEM
    },
    getVGap() {
      return PEM
    },
    getSubTreeSep(d) {
      if (!d.children || !d.children.length) {
        return 0
      }
      return PEM
    },
  })
  const x = tree.x || FIRST_ROOT_X
  const y = tree.y || FIRST_ROOT_Y
  const x1 = rootNode.x
  const y1 = rootNode.y
  const moveX = x - x1
  const moveY = y - y1
  const newTree = dfsTree(rootNode, (currentNode) => {
    return {
      id: currentNode.id,
      properties: currentNode.data.properties,
      type: currentNode.data.type,
      x: currentNode.x + moveX,
      y: currentNode.y + moveY,
    }
  })
  return newTree
}
 
export const treeToGraph = (rootNode: any) => {
  const nodes: any[] = []
  const edges: any[] = []
  function getNode(current: any, parent = null) {
    const node = {
      ...current,
    }
    nodes.push(node)
    if (current.children && current.children.length) {
      current.children.forEach((subNode: any) => {
        getNode(subNode, node)
      })
    }
    if (parent) {
      const edge = {
        sourceNodeId: parent.id,
        targetNodeId: node.id,
        type: 'polyline',
      }
      edges.push(edge)
    }
  }
  getNode(rootNode)
  return {
    nodes,
    edges,
  }
}
 
/**
 * 布局
 * @param graphData
 * @returns
 */
export const getLayoutData = (graphData: any) => {
  NODE_SIZE = graphData.nodes.length
  const tree = graphToTree(graphData)
  console.log(graphData, 'graphData---')
  tree.isRoot = true
 
  const newTree = layoutTree(tree)
  return treeToGraph(newTree)
}