treeDiagram.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { TopicType } from "@/enum";
  2. import { MindMapProjectInfo, TopicItem, HierarchyResult } from "@/types";
  3. const DISTANCE = 20; // 子节点相对于父节点的偏差
  4. function firstWalk(node: TopicItem): HierarchyResult {
  5. const root: HierarchyResult = {
  6. x: 0,
  7. y: 0,
  8. totalHeight: 0,
  9. totalWidth: 0,
  10. width: node.width,
  11. height: node.height,
  12. id: node.id,
  13. data: node,
  14. children: [],
  15. };
  16. root.children = node.collapsed ? [] : node.children?.map((child) => firstWalk(child)) || [];
  17. return root;
  18. }
  19. // 设置宽高
  20. function secondWalk(
  21. node: HierarchyResult,
  22. pageSetting: MindMapProjectInfo["pageSetting"]
  23. ) {
  24. let totalHeight = node.height;
  25. let totalWidth = node.data.type === TopicType.main ? 0 : node.width;
  26. if (node.children?.length) {
  27. node.children.forEach((c: HierarchyResult, index) => {
  28. const childSize = secondWalk(c, pageSetting);
  29. // const offsetY = node.data.type === TopicType.main ? pageSetting.branchY : pageSetting.subTopicY;
  30. // 总的高度 = 自身高度 + 子节点的高度 + 节点之间的距离
  31. totalHeight += childSize.height + pageSetting.branchY;
  32. if (node.data.type === TopicType.main) {
  33. const offsetX = index < node.children.length - 1 ? pageSetting.branchX : 0;
  34. totalWidth += childSize.width + offsetX;
  35. } else {
  36. // 总的宽度 = 子节点的宽度与自身宽度取最大值
  37. totalWidth = Math.max(DISTANCE + childSize.width, totalWidth);
  38. }
  39. });
  40. }
  41. node.totalHeight = totalHeight;
  42. node.totalWidth = totalWidth;
  43. return {
  44. height: totalHeight,
  45. width: Math.max(totalWidth, node.width),
  46. };
  47. }
  48. function thirdWalk(node: HierarchyResult, pageSetting: MindMapProjectInfo['pageSetting']) {
  49. let startX = node.width / 2 - node.totalWidth / 2;
  50. node.children.forEach((child) => {
  51. child.y = node.y + node.height + pageSetting.branchY;
  52. child.x = startX;
  53. startX += child.totalWidth + pageSetting.branchX;
  54. fourthWalk(child, pageSetting);
  55. });
  56. }
  57. function fourthWalk(node: HierarchyResult, pageSetting: MindMapProjectInfo['pageSetting']) {
  58. let startY = node.y + node.height + pageSetting.branchY;
  59. node.children.forEach((child) => {
  60. child.y = startY;
  61. child.x = node.x + DISTANCE;
  62. startY += child.totalHeight + pageSetting.branchY;
  63. if(child.children.length) {
  64. fourthWalk(child, pageSetting);
  65. }
  66. });
  67. }
  68. export const getTreeDiagramHierarchy = <K>(
  69. topic: TopicItem,
  70. pageSetting: MindMapProjectInfo["pageSetting"]
  71. ): K => {
  72. const root = firstWalk(topic);
  73. secondWalk(root, pageSetting);
  74. thirdWalk(root, pageSetting);
  75. console.log(root);
  76. return root as K;
  77. };