mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
chore(auto-layout): auto layout animation disabled by default (#449)
This commit is contained in:
parent
de7f2d3c07
commit
25e20d8c20
@ -3,7 +3,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { LayoutConfig } from './type';
|
import { LayoutConfig, LayoutOptions } from './type';
|
||||||
|
|
||||||
export const DefaultLayoutConfig: LayoutConfig = {
|
export const DefaultLayoutConfig: LayoutConfig = {
|
||||||
rankdir: 'LR',
|
rankdir: 'LR',
|
||||||
@ -16,3 +16,8 @@ export const DefaultLayoutConfig: LayoutConfig = {
|
|||||||
acyclicer: undefined,
|
acyclicer: undefined,
|
||||||
ranker: 'network-simplex',
|
ranker: 'network-simplex',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DefaultLayoutOptions: LayoutOptions = {
|
||||||
|
getFollowNode: undefined,
|
||||||
|
enableAnimation: false,
|
||||||
|
};
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { GetFollowNode, LayoutConfig, LayoutOptions, LayoutParams } from './type';
|
import { LayoutConfig, LayoutOptions, LayoutParams } from './type';
|
||||||
import { LayoutStore } from './store';
|
import { LayoutStore } from './store';
|
||||||
import { LayoutPosition } from './position';
|
import { LayoutPosition } from './position';
|
||||||
import { DagreLayout } from './dagre';
|
import { DagreLayout } from './dagre';
|
||||||
@ -21,9 +21,8 @@ export class Layout {
|
|||||||
this._position = new LayoutPosition(this._store);
|
this._position = new LayoutPosition(this._store);
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(params: LayoutParams, options: LayoutOptions = {}): void {
|
public init(params: LayoutParams, options: LayoutOptions): void {
|
||||||
this._store.create(params);
|
this._store.create(params, options);
|
||||||
this.setFollowNode(options.getFollowNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(): void {
|
public layout(): void {
|
||||||
@ -39,20 +38,4 @@ export class Layout {
|
|||||||
}
|
}
|
||||||
return await this._position.position();
|
return await this._position.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
public setFollowNode(getFollowNode?: GetFollowNode): void {
|
|
||||||
if (!getFollowNode) return;
|
|
||||||
const context = { store: this._store };
|
|
||||||
this._store.nodes.forEach((node) => {
|
|
||||||
const followTo = getFollowNode(node, context)?.followTo;
|
|
||||||
if (!followTo) return;
|
|
||||||
const followToNode = this._store.getNode(followTo);
|
|
||||||
if (!followToNode) return;
|
|
||||||
if (!followToNode.followedBy) {
|
|
||||||
followToNode.followedBy = [];
|
|
||||||
}
|
|
||||||
followToNode.followedBy.push(node.id);
|
|
||||||
node.followTo = followTo;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,19 @@ export class LayoutPosition {
|
|||||||
constructor(private readonly store: LayoutStore) {}
|
constructor(private readonly store: LayoutStore) {}
|
||||||
|
|
||||||
public async position(): Promise<void> {
|
public async position(): Promise<void> {
|
||||||
|
if (this.store.options.enableAnimation) {
|
||||||
|
return this.positionWithAnimation();
|
||||||
|
}
|
||||||
|
return this.positionDirectly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private positionDirectly(): void {
|
||||||
|
this.store.nodes.forEach((layoutNode) => {
|
||||||
|
this.updateNodePosition({ layoutNode, step: 100 });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async positionWithAnimation(): Promise<void> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
startTween({
|
startTween({
|
||||||
from: { d: 0 },
|
from: { d: 0 },
|
||||||
|
|||||||
@ -10,7 +10,14 @@ import {
|
|||||||
} from '@flowgram.ai/free-layout-core';
|
} from '@flowgram.ai/free-layout-core';
|
||||||
import { FlowNodeBaseType, FlowNodeTransformData } from '@flowgram.ai/document';
|
import { FlowNodeBaseType, FlowNodeTransformData } from '@flowgram.ai/document';
|
||||||
|
|
||||||
import type { LayoutConfig, LayoutEdge, LayoutNode, LayoutParams } from './type';
|
import type {
|
||||||
|
GetFollowNode,
|
||||||
|
LayoutConfig,
|
||||||
|
LayoutEdge,
|
||||||
|
LayoutNode,
|
||||||
|
LayoutOptions,
|
||||||
|
LayoutParams,
|
||||||
|
} from './type';
|
||||||
|
|
||||||
interface LayoutStoreData {
|
interface LayoutStoreData {
|
||||||
nodes: Map<string, LayoutNode>;
|
nodes: Map<string, LayoutNode>;
|
||||||
@ -26,6 +33,8 @@ export class LayoutStore {
|
|||||||
|
|
||||||
private container: WorkflowNodeEntity;
|
private container: WorkflowNodeEntity;
|
||||||
|
|
||||||
|
public options: LayoutOptions;
|
||||||
|
|
||||||
constructor(public readonly config: LayoutConfig) {}
|
constructor(public readonly config: LayoutConfig) {}
|
||||||
|
|
||||||
public get initialized(): boolean {
|
public get initialized(): boolean {
|
||||||
@ -56,9 +65,10 @@ export class LayoutStore {
|
|||||||
return Array.from(this.store.edges.values());
|
return Array.from(this.store.edges.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public create(params: LayoutParams): void {
|
public create(params: LayoutParams, options: LayoutOptions): void {
|
||||||
this.store = this.createStore(params);
|
this.store = this.createStore(params);
|
||||||
this.indexMap = this.createIndexMap();
|
this.indexMap = this.createIndexMap();
|
||||||
|
this.setOptions(options);
|
||||||
this.init = true;
|
this.init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,4 +289,27 @@ export class LayoutStore {
|
|||||||
|
|
||||||
return uniqueNodeIds;
|
return uniqueNodeIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 记录运行选项 */
|
||||||
|
private setOptions(options: LayoutOptions): void {
|
||||||
|
this.options = options;
|
||||||
|
this.setFollowNode(options.getFollowNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 设置跟随节点配置 */
|
||||||
|
private setFollowNode(getFollowNode?: GetFollowNode): void {
|
||||||
|
if (!getFollowNode) return;
|
||||||
|
const context = { store: this };
|
||||||
|
this.nodes.forEach((node) => {
|
||||||
|
const followTo = getFollowNode(node, context)?.followTo;
|
||||||
|
if (!followTo) return;
|
||||||
|
const followToNode = this.getNode(followTo);
|
||||||
|
if (!followToNode) return;
|
||||||
|
if (!followToNode.followedBy) {
|
||||||
|
followToNode.followedBy = [];
|
||||||
|
}
|
||||||
|
followToNode.followedBy.push(node.id);
|
||||||
|
node.followTo = followTo;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,6 +71,7 @@ export interface LayoutParams {
|
|||||||
|
|
||||||
export interface LayoutOptions {
|
export interface LayoutOptions {
|
||||||
getFollowNode?: GetFollowNode;
|
getFollowNode?: GetFollowNode;
|
||||||
|
enableAnimation: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LayoutConfig {
|
export interface LayoutConfig {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import {
|
|||||||
|
|
||||||
import { AutoLayoutOptions } from './type';
|
import { AutoLayoutOptions } from './type';
|
||||||
import { LayoutConfig } from './layout/type';
|
import { LayoutConfig } from './layout/type';
|
||||||
|
import { DefaultLayoutOptions } from './layout/constant';
|
||||||
import { DefaultLayoutConfig, Layout, type LayoutOptions } from './layout';
|
import { DefaultLayoutConfig, Layout, type LayoutOptions } from './layout';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@ -28,8 +29,11 @@ export class AutoLayoutService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async layout(options: LayoutOptions = {}): Promise<void> {
|
public async layout(options: Partial<LayoutOptions> = {}): Promise<void> {
|
||||||
await this.layoutNode(this.document.root, options);
|
await this.layoutNode(this.document.root, {
|
||||||
|
...DefaultLayoutOptions,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async layoutNode(node: WorkflowNodeEntity, options: LayoutOptions): Promise<void> {
|
private async layoutNode(node: WorkflowNodeEntity, options: LayoutOptions): Promise<void> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user