fix(auto-layout): branches with multi sub nodes (#272)

This commit is contained in:
Louis Young 2025-05-26 16:12:59 +08:00 committed by GitHub
parent 755aaf2223
commit 9ae858b363
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 20 deletions

View File

@ -1,4 +1,8 @@
import { WorkflowLineEntity, WorkflowNodeEntity } from '@flowgram.ai/free-layout-core';
import {
WorkflowLineEntity,
WorkflowNodeEntity,
WorkflowNodeLinesData,
} from '@flowgram.ai/free-layout-core';
import { FlowNodeBaseType, FlowNodeTransformData } from '@flowgram.ai/document';
import { LayoutEdge, LayoutNode, LayoutParams } from './type';
@ -15,6 +19,8 @@ export class LayoutStore {
private store: LayoutStoreData;
private container: WorkflowNodeEntity;
public get initialized(): boolean {
return this.init;
}
@ -47,11 +53,9 @@ export class LayoutStore {
}
/** 创建布局数据 */
private createStore(params: {
nodes: WorkflowNodeEntity[];
edges: WorkflowLineEntity[];
}): LayoutStoreData {
const { nodes, edges } = params;
private createStore(params: LayoutParams): LayoutStoreData {
const { nodes, edges, container } = params;
this.container = container;
const layoutNodes = this.createLayoutNodes(nodes);
const layoutEdges = this.createEdgesStore(edges);
const virtualEdges = this.createVirtualEdges(params);
@ -211,30 +215,42 @@ export class LayoutStore {
nodeIdList.push(node.id);
});
const sameFromEdges = new Map<string, LayoutEdge[]>();
// 第2级排序被连线节点排序靠后
this.edges.forEach((edge) => {
nodeIdList.push(edge.to);
if (edge.entity.info.fromPort) {
const edgesForFrom = sameFromEdges.get(edge.from) || [];
sameFromEdges.set(edge.from, [...edgesForFrom, edge]);
}
});
// 第3级排序相同 from 的节点的不同 port根据 port y坐标排序
sameFromEdges.forEach((edges, from) => {
const sortedEdges = edges.sort((a, b) => {
const aPort = a.entity.fromPort;
const bPort = b.entity.fromPort;
// 第3级排序按照从开始节点进行遍历排序
const visited = new Set<string>();
const visit = (node: WorkflowNodeEntity) => {
if (visited.has(node.id)) {
return;
}
visited.add(node.id);
nodeIdList.push(node.id);
// 访问子节点
node.blocks.forEach((child) => {
visit(child);
});
// 访问后续节点
const { outputLines } = node.getData(WorkflowNodeLinesData);
const sortedLines = outputLines.sort((a, b) => {
const aPort = a.fromPort;
const bPort = b.fromPort;
if (aPort && bPort) {
return aPort.point.y - bPort.point.y;
}
return 0;
});
sortedEdges.forEach((edge) => {
nodeIdList.push(edge.to);
});
sortedLines.forEach((line) => {
const { to } = line;
if (!to) {
return;
}
visit(to);
});
};
visit(this.container);
// 使用 reduceRight 去重并保留最后一个出现的节点 id
const uniqueNodeIds: string[] = nodeIdList.reduceRight((acc: string[], nodeId: string) => {

View File

@ -61,6 +61,7 @@ export interface DagreNode {
export interface LayoutParams {
nodes: WorkflowNodeEntity[];
edges: WorkflowLineEntity[];
container: WorkflowNodeEntity;
}
export interface LayoutOptions {

View File

@ -30,7 +30,7 @@ export class AutoLayoutService {
await Promise.all(nodes.map(async (child) => this.layoutNode(child, options)));
const layout = new Layout();
layout.init({ nodes, edges }, options);
layout.init({ nodes, edges, container: node }, options);
layout.layout();
await layout.position();
}