Переглянути джерело

feat: 添加组织结构图

liaojiaxing 6 місяців тому
батько
коміт
bb096350e6

+ 45 - 6
apps/designer/src/pages/mindmap/edge.ts

@@ -167,14 +167,45 @@ Graph.registerConnector(
   true
 );
 
+// 组织结构
+Graph.registerConnector(
+  "organization-branch-connector",
+  function (sourcePoint, targetPoint, routerPoints, options) {
+    const pathData = `
+     M ${sourcePoint.x} ${sourcePoint.y}
+     L ${sourcePoint.x} ${sourcePoint.y + 10}
+     L ${targetPoint.x} ${sourcePoint.y + 10}
+     L ${targetPoint.x} ${targetPoint.y}
+    `;
+    return options.raw ? Path.parse(pathData) : pathData;
+  },
+  true
+);
+Graph.registerConnector(
+  "organization-sub-connector",
+  function (sourcePoint, targetPoint, routerPoints, options) {
+    const pathData = `
+     M ${sourcePoint.x} ${sourcePoint.y}
+     L ${sourcePoint.x} ${sourcePoint.y + 10}
+     L ${targetPoint.x} ${sourcePoint.y + 10}
+     L ${targetPoint.x} ${targetPoint.y}
+    `;
+    return options.raw ? Path.parse(pathData) : pathData;
+  },
+  true
+);
+
 const getConnector = (
   structure: StructureType,
   theme: string,
   type: TopicType
 ) => {
   // TODO根据结构处理连接线
-  if(structure === StructureType.tree) {
-    return `tree-${type}-connector`
+  if (structure === StructureType.tree) {
+    return `tree-${type}-connector`;
+  }
+  if (structure === StructureType.organization) {
+    return `organization-${type}-connector`;
   }
   const themeObj = getTheme(theme);
   if (type === TopicType.branch) {
@@ -211,8 +242,8 @@ const getSourceAnchor = (type: TopicType, structure: StructureType) => {
         ? {
             name: "bottom",
             args: {
-              dy: -5
-            }
+              dy: -5,
+            },
           }
         : {
             name: "bottomLeft",
@@ -221,10 +252,14 @@ const getSourceAnchor = (type: TopicType, structure: StructureType) => {
             },
           };
     }
+    case StructureType.organization: {
+      return {
+        name: "bottom",
+      };
+    }
     case StructureType.leftBracket:
     case StructureType.leftFishbone:
     case StructureType.leftTreeShape:
-    case StructureType.organization:
     case StructureType.rightBracket:
     case StructureType.rightFishbone:
     case StructureType.rightTreeShape:
@@ -258,10 +293,14 @@ const getTargetAnchor = (type: TopicType, structure: StructureType) => {
             name: "left",
           };
     }
+    case StructureType.organization: {
+      return {
+        name: "top",
+      };
+    }
     case StructureType.leftBracket:
     case StructureType.leftFishbone:
     case StructureType.leftTreeShape:
-    case StructureType.organization:
     case StructureType.rightBracket:
     case StructureType.rightFishbone:
     case StructureType.rightTreeShape:

+ 5 - 0
apps/designer/src/pages/mindmap/hierarchy.ts

@@ -2,6 +2,7 @@ import { StructureType, TopicType } from "@/enum";
 import { MindMapProjectInfo, TopicItem } from "@/types";
 import Hierarchy from "@antv/hierarchy";
 import { getTreeStructure } from "@/utils/hierarchy/tree";
+import { getOrganization } from "@/utils/hierarchy/organization";
 
 // 思维导图结构实现
 export const hierarchyMethodMap: Record<
@@ -83,5 +84,9 @@ export const hierarchyMethodMap: Record<
   // 树状结构
   [StructureType.tree]: <T>(topic: TopicItem, pageSetting: MindMapProjectInfo['pageSetting']): T => {
     return getTreeStructure<T>(topic, pageSetting);
+  },
+  // 组织结构
+  [StructureType.organization]: <T>(topic: TopicItem, pageSetting: MindMapProjectInfo['pageSetting']): T => {
+    return getOrganization<T>(topic, pageSetting);
   }
 };

+ 75 - 0
apps/designer/src/utils/hierarchy/organization.ts

