feat: test buildNodesAndEdgesFromDSLComponents (#940)

### What problem does this PR solve?
 feat: test buildNodesAndEdgesFromDSLComponents #918

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2024-05-27 19:35:14 +08:00
committed by GitHub
parent 571aaaff22
commit d9bc093df1
9 changed files with 4844 additions and 188 deletions

View File

@@ -1,10 +1,32 @@
import { DSLComponents } from '@/interfaces/database/flow';
import dagre from 'dagre';
import { Edge, Node, Position } from 'reactflow';
import { v4 as uuidv4 } from 'uuid';
export const buildNodesFromDSLComponents = (data: DSLComponents) => {
const buildEdges = (
operatorIds: string[],
currentId: string,
allEdges: Edge[],
isUpstream = false,
) => {
operatorIds.forEach((cur) => {
const source = isUpstream ? cur : currentId;
const target = isUpstream ? currentId : cur;
if (!allEdges.some((e) => e.source === source && e.target === target)) {
allEdges.push({
id: uuidv4(),
label: '',
type: 'step',
source: source,
target: target,
});
}
});
};
export const buildNodesAndEdgesFromDSLComponents = (data: DSLComponents) => {
const nodes: Node[] = [];
const edges: Edge[] = [];
let edges: Edge[] = [];
Object.entries(data).forEach(([key, value]) => {
const downstream = [...value.downstream];
@@ -23,22 +45,51 @@ export const buildNodesFromDSLComponents = (data: DSLComponents) => {
targetPosition: Position.Right,
});
// intermediate node
// The first and last nodes do not need to be considered
if (upstream.length > 0 && downstream.length > 0) {
for (let i = 0; i < upstream.length; i++) {
const up = upstream[i];
for (let j = 0; j < downstream.length; j++) {
const down = downstream[j];
edges.push({
id: uuidv4(),
label: '',
type: 'step',
source: up,
target: down,
});
}
}
}
buildEdges(upstream, key, edges, true);
buildEdges(downstream, key, edges, false);
});
return { nodes, edges };
};
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const nodeWidth = 172;
const nodeHeight = 36;
export const getLayoutedElements = (
nodes: Node[],
edges: Edge[],
direction = 'TB',
) => {
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({ rankdir: direction });
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
nodes.forEach((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
node.targetPosition = isHorizontal ? Position.Left : Position.Top;
node.sourcePosition = isHorizontal ? Position.Right : Position.Bottom;
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
node.position = {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2,
};
return node;
});
return { nodes, edges };
};