@flowgram.ai/free-auto-layout-plugin 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +30 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +30 -4
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.d.mts
CHANGED
|
@@ -224,16 +224,29 @@ interface LayoutParams {
|
|
|
224
224
|
layoutEdges: LayoutEdge[];
|
|
225
225
|
}
|
|
226
226
|
interface LayoutOptions {
|
|
227
|
+
/** Custom layout configuration to override default dagre settings. */
|
|
227
228
|
layoutConfig?: Partial<LayoutConfig>;
|
|
229
|
+
/** The container node entity used as the root for the layout. */
|
|
228
230
|
containerNode?: WorkflowNodeEntity;
|
|
231
|
+
/** Custom function to determine follow-node relationships between layout nodes. */
|
|
229
232
|
getFollowNode?: GetFollowNode;
|
|
233
|
+
/** Whether to animate node movements during layout positioning. */
|
|
230
234
|
enableAnimation?: boolean;
|
|
235
|
+
/** Duration of the position animation in milliseconds. Only effective when `enableAnimation` is true. */
|
|
231
236
|
animationDuration?: number;
|
|
237
|
+
/** When true, skips the fit-view step after layout is applied. */
|
|
232
238
|
disableFitView?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* When true, aligns nodes by their top edge instead of their center point.
|
|
241
|
+
* Defaults to false (center-aligned). Set to true to place all nodes' top edges on the same horizontal line.
|
|
242
|
+
*/
|
|
243
|
+
alignTopEdge?: boolean;
|
|
244
|
+
/** Filter function to exclude specific nodes from the layout. Return false to skip a node. */
|
|
233
245
|
filterNode?: (params: {
|
|
234
246
|
node: WorkflowNodeEntity;
|
|
235
247
|
parent?: WorkflowNodeEntity;
|
|
236
248
|
}) => boolean;
|
|
249
|
+
/** Filter function to exclude specific edges from the layout. Return false to skip an edge. */
|
|
237
250
|
filterLine?: (params: {
|
|
238
251
|
line: WorkflowLineEntity;
|
|
239
252
|
}) => boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -224,16 +224,29 @@ interface LayoutParams {
|
|
|
224
224
|
layoutEdges: LayoutEdge[];
|
|
225
225
|
}
|
|
226
226
|
interface LayoutOptions {
|
|
227
|
+
/** Custom layout configuration to override default dagre settings. */
|
|
227
228
|
layoutConfig?: Partial<LayoutConfig>;
|
|
229
|
+
/** The container node entity used as the root for the layout. */
|
|
228
230
|
containerNode?: WorkflowNodeEntity;
|
|
231
|
+
/** Custom function to determine follow-node relationships between layout nodes. */
|
|
229
232
|
getFollowNode?: GetFollowNode;
|
|
233
|
+
/** Whether to animate node movements during layout positioning. */
|
|
230
234
|
enableAnimation?: boolean;
|
|
235
|
+
/** Duration of the position animation in milliseconds. Only effective when `enableAnimation` is true. */
|
|
231
236
|
animationDuration?: number;
|
|
237
|
+
/** When true, skips the fit-view step after layout is applied. */
|
|
232
238
|
disableFitView?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* When true, aligns nodes by their top edge instead of their center point.
|
|
241
|
+
* Defaults to false (center-aligned). Set to true to place all nodes' top edges on the same horizontal line.
|
|
242
|
+
*/
|
|
243
|
+
alignTopEdge?: boolean;
|
|
244
|
+
/** Filter function to exclude specific nodes from the layout. Return false to skip a node. */
|
|
233
245
|
filterNode?: (params: {
|
|
234
246
|
node: WorkflowNodeEntity;
|
|
235
247
|
parent?: WorkflowNodeEntity;
|
|
236
248
|
}) => boolean;
|
|
249
|
+
/** Filter function to exclude specific edges from the layout. Return false to skip an edge. */
|
|
237
250
|
filterLine?: (params: {
|
|
238
251
|
line: WorkflowLineEntity;
|
|
239
252
|
}) => boolean;
|
package/dist/index.js
CHANGED
|
@@ -2192,7 +2192,7 @@ var LayoutStore = class {
|
|
|
2192
2192
|
const blockIdSet = new Set(blocks.map((b) => b.id));
|
|
2193
2193
|
const groupFromEdges = edges.filter((edge) => blockIdSet.has(edge.to?.id ?? "")).map((edge) => {
|
|
2194
2194
|
const { from, to } = edge.info;
|
|
2195
|
-
if (!from || !to
|
|
2195
|
+
if (!from || !to) {
|
|
2196
2196
|
return;
|
|
2197
2197
|
}
|
|
2198
2198
|
const id = `virtual_${groupId}_from_${from}_to_${to}`;
|
|
@@ -2211,7 +2211,7 @@ var LayoutStore = class {
|
|
|
2211
2211
|
}).filter(Boolean);
|
|
2212
2212
|
const groupToEdges = edges.filter((edge) => blockIdSet.has(edge.from?.id ?? "")).map((edge) => {
|
|
2213
2213
|
const { from, to } = edge.info;
|
|
2214
|
-
if (!from || !to
|
|
2214
|
+
if (!from || !to) {
|
|
2215
2215
|
return;
|
|
2216
2216
|
}
|
|
2217
2217
|
const id = `virtual_${groupId}_from_${from}_to_${to}`;
|
|
@@ -2371,10 +2371,10 @@ var LayoutPosition = class {
|
|
|
2371
2371
|
updateNodePosition(params) {
|
|
2372
2372
|
const { layoutNode, step } = params;
|
|
2373
2373
|
const { transform } = layoutNode.entity.transform;
|
|
2374
|
+
const centerToTopEdgeOffset = (layoutNode.size.height - layoutNode.padding.top - layoutNode.padding.bottom) / 2;
|
|
2374
2375
|
const layoutPosition = {
|
|
2375
2376
|
x: layoutNode.position.x + layoutNode.offset.x,
|
|
2376
|
-
|
|
2377
|
-
y: layoutNode.position.y + layoutNode.offset.y - (layoutNode.size.height - layoutNode.padding.top - layoutNode.padding.bottom) / 2
|
|
2377
|
+
y: layoutNode.position.y + layoutNode.offset.y - centerToTopEdgeOffset
|
|
2378
2378
|
};
|
|
2379
2379
|
const deltaX = (layoutPosition.x - transform.position.x) * step / 100;
|
|
2380
2380
|
const deltaY = (layoutPosition.y - transform.position.y) * step / 100;
|
|
@@ -2400,6 +2400,7 @@ var DagreLayout = class {
|
|
|
2400
2400
|
layout() {
|
|
2401
2401
|
this.graphSetData();
|
|
2402
2402
|
this.dagreLayout();
|
|
2403
|
+
this.alignTopEdgeIfNeeded();
|
|
2403
2404
|
this.layoutSetPosition();
|
|
2404
2405
|
}
|
|
2405
2406
|
dagreLayout() {
|
|
@@ -2484,6 +2485,28 @@ var DagreLayout = class {
|
|
|
2484
2485
|
};
|
|
2485
2486
|
});
|
|
2486
2487
|
}
|
|
2488
|
+
alignTopEdgeIfNeeded() {
|
|
2489
|
+
const { alignTopEdge } = this.store.options;
|
|
2490
|
+
const { rankdir, marginy = 0 } = this.store.config;
|
|
2491
|
+
if (!alignTopEdge || rankdir !== "LR" && rankdir !== "RL") {
|
|
2492
|
+
return;
|
|
2493
|
+
}
|
|
2494
|
+
const rankGroups = this.rankGroup(this.graph);
|
|
2495
|
+
rankGroups.forEach((indexSet) => {
|
|
2496
|
+
const graphNodes = Array.from(indexSet).map((id) => this.graph.node(id)).filter(Boolean);
|
|
2497
|
+
if (graphNodes.length === 0) {
|
|
2498
|
+
return;
|
|
2499
|
+
}
|
|
2500
|
+
const minTop = Math.min(...graphNodes.map((node) => node.y - node.height / 2));
|
|
2501
|
+
const deltaY = marginy - minTop;
|
|
2502
|
+
if (deltaY === 0) {
|
|
2503
|
+
return;
|
|
2504
|
+
}
|
|
2505
|
+
graphNodes.forEach((node) => {
|
|
2506
|
+
node.y += deltaY;
|
|
2507
|
+
});
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2487
2510
|
normalizeNumber(number) {
|
|
2488
2511
|
return Number.isNaN(number) ? 0 : number;
|
|
2489
2512
|
}
|
|
@@ -2548,6 +2571,9 @@ var DagreLayout = class {
|
|
|
2548
2571
|
const rankGroup = /* @__PURE__ */ new Map();
|
|
2549
2572
|
g.nodes().forEach((i) => {
|
|
2550
2573
|
const graphNode = g.node(i);
|
|
2574
|
+
if (!graphNode || typeof graphNode.rank !== "number") {
|
|
2575
|
+
return;
|
|
2576
|
+
}
|
|
2551
2577
|
const rank2 = graphNode.rank;
|
|
2552
2578
|
if (!rankGroup.has(rank2)) {
|
|
2553
2579
|
rankGroup.set(rank2, /* @__PURE__ */ new Set());
|