143 lines
3.8 KiB
TypeScript
143 lines
3.8 KiB
TypeScript
import { RenderData } from '@kevisual/container';
|
|
|
|
type Page = {
|
|
data: {
|
|
edges: { id: string; source: string; target: string }[];
|
|
nodes: { id: string; type: string; position: { x: number; y: number }; data: any }[];
|
|
};
|
|
id: string;
|
|
type: string;
|
|
[key: string]: any;
|
|
};
|
|
type Container = {
|
|
code: string;
|
|
id: string;
|
|
[key: string]: any;
|
|
};
|
|
type PageEditData = {
|
|
page: Page;
|
|
containerList: Container[];
|
|
};
|
|
export const getContainerData = (pageEditData: PageEditData) => {
|
|
const { page, containerList } = pageEditData;
|
|
const containerObj = containerList.reduce((acc, container) => {
|
|
acc[container.id] = container;
|
|
return acc;
|
|
}, {});
|
|
|
|
const { edges, nodes } = page.data;
|
|
const nodesObj = nodes.reduce((acc, node) => {
|
|
acc[node.id] = node;
|
|
return acc;
|
|
}, {});
|
|
const treeArray = getTreeFromEdges(edges);
|
|
const floatNodes = nodes.filter((node) => !treeArray.find((item) => item.id === node.id));
|
|
const treeNodes = nodes.filter((node) => treeArray.find((item) => item.id === node.id));
|
|
const renderData: RenderData[] = [];
|
|
for (let tree of treeArray) {
|
|
const node = nodesObj[tree.id];
|
|
const container = containerObj[node.data?.cid];
|
|
const style = node.data?.style ?? {
|
|
position: 'absolute',
|
|
width: 100,
|
|
height: 100,
|
|
};
|
|
const data = {
|
|
node: { ...node },
|
|
container: { ...container },
|
|
};
|
|
renderData.push({
|
|
id: node.id,
|
|
children: tree.children,
|
|
parents: tree.parents,
|
|
code: container?.code || '',
|
|
codeId: container?.id,
|
|
data: data || {},
|
|
className: node.data?.className,
|
|
shadowRoot: node.data?.shadowRoot,
|
|
showChild: node.data?.showChild,
|
|
style,
|
|
});
|
|
}
|
|
for (let node of floatNodes) {
|
|
const container = containerObj[node.data?.cid];
|
|
const style = node.data?.style ?? {
|
|
position: 'absolute',
|
|
width: 100,
|
|
height: 100,
|
|
};
|
|
const data = {
|
|
node: { ...node },
|
|
container: { ...container },
|
|
};
|
|
renderData.push({
|
|
id: node.id,
|
|
children: [],
|
|
parents: [],
|
|
code: container?.code || '',
|
|
codeId: container?.id,
|
|
data: data || {},
|
|
className: node.data?.className,
|
|
shadowRoot: node.data?.shadowRoot,
|
|
showChild: node.data?.showChild,
|
|
style,
|
|
});
|
|
}
|
|
return renderData;
|
|
};
|
|
const getTreeFromEdges = (
|
|
edges: { id: string; source: string; target: string }[],
|
|
): {
|
|
id: string;
|
|
parents: string[];
|
|
children: string[];
|
|
}[] => {
|
|
// 构建树形结构
|
|
function buildNodeTree(edges) {
|
|
const nodeMap = {};
|
|
|
|
// 初始化每个节点的子节点列表和父节点列表
|
|
edges.forEach((edge) => {
|
|
if (!nodeMap[edge.source]) {
|
|
nodeMap[edge.source] = { id: edge.source, parents: [], children: [] };
|
|
}
|
|
if (!nodeMap[edge.target]) {
|
|
nodeMap[edge.target] = { id: edge.target, parents: [], children: [] };
|
|
}
|
|
|
|
// 连接父节点和子节点
|
|
nodeMap[edge.source].children.push(nodeMap[edge.target]);
|
|
nodeMap[edge.target].parents.push(nodeMap[edge.source]);
|
|
});
|
|
|
|
return nodeMap;
|
|
}
|
|
|
|
const nodeTree = buildNodeTree(edges);
|
|
|
|
// 递归获取所有父节点,按顺序
|
|
function getAllParents(node) {
|
|
const parents: string[] = [];
|
|
function traverseParents(currentNode) {
|
|
if (currentNode.parents.length > 0) {
|
|
currentNode.parents.forEach((parent: any) => {
|
|
parents.push(parent.id);
|
|
traverseParents(parent);
|
|
});
|
|
}
|
|
}
|
|
traverseParents(node);
|
|
return parents.reverse(); // 确保顺序从最顶层到直接父节点
|
|
}
|
|
|
|
function getNodeInfo(nodeMap) {
|
|
return Object.values(nodeMap).map((node: any) => ({
|
|
id: node.id,
|
|
parents: getAllParents(node),
|
|
children: node.children.map((child) => child.id),
|
|
}));
|
|
}
|
|
const result = getNodeInfo(nodeTree);
|
|
return result;
|
|
};
|