|
@@ -1,11 +1,10 @@
|
|
|
-import { BorderSize, TopicType } from "@/enum";
|
|
|
+import { TopicType } from "@/enum";
|
|
|
import { MindMapProjectInfo, TopicItem } from "@/types";
|
|
|
import { Graph, Cell, Node } from "@antv/x6";
|
|
|
import TopicComponent from "@/components/mindMap/Topic";
|
|
|
-import Hierarchy from "@antv/hierarchy";
|
|
|
import { topicData } from "@/config/data";
|
|
|
import { uuid } from "@/utils";
|
|
|
-import { SetState } from "ahooks/lib/useSetState";
|
|
|
+import { hierarchyMethodMap } from "@/pages/mindmap/hierarchy";
|
|
|
|
|
|
interface HierarchyResult {
|
|
|
id: string;
|
|
@@ -28,52 +27,33 @@ export const renderMindMap = (
|
|
|
const cells: Cell[] = [];
|
|
|
topics.forEach((topic) => {
|
|
|
// 遍历出层次结构
|
|
|
- const result: HierarchyResult = Hierarchy.mindmap(topic, {
|
|
|
- direction: "H",
|
|
|
- getHeight(d: TopicItem) {
|
|
|
- return d.height;
|
|
|
- },
|
|
|
- getWidth(d: TopicItem) {
|
|
|
- return d.width;
|
|
|
- },
|
|
|
- getHGap(d: TopicItem) {
|
|
|
- if (d.type === TopicType.main) return pageSetting.branchX;
|
|
|
- if (d.type === TopicType.branch) return pageSetting.subTopicX;
|
|
|
- if (d.type === TopicType.sub) return pageSetting.subTopicX;
|
|
|
- return 40;
|
|
|
- },
|
|
|
- getVGap(d: TopicItem) {
|
|
|
- if (d.type === TopicType.main) return pageSetting.subTopicY;
|
|
|
- if (d.type === TopicType.branch) return pageSetting.subTopicY;
|
|
|
- if (d.type === TopicType.sub) return pageSetting.subTopicY;
|
|
|
- return 20;
|
|
|
- },
|
|
|
- getSide: () => {
|
|
|
- return "right";
|
|
|
- },
|
|
|
- });
|
|
|
+ const result: HierarchyResult = hierarchyMethodMap[projectInfo.mapType]?.(topic, pageSetting);
|
|
|
+ const originPosition = { x: topic?.x ?? -10, y: topic?.y ?? -10 };
|
|
|
+ const offsetX = originPosition.x - result.x;
|
|
|
+ const offsetY = originPosition.y - result.y;
|
|
|
const traverse = (
|
|
|
- hierarchyItem: HierarchyResult
|
|
|
+ hierarchyItem: HierarchyResult,
|
|
|
+ parent?: Node
|
|
|
) => {
|
|
|
if (hierarchyItem) {
|
|
|
const { data, children, x, y } = hierarchyItem;
|
|
|
const id = data?.id || uuid();
|
|
|
// 创建主题
|
|
|
- cells.push(
|
|
|
- graph.createNode({
|
|
|
- ...TopicComponent,
|
|
|
- width: data.width,
|
|
|
- height: data.height,
|
|
|
- data: {
|
|
|
- ...data,
|
|
|
- // 节点内部执行数据更新方法
|
|
|
- setMindProjectInfo,
|
|
|
- },
|
|
|
- id,
|
|
|
- x,
|
|
|
- y,
|
|
|
- })
|
|
|
- );
|
|
|
+ const node = graph.createNode({
|
|
|
+ ...TopicComponent,
|
|
|
+ width: data.width,
|
|
|
+ height: data.height,
|
|
|
+ data: {
|
|
|
+ ...data,
|
|
|
+ // 节点内部执行数据更新方法
|
|
|
+ setMindProjectInfo,
|
|
|
+ },
|
|
|
+ id,
|
|
|
+ x: offsetX + x,
|
|
|
+ y: offsetY + y,
|
|
|
+ });
|
|
|
+ cells.push(node);
|
|
|
+ parent && parent.addChild(node);
|
|
|
|
|
|
if (children) {
|
|
|
children.forEach((item: HierarchyResult) => {
|
|
@@ -99,7 +79,7 @@ export const renderMindMap = (
|
|
|
})
|
|
|
);
|
|
|
// 递归遍历
|
|
|
- traverse(item);
|
|
|
+ traverse(item, node);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
@@ -107,8 +87,8 @@ export const renderMindMap = (
|
|
|
|
|
|
traverse(result);
|
|
|
});
|
|
|
-
|
|
|
- cells.forEach((cell) => {
|
|
|
+ // 处理节点
|
|
|
+ cells.filter(cell => cell.isNode()).forEach((cell) => {
|
|
|
// 存在更新位置,否则添加
|
|
|
if (graph.hasCell(cell.id) && cell.isNode()) {
|
|
|
const oldCell = graph.getCellById(cell.id);
|
|
@@ -117,6 +97,16 @@ export const renderMindMap = (
|
|
|
graph.addCell(cell);
|
|
|
}
|
|
|
});
|
|
|
+ cells.filter(cell => cell.isEdge()).forEach((cell) => {
|
|
|
+ graph.addCell(cell);
|
|
|
+ })
|
|
|
+ const oldCells = graph.getCells();
|
|
|
+ // 移除不存在的节点
|
|
|
+ oldCells.forEach((cell) => {
|
|
|
+ if (!cells.find(item => cell.id === item.id)) {
|
|
|
+ graph.removeCell(cell);
|
|
|
+ }
|
|
|
+ });
|
|
|
// graph.centerContent();
|
|
|
};
|
|
|
|
|
@@ -124,33 +114,41 @@ export const renderMindMap = (
|
|
|
* 添加分支主题
|
|
|
*/
|
|
|
export const addTopic = (
|
|
|
- node: Node,
|
|
|
type: TopicType,
|
|
|
- otherData: Record<string, any> = {}
|
|
|
+ setMindProjectInfo: (info: MindMapProjectInfo) => void,
|
|
|
+ node?: Node,
|
|
|
+ otherData: Record<string, any> = {},
|
|
|
) => {
|
|
|
const projectInfo = getMindMapProjectByLocal();
|
|
|
- if (!projectInfo) return;
|
|
|
+ if (!projectInfo || !setMindProjectInfo) return;
|
|
|
|
|
|
- const topic = buildTopic(type, otherData);
|
|
|
- const parentData = node.getData();
|
|
|
- const traverse = (topics: TopicItem[]) => {
|
|
|
- topics.forEach((item) => {
|
|
|
- if (item.id === parentData.id) {
|
|
|
+ const topic = buildTopic(type, {
|
|
|
+ ...(otherData || {}),
|
|
|
+ parentId: node?.id
|
|
|
+ });
|
|
|
+
|
|
|
+ if( node) {
|
|
|
+ const parentData = node.getData();
|
|
|
+ const traverse = (topics: TopicItem[]) => {
|
|
|
+ topics.forEach((item) => {
|
|
|
+ if (item.id === parentData?.id) {
|
|
|
+ if (item.children) {
|
|
|
+ item.children?.push(topic);
|
|
|
+ } else {
|
|
|
+ item.children = [topic];
|
|
|
+ }
|
|
|
+ }
|
|
|
if (item.children) {
|
|
|
- item.children?.push(topic);
|
|
|
- } else {
|
|
|
- item.children = [topic];
|
|
|
+ traverse(item.children);
|
|
|
}
|
|
|
- }
|
|
|
- if (item.children) {
|
|
|
- traverse(item.children);
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- traverse(projectInfo?.topics || []);
|
|
|
+ });
|
|
|
+ };
|
|
|
+ traverse(projectInfo?.topics || []);
|
|
|
+ } else {
|
|
|
+ projectInfo.topics.push(topic);
|
|
|
+ }
|
|
|
|
|
|
- parentData?.setMindProjectInfo(projectInfo);
|
|
|
+ setMindProjectInfo(projectInfo);
|
|
|
};
|
|
|
|
|
|
const topicMap = {
|
|
@@ -202,3 +200,32 @@ export const buildTopic = (
|
|
|
export const getMindMapProjectByLocal = (): MindMapProjectInfo | null => {
|
|
|
return JSON.parse(localStorage.getItem("minMapProjectInfo") || "null");
|
|
|
};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 更新主题数据
|
|
|
+ * @param id 主题id
|
|
|
+ * @param value 更新的数据
|
|
|
+ * @param setMindProjectInfo 更新项目信息方法
|
|
|
+ */
|
|
|
+export const updateTopic = (
|
|
|
+ id: string,
|
|
|
+ value: Partial<TopicItem>,
|
|
|
+ setMindProjectInfo: (info: MindMapProjectInfo) => void
|
|
|
+) => {
|
|
|
+ const projectInfo = getMindMapProjectByLocal();
|
|
|
+ if (!projectInfo || !setMindProjectInfo) return;
|
|
|
+
|
|
|
+ const traverse = (topics: TopicItem[]) => {
|
|
|
+ topics.forEach((item) => {
|
|
|
+ if (item.id === id) {
|
|
|
+ Object.assign(item, value);
|
|
|
+ }
|
|
|
+ if (item.children) {
|
|
|
+ traverse(item.children);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ traverse(projectInfo?.topics || []);
|
|
|
+ setMindProjectInfo(projectInfo);
|
|
|
+}
|