import LogicFlow, { BaseEdgeModel, BaseNodeModel, CallbackArgs, Model } from '@logicflow/core'; import { DynamicGroupNode } from './node'; import { DynamicGroupNodeModel } from './model'; import { ExtensionEventType } from '../constant/events'; import EdgeConfig = LogicFlow.EdgeConfig; import EdgeData = LogicFlow.EdgeData; import NodeData = LogicFlow.NodeData; import BoxBoundsPoint = Model.BoxBoundsPoint; import ElementsInfoInGroup = DynamicGroup.ElementsInfoInGroup; export * from './node'; export * from './model'; export declare const dynamicGroup: { type: string; view: typeof DynamicGroupNode; model: typeof DynamicGroupNodeModel; }; export type SensorOutlineOptions = { /** 拖拽感应外框描边颜色,默认 '#feb663' */ stroke?: string; /** 拖拽感应外框线宽,默认 2 */ strokeWidth?: number; }; export declare class DynamicGroup { static pluginName: string; private lf; /** * 为 true 时禁止手动将边连到/从 dynamic-group 节点本身。 * 默认 false,与历史行为一致;折叠虚拟边不受影响。 */ disallowEdgeConnectToGroup: boolean; /** * 删除 dynamic-group 时是否级联删除其成员。 * 默认 true,与 v1.1 以来行为一致;为 false 时仅删除分组,成员保留并解除归属。 */ cascadeDeleteChildren: boolean; /** 拖拽节点进入分组时的感应外框样式 */ sensorOutline?: SensorOutlineOptions; topGroupZIndex: number; private activeGroups; nodeGroupMap: Map; /** 折叠态虚拟边 id → 所属分组与真实边 id */ collapsedVirtualEdges: Map; /** 折叠隐藏的真实边 id → 分组 id */ collapsedRealEdgeToGroup: Map; private originDeleteNode?; constructor({ lf, options }: LogicFlow.IExtensionProps); /** * 获取节点所属的分组 * @param nodeId */ getGroupByNodeId(nodeId: string): BaseNodeModel | undefined; registerCollapsedVirtualEdge(virtualId: string, groupId: string, realEdgeId: string): void; unregisterCollapsedVirtualEdge(virtualId: string): void; /** * 折叠态删边:删虚拟边时连带删对应真实边,防止展开后「边复活」(#2395)。 * Gateway 双分支等场景下,每条虚拟边只映射一条真实边。 */ onEdgeDelete: ({ data: edge }: CallbackArgs<'edge:delete'>) => void; /** * 获取自定位置及其所属分组 * 当分组重合时,优先返回最上层的分组 * @param bounds * @param nodeData */ getGroupByBounds(bounds: BoxBoundsPoint, nodeData: NodeData): DynamicGroupNodeModel | undefined; /** * 提高元素的层级,如果是 group,同时提高其子元素的层级 * @param model */ sendNodeToFront(model?: BaseNodeModel): void; /** * 递归计算某个分组内最高的 zIndex 值 * TODO: 这块儿有点疑问❓如果 node 不是 group,这块儿返回的 maxZIndex 是最小值,但 node 的 zIndex 不一定是这个值 * @param node */ getMaxZIndex(node: BaseNodeModel): number; /** * 校准当前 topGroupZIndex 的值 * @param nodes */ calibrateTopGroupZIndex(nodes: NodeData[]): void; onSelectionDrop: () => void; onNodeAdd: ({ data: node }: CallbackArgs<'node:add'>) => void; onNodeDndAdd: ({ data: node }: CallbackArgs<'node:dnd-add'>) => void; onNodeDrop: ({ data: node }: CallbackArgs<'node:drop'>) => void; onNodeMouseUp: () => void; clearDragTargetHighlight(): void; detachNodeFromGroup: (groupId: string, nodeId: string) => void; releaseGroupMembers: (groupModel: DynamicGroupNodeModel) => void; removeChildFromOtherGroups: (childId: string, ownerGroupId: string) => void; setNodeGroup: (groupId: string, childId: string) => void; syncGroupChildren: (node: LogicFlow.NodeData) => void; addNodeToGroup: (node: LogicFlow.NodeData) => void; onGroupAddNode: ({ data: groupData, childId, }: CallbackArgs) => void; removeNodeFromGroup: ({ data: node, model, }: CallbackArgs<'node:delete'>) => void; onSelectionDrag: () => void; onNodeDrag: ({ data: node }: CallbackArgs<'node:drag'>) => void; private getTargetGroupForNode; setActiveGroup: (node: LogicFlow.NodeData) => void; /** * 1. 分组节点默认在普通节点下面 * 2. 分组节点被选中后,会将分组节点以及其内部的其它分组节点放到其余分组节点的上面 * 3. 分组节点取消选中后,不会将分组节点重置为原来的高度 * 4. 由于 LogicFlow 核心目标是支持用户手动绘制流程图,所以暂时不支持一张流程图超过 1000 个分组节点的情况 * @param node * @param isMultiple * @param isSelected */ onNodeSelect: ({ data: node, isMultiple, isSelected, }: Omit, 'e' | 'position'>) => void; onNodeMove: ({ data, }: Omit, 'e' | 'position'>) => void; onNodeResize: ({ model, }: Omit, 'e' | 'position'>) => void; onGraphRendered: ({ data }: CallbackArgs<'graph:rendered'>) => void; removeChildrenInGroupNodeData(nodeData: T): T; /** * 创建一个 Group 类型节点内部所有子节点的副本 * 并且在遍历所有 nodes 的过程中,顺便拿到所有 edges (只在 Group 范围的 edges) */ initGroupChildNodes(nodeIdMap: Record, children: Set, curGroup: DynamicGroupNodeModel, distance: number): ElementsInfoInGroup; /** * 根据参数 edge 选择是新建边还是基于已有边,复制一条边出来 * @param edge * @param nodeIdMap * @param distance */ createEdge(edge: EdgeConfig | EdgeData, nodeIdMap: Record, distance: number): BaseEdgeModel; /** * 检测group:resize后的bounds是否会小于children的bounds * 限制group进行resize时不能小于内部的占地面积 * @param groupModel * @param deltaX * @param deltaY * @param newWidth * @param newHeight */ checkGroupBoundsWithChildren(groupModel: DynamicGroupNodeModel, deltaX: number, deltaY: number, newWidth: number, newHeight: number): boolean; /** * Group 插件的初始化方法 * TODO:1. 待讨论,可能之前插件分类是有意义的 components, material, tools * 区别是:1. 有些插件就是自定义节点,可能会有初始化方法 init,但不必要有 render (比如 Group) * 2. 有些插件是渲染一些部件(比如 MiniMap、Control、Menu 等)必须要有 render * 3. 工具类的,init 、 render * 该如何分类呢?并如何完善插件的类型 * * TODO: 2. 插件的 destroy 方法该做些什么,是否应该加 destroy 方法 * TODO: 3. 是否应该定义一个 Extension 的基类,所有插件基于这个基类来开发,这样在初始化的时候就可以确认执行什么方法 */ init(): void; render(): void; destroy(): void; } export declare namespace DynamicGroup { type ElementsInfoInGroup = { childNodes: BaseNodeModel[]; edgesData: EdgeData[]; }; type DynamicGroupOptions = Partial<{ isCollapsed: boolean; /** 为 true 时禁止手动将边连到/从分组节点;默认 false */ disallowEdgeConnectToGroup: boolean; /** 删除分组时是否级联删除成员;默认 true */ cascadeDeleteChildren: boolean; /** 拖拽节点进入分组时的感应外框样式 */ sensorOutline: SensorOutlineOptions; }>; } export default DynamicGroup;