@@ -0,0 +1,75 @@
+import { TopicType } from "@/enum";
+import { MindMapProjectInfo, TopicItem, HierarchyResult } from "@/types";
+
+function firstWalk(node: TopicItem): HierarchyResult {
+  const root: HierarchyResult = {
+    x: 0,
+    y: 0,
+    totalHeight: 0,
+    totalWidth: 0,
+    width: node.width,
+    height: node.height,
+    id: node.id,
+    data: node,
+    children: [],
+  };
+
+  root.children = node.children?.map((child) => firstWalk(child)) || [];
+
+  return root;
+}
+
+// 设置宽高
+function secondWalk(
+  node: HierarchyResult,
+  pageSetting: MindMapProjectInfo["pageSetting"]
+) {
+  let totalHeight = node.height;
+  let totalWidth = 0;
+  if (node.children?.length) {
+    node.children.forEach((c: HierarchyResult, index) => {
+      const childSize = secondWalk(c, pageSetting);
+      const offsetY = node.data.type === TopicType.main ? pageSetting.branchY :  pageSetting.subTopicY;
+      // 总的高度 = 自身高度 + 子节点的高度 + 节点之间的距离
+      totalHeight += childSize.height + offsetY;
+      
+      const offsetX = index < node.children.length - 1 ? pageSetting.branchX : 0;
+      totalWidth += childSize.width + offsetX;
+    });
+  }
+  node.totalHeight = totalHeight;
+  node.totalWidth =  Math.max(totalWidth, node.width);
+
+  return {
+    height: totalHeight,
+    width: Math.max(totalWidth, node.width),
+  };
+}
+
+function thirdWalk(node: HierarchyResult, pageSetting: MindMapProjectInfo['pageSetting']) {
+  let startX = node.x + node.width / 2 - node.totalWidth / 2;
+  // const offsetX = node.data.type === TopicType.main ? pageSetting.branchX : pageSetting.subTopicX;
+  // const offsetY = node.data.type === TopicType.main ? pageSetting.branchY : pageSetting.subTopicY;
+  node.children.forEach((child) => {
+    child.y = node.y + node.height + pageSetting.branchY;
+    if(node.children.length === 1) {
+      child.x = startX + node.totalWidth / 2 - child.width / 2;
+    } else {
+      child.x = startX + child.totalWidth / 2 - child.width / 2;
+    }
+    startX += child.totalWidth + pageSetting.branchX;
+    thirdWalk(child, pageSetting);
+  });
+}
+
+
+export const getOrganization = <K>(
+  topic: TopicItem,
+  pageSetting: MindMapProjectInfo["pageSetting"]
+): K => {
+  const root = firstWalk(topic);
+  secondWalk(root, pageSetting);
+  thirdWalk(root, pageSetting);
+  console.log(root);
+  return root as K;
+};

+ 5 - 5
apps/designer/src/utils/hierarchy/tree.ts

@@ -30,9 +30,9 @@ function secondWalk(
   if (node.children?.length) {
     node.children.forEach((c: HierarchyResult, index) => {
       const childSize = secondWalk(c, pageSetting);
-      const offsetY = node.data.type === TopicType.main ? pageSetting.branchY :  pageSetting.subTopicY;
+      // const offsetY = node.data.type === TopicType.main ? pageSetting.branchY :  pageSetting.subTopicY;
       // 总的高度 = 自身高度 + 子节点的高度 + 节点之间的距离
-      totalHeight += childSize.height + offsetY;
+      totalHeight += childSize.height + pageSetting.branchY;
       
       if (node.data.type === TopicType.main) {
         const offsetX = index < node.children.length - 1 ? pageSetting.branchX : 0;
@@ -57,17 +57,17 @@ function thirdWalk(node: HierarchyResult, pageSetting: MindMapProjectInfo['pageS
   node.children.forEach((child) => {
     child.y = node.y + node.height + pageSetting.branchY;
     child.x = startX;
-    startX += child.totalWidth + pageSetting.subTopicX;
+    startX += child.totalWidth + pageSetting.branchX;
     fourthWalk(child, pageSetting);
   });
 }
 
 function fourthWalk(node: HierarchyResult, pageSetting: MindMapProjectInfo['pageSetting']) {
-  let startY = node.y + node.height + pageSetting.subTopicY;
+  let startY = node.y + node.height + pageSetting.branchY;
   node.children.forEach((child) => {
     child.y = startY;
     child.x = node.x + DISTANCE;
-    startY += child.totalHeight + pageSetting.subTopicY;
+    startY += child.totalHeight + pageSetting.branchY;
     if(child.children.length) {
       fourthWalk(child, pageSetting);
     }