import { Expr } from '../types/common.js'; import { NodeData, EdgeData, GraphData, GraphNode, GraphEdge } from '../types/data.js'; import { ID } from '../types/id.js'; import { Point } from '../types/point.js'; import { Size } from '../types/size.js'; interface DataOptions { /** * 自定义节点属性映射 * * Custom node field mapping */ node?: (datum: N) => { id?: ID; x?: number; y?: number; z?: number; parentId?: ID | null; isCombo?: boolean; }; /** * 自定义边属性映射 * * Custom edge field mapping */ edge?: (datum: E) => { id?: ID; source?: ID; target?: ID; }; } interface BaseLayoutOptions extends DataOptions { /** * 布局中心 * * Layout center */ center?: Point; /** * 布局宽度 * * Layout width */ width?: number; /** * 布局高度 * * Layout height */ height?: number; /** * 节点大小(直径)。用于防止节点重叠时的碰撞检测 * * Node size (diameter). Used for collision detection when nodes overlap * @defaultValue 10 */ nodeSize?: Size | Expr | ((node: NodeData) => Size); /** * 节点之间的最小间距 * * Minimum spacing between nodes * @defaultValue 0 */ nodeSpacing?: Size | Expr | ((node: NodeData) => Size); /** * 是否启用 WebWorker * * Whether to run the layout in a WebWorker */ enableWorker?: boolean; [key: string]: any; } interface Layout { /** * 执行布局计算 * * Execute layout calculation */ execute(graph: GraphData, options?: O): Promise; /** * 遍历节点布局结果 * * Iterate over node layout results */ forEachNode(callback: (node: GraphNode) => void): void; /** * 遍历边布局结果 * * Iterate over edge layout results */ forEachEdge(callback: (edge: GraphEdge) => void): void; /** * 布局计算的配置项 * * Layout calculation configuration item */ options: O; /** * 布局id * * Layout id */ id: string; } interface LayoutWithIterations extends Layout { /** * 停止布局计算 * * Stop the layout calculation * @description * Some layout algorithm has n iterations so that the simulation needs to be stopped at any time. * This method is useful for running the simulation manually. */ stop(): void; /** * 手动推进布局计算若干步 * * Manually steps the simulation by the specified number of iterations. */ tick(iterations?: number): void; /** * 重置布局计算 * * Restart the layout calculation */ restart(): void; /** * 设置节点固定位置,在布局过程中该节点不会被移动 * * Set the fixed position of a node. The node will not be moved during the layout process. */ setFixedPosition(nodeId: string, position: Point | null): void; } interface SimulationOptions { /** * 最大迭代次数,若为 0 则将自动调整 * * Maximum number of iterations, if it is 0, it will be automatically adjusted * @defaultValue 0 */ maxIteration?: number; /** * 当一次迭代的平均/最大/最小(根据distanceThresholdMode决定)移动长度小于该值时停止迭代。数字越小,布局越收敛,所用时间将越长 * * When the average/max/min (depending on distanceThresholdMode) movement length of one iteration is less than this value, the iteration will stop. The smaller the number, the more converged the layout, and the longer the time it takes to use * @defaultValue 0.4 */ minMovement?: number; /** * 是否启用动画模式:动画模式下布局过程会被分解为多次迭代并通过定时器执行,从而可以在布局过程中看到节点的移动过程;非动画模式下布局将在一次函数调用中完成所有迭代 * * Whether to enable animation mode: in animation mode, the layout process will be decomposed into multiple iterations and executed through a timer, so that you can see the movement process of the nodes during the layout; in non-animation mode, the layout will complete all iterations in one function call * @defaultValue true */ animate?: boolean; } export type { BaseLayoutOptions, DataOptions, Layout, LayoutWithIterations, SimulationOptions };