You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.5 KiB

9 months ago
  1. import dagre from 'dagre';
  2. const edgeType = 'smoothstep';
  3. export const flattenTree = (tree) => {
  4. let stack = [tree];
  5. let nodes = [];
  6. let edges = [];
  7. while (stack.length > 0) {
  8. let node = stack.pop();
  9. nodes.push({ id: node.id, data: { ...node, label: `${node.name}` }, position: node.position });
  10. if (node.children && node.children.length > 0) {
  11. node.children.map(item => {
  12. edges.push({ source: node.id, target: item.id, id: item.id, type: edgeType, animated: true });
  13. stack.unshift(item);
  14. });
  15. };
  16. };
  17. return { nodes, edges };
  18. };
  19. export const getLayoutedElements = (nodes, edges, direction = 'TB') => {
  20. const dagreGraph = new dagre.graphlib.Graph();
  21. dagreGraph.setDefaultEdgeLabel(() => ({}));
  22. const nodeWidth = 172;
  23. const nodeHeight = 36;
  24. const isHorizontal = direction === 'LR';
  25. dagreGraph.setGraph({ rankdir: direction });
  26. nodes.forEach((node: any) => {
  27. dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
  28. });
  29. edges.forEach((edge: any) => {
  30. dagreGraph.setEdge(edge.source, edge.target);
  31. });
  32. dagre.layout(dagreGraph);
  33. nodes.forEach((node: any) => {
  34. const nodeWithPosition = dagreGraph.node(node.id);
  35. node.targetPosition = isHorizontal ? 'left' : 'top';
  36. node.sourcePosition = isHorizontal ? 'right' : 'bottom';
  37. node.position = {
  38. x: nodeWithPosition.x - nodeWidth / 2,
  39. y: nodeWithPosition.y - nodeHeight / 2,
  40. };
  41. return node;
  42. });
  43. return { nodes, edges };
  44. };