import EventEmitter from '@antv/event-emitter'; import { IGroup, Point } from '@antv/g-base'; import { Stack } from '@antv/algorithm'; import { IAbstractGraph } from '../interface/graph'; import { IEdge, INode, ICombo } from '../interface/item'; import { GraphAnimateConfig, GraphOptions, EdgeConfig, GraphData, Item, ITEM_TYPE, ModelConfig, NodeConfig, NodeMap, Padding, TreeGraphData, ComboConfig, ModeOption, ModeType, States, HullCfg, IG6GraphEvent, IPoint, FitViewRules, G6Event } from '../types'; import Hull from '../item/hull'; export interface PrivateGraphOption extends GraphOptions { data: GraphData; event: boolean; nodes: NodeConfig[]; edges: EdgeConfig[]; vedges: EdgeConfig[]; combos: ComboConfig[]; itemMap: NodeMap; callback: () => void; /** * 格式: * { * hover: [Node, Node], * selected: [Node] * } */ states: States; } export default abstract class AbstractGraph extends EventEmitter implements IAbstractGraph { protected animating: boolean; protected cfg: GraphOptions & { [key: string]: any; }; destroyed: boolean; protected undoStack: Stack; protected redoStack: Stack; constructor(cfg: GraphOptions); protected init(): void; protected abstract initLayoutController(): void; protected abstract initEventController(): void; /** * initCanvas 需要在 PC 和 Mobile 分别实现 */ protected abstract initCanvas(): void; /** * initPlugins 需要在 PC 和 Mobile 分别实现 */ protected abstract initPlugins(): void; protected initGroups(): void; getDefaultCfg(): Partial; /** * 将值设置到 this.cfg 变量上面 * @param key 键 或 对象值 * @param val 值 */ set(key: string | object, val?: T): AbstractGraph; /** * 获取 this.cfg 中的值 * @param key 键 */ get(key: string): any; /** * 获取 graph 的根图形分组 * @return 根 group */ getGroup(): IGroup; /** * 获取 graph 的 DOM 容器 * @return DOM 容器 */ getContainer(): HTMLElement; /** * 获取 graph 的最小缩放比例 * @return minZoom */ getMinZoom(): number; /** * 设置 graph 的最小缩放比例 * @return minZoom */ setMinZoom(ratio: number): AbstractGraph; /** * 获取 graph 的最大缩放比例 * @param maxZoom */ getMaxZoom(): number; /** * 设置 graph 的最大缩放比例 * @param maxZoom */ setMaxZoom(ratio: number): AbstractGraph; /** * 获取 graph 的宽度 * @return width */ getWidth(): number; /** * 获取 graph 的高度 * @return width */ getHeight(): number; /** * 清理元素多个状态 * @param {string|Item} item 元素id或元素实例 * @param {string[]} states 状态 */ clearItemStates(item: Item | string, states?: string[] | string): void; /** * 设置各个节点样式,以及在各种状态下节点 keyShape 的样式。 * 若是自定义节点切在各种状态下 * graph.node(node => { * return { * type: 'rect', * label: node.id, * style: { fill: '#666' }, * stateStyles: { * selected: { fill: 'blue' }, * custom: { fill: 'green' } * } * } * }); * @param {function} nodeFn 指定每个节点样式 */ node(nodeFn: (config: NodeConfig) => Partial): void; /** * 设置各个边样式 * @param {function} edgeFn 指定每个边的样式,用法同 node */ edge(edgeFn: (config: EdgeConfig) => Partial): void; /** * 设置各个 combo 的配置 * @param comboFn */ combo(comboFn: (config: ComboConfig) => Partial): void; /** * 根据 ID 查询图元素实例 * @param id 图元素 ID */ findById(id: string): Item; /** * 根据对应规则查找单个元素 * @param {ITEM_TYPE} type 元素类型(node | edge | group) * @param {(item: T, index: number) => T} fn 指定规则 * @return {T} 元素实例 */ find(type: ITEM_TYPE, fn: (item: T, index?: number) => boolean): T | undefined; /** * 查找所有满足规则的元素 * @param {string} type 元素类型(node|edge) * @param {string} fn 指定规则 * @return {array} 元素实例 */ findAll(type: ITEM_TYPE, fn: (item: T, index?: number) => boolean): T[]; /** * 查找所有处于指定状态的元素 * @param {string} type 元素类型(node|edge) * @param {string} state 状态 * @return {object} 元素实例 */ findAllByState(type: ITEM_TYPE, state: string, additionalFilter?: (item: Item) => boolean): T[]; /** * 平移画布 * @param dx 水平方向位移 * @param dy 垂直方向位移 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 */ translate(dx: number, dy: number, animate?: boolean, animateCfg?: GraphAnimateConfig): void; /** * 平移画布到某点 * @param {number} x 水平坐标 * @param {number} y 垂直坐标 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 */ moveTo(x: number, y: number, animate?: boolean, animateCfg?: GraphAnimateConfig): void; /** * 调整视口适应视图 * @param {object} padding 四周围边距 * @param {FitViewRules} rules fitView的规则 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 */ fitView(padding?: Padding, rules?: FitViewRules, animate?: boolean, animateCfg?: GraphAnimateConfig): void; /** * 调整视口适应视图,不缩放,仅将图 bbox 中心对齐到画布中心 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 */ fitCenter(animate?: boolean, animateCfg?: GraphAnimateConfig): void; /** * 新增行为 * @param {string | ModeOption | ModeType[]} behaviors 添加的行为 * @param {string | string[]} modes 添加到对应的模式 * @return {Graph} Graph */ addBehaviors(behaviors: string | ModeOption | ModeType[], modes: string | string[]): AbstractGraph; /** * 移除行为 * @param {string | ModeOption | ModeType[]} behaviors 移除的行为 * @param {string | string[]} modes 从指定的模式中移除 * @return {Graph} Graph */ removeBehaviors(behaviors: string | ModeOption | ModeType[], modes: string | string[]): AbstractGraph; /** * 更新行为参数 * @param {string | ModeOption | ModeType} behavior 需要更新的行为 * @param {string | string[]} modes 指定的模式中的行为,不指定则为 default * @return {Graph} Graph */ updateBehavior(behavior: string, newCfg: object, mode?: string): AbstractGraph; /** * 伸缩窗口 * @param ratio 伸缩比例 * @param center 以center的x, y坐标为中心缩放 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 * @return {boolean} 缩放是否成功 */ zoom(ratio: number, center?: Point, animate?: boolean, animateCfg?: GraphAnimateConfig): boolean; /** * 伸缩视口到一固定比例 * @param {number} toRatio 伸缩比例 * @param {Point} center 以center的x, y坐标为中心缩放 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 * @return {boolean} 缩放是否成功 */ zoomTo(toRatio: number, center?: Point, animate?: boolean, animateCfg?: GraphAnimateConfig): boolean; /** * 将元素移动到视口中心 * @param {Item} item 指定元素 * @param {boolean} animate 是否带有动画地移动 * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项 */ focusItem(item: Item | string, animate?: boolean, animateCfg?: GraphAnimateConfig): void; /** * Focus on the passed items * @param {Item[]} items Items you want to focus on * @param {boolean} zoomToFit Wether to zoom on the passed items * @param {boolean} animate Wether to animate the transition * @param {GraphAnimateConfig} animateCfg Animation configuration */ focusItems(items: Item[], zoomToFit?: boolean, animate?: boolean, animateCfg?: GraphAnimateConfig): void; /** * 自动重绘 * @internal 仅供内部更新机制调用,外部根据需求调用 render 或 paint 接口 */ autoPaint(): void; /** * 仅画布重新绘制 */ paint(): void; /** * 将屏幕坐标转换为视口坐标 * @param {number} clientX 屏幕x坐标 * @param {number} clientY 屏幕y坐标 * @return {Point} 视口坐标 */ getPointByClient(clientX: number, clientY: number): Point; /** * 将绘制坐标转换为屏幕坐标 * @param {number} x 绘制坐标 x * @param {number} y 绘制坐标 y * @return {Point} 绘制坐标 */ getClientByPoint(x: number, y: number): Point; /** * 将画布坐标转换为绘制坐标 * @param {number} canvasX 画布 x 坐标 * @param {number} canvasY 画布 y 坐标 * @return {object} 绘制坐标 */ getPointByCanvas(canvasX: number, canvasY: number): Point; /** * 将绘制坐标转换为画布坐标 * @param {number} x 绘制坐标 x * @param {number} y 绘制坐标 y * @return {object} 画布坐标 */ getCanvasByPoint(x: number, y: number): Point; /** * 获取图内容的中心绘制坐标 * @return {object} 中心绘制坐标 */ getGraphCenterPoint(): Point; /** * 获取视口中心绘制坐标 * @return {object} 视口中心绘制坐标 */ getViewPortCenterPoint(): Point; /** * 显示元素 * @param {Item} item 指定元素 * @param {boolean} stack 本次操作是否入栈,默认为 true */ showItem(item: Item | string, stack?: boolean): void; /** * 隐藏元素 * @param {Item} item 指定元素 * @param {boolean} stack 本次操作是否入栈,默认为 true */ hideItem(item: Item | string, stack?: boolean): void; /** * 刷新元素 * @param {string|object} item 元素id或元素实例 */ refreshItem(item: Item | string): void; /** * 设置是否在更新/刷新后自动重绘 * @param {boolean} auto 自动重绘 */ setAutoPaint(auto: boolean): void; /** * 删除元素 * @param {Item} item 元素id或元素实例 * @param {boolean} stack 本次操作是否入栈,默认为 true */ remove(item: Item | string, stack?: boolean): void; /** * 删除元素 * @param {Item} item 元素id或元素实例 * @param {boolean} stack 本次操作是否入栈,默认为 true */ removeItem(item: Item | string, stack?: boolean): void; private innerAddItem; /** * 新增元素 * @param {ITEM_TYPE} type 元素类型(node | edge) * @param {ModelConfig} model 元素数据模型 * @param {boolean} stack 本次操作是否入栈,默认为 true * @param {boolean} sortCombo 本次操作是否需要更新 combo 层级顺序,内部参数,用户在外部使用 addItem 时始终时需要更新 * @return {Item} 元素实例 */ addItem(type: ITEM_TYPE, model: ModelConfig, stack?: boolean, sortCombo?: boolean): Item | boolean; addItems(items?: { type: ITEM_TYPE; model: ModelConfig; }[], stack?: boolean, sortCombo?: boolean): (boolean | Item)[]; /** * 新增元素 * @param {ITEM_TYPE} type 元素类型(node | edge) * @param {ModelConfig} model 元素数据模型 * @param {boolean} stack 本次操作是否入栈,默认为 true * @param {boolean} sortCombo 本次操作是否需要更新 combo 层级顺序,内部参数,用户在外部使用 addItem 时始终时需要更新 * @return {Item} 元素实例 */ add(type: ITEM_TYPE, model: ModelConfig, stack?: boolean, sortCombo?: boolean): Item | boolean; /** * 更新元素 * @param {Item} item 元素id或元素实例 * @param {Partial | EdgeConfig} cfg 需要更新的数据 */ updateItem(item: Item | string, cfg: Partial | EdgeConfig, stack?: boolean): void; /** * 更新元素 * @param {Item} item 元素id或元素实例 * @param {Partial | EdgeConfig} cfg 需要更新的数据 * @param {boolean} stack 本次操作是否入栈,默认为 true */ update(item: Item | string, cfg: Partial | EdgeConfig, stack?: boolean): void; /** * 设置元素状态 * @param {Item} item 元素id或元素实例 * @param {string} state 状态名称 * @param {string | boolean} value 是否启用状态 或 状态值 */ setItemState(item: Item | string, state: string, value: string | boolean): void; /** * 将指定状态的优先级提升为最高优先级 * @param {Item} item 元素id或元素实例 * @param state 状态名称 */ priorityState(item: Item | string, state: string): void; /** * 设置视图初始化数据 * @param {GraphData} data 初始化数据 */ data(data?: GraphData | TreeGraphData): void; /** * 根据data接口的数据渲染视图 */ render(): void; /** * 接收数据进行渲染 * @Param {Object} data 初始化数据 */ read(data: GraphData): void; protected diffItems(type: ITEM_TYPE, items: { nodes: INode[]; edges: IEdge[]; }, models: NodeConfig[] | EdgeConfig[]): void; /** * 更改源数据,根据新数据重新渲染视图 * @param {GraphData | TreeGraphData} data 源数据 * @param {boolean} 是否入栈,默认为true * @return {object} this */ changeData(propsData?: GraphData | TreeGraphData, stack?: boolean): AbstractGraph; /** * 私有方法,在 render 和 changeData 的时候批量添加数据中所有平铺的 combos * @param {ComboConfig[]} combos 平铺的 combos 数据 */ protected addCombos(combos: ComboConfig[]): void; /** * 根据已经存在的节点或 combo 创建新的 combo * @param combo combo ID 或 Combo 配置 * @param childrenIds 添加到 Combo 中的元素,包括节点和 combo */ createCombo(combo: string | ComboConfig, childrenIds: string[], stack?: boolean): void; /** * 解散 combo * @param {String | INode | ICombo} combo 需要被解散的 Combo item 或 id */ uncombo(combo: string | ICombo, stack?: boolean): void; /** * 根据 combo 位置更新内部节点位置 followCombo = true * 或根据内部元素的 bbox 更新所有 combos 的绘制,包括 combos 的位置和范围,followCombo = false */ updateCombos(followCombo?: boolean): void; /** * 根据节点的 bbox 更新 combo 及其祖先 combos 的绘制,包括 combos 的位置和范围 * @param {String | ICombo} combo 需要被更新的 Combo 或 id,若指定,则该 Combo 及所有祖先 Combod 都会被更新 */ updateCombo(combo: string | ICombo): void; /** * 更新树结构,例如移动子树等 * @param {String | INode | ICombo} item 需要被更新的 Combo 或 节点 id * @param {string | undefined} parentId 新的父 combo id,undefined 代表没有父 combo */ updateComboTree(item: string | INode | ICombo, parentId?: string | undefined, stack?: boolean): void; /** * 导出图数据 * @return {object} data */ save(): GraphData | TreeGraphData; /** * 改变画布大小 * @param {number} width 画布宽度 * @param {number} height 画布高度 * @return {object} this */ changeSize(width: number, height: number): AbstractGraph; /** * 当源数据在外部发生变更时,根据新数据刷新视图。但是不刷新节点位置 */ refresh(): void; /** * 获取当前图中所有节点的item实例 * @return {INode} item数组 */ getNodes(): INode[]; /** * 获取当前图中所有边的item实例 * @return {IEdge} item数组 */ getEdges(): IEdge[]; /** * 获取图中所有的 combo 实例 */ getCombos(): ICombo[]; /** * 获取指定 Combo 中所有的节点 * @param comboId combo ID */ getComboChildren(combo: string | ICombo): { nodes: INode[]; combos: ICombo[]; }; /** * 根据 graph 上的 animateCfg 进行视图中节点位置动画接口 */ positionsAnimate(referComboModel?: boolean): void; /** * 当节点位置在外部发生改变时,刷新所有节点位置,重计算边 */ refreshPositions(referComboModel?: boolean): void; stopAnimate(): void; isAnimating(): boolean; /** * 获取当前视口伸缩比例 * @return {number} 比例 */ getZoom(): number; /** * 获取当前的行为模式 * @return {string} 当前行为模式 */ getCurrentMode(): string; /** * 切换行为模式 * @param {string} mode 指定模式 * @return {object} this */ setMode(mode: string): AbstractGraph; /** * 清除画布元素 * @return {object} this */ clear(avoidEmit?: boolean): AbstractGraph; /** * 更换布局配置项 * @param {object} cfg 新布局配置项 * @param {'center' | 'begin'} align 对齐方式,可选中心(center)对齐到对齐点,或左上角(begin)对齐到对齐点 * @param {IPoint} alignPoint 画布上的对齐点,为 Canvas 坐标系(Canvas DOM) * 若 cfg 含有 type 字段或为 String 类型,且与现有布局方法不同,则更换布局 * 若 cfg 不包括 type ,则保持原有布局方法,仅更新布局配置项 */ updateLayout(cfg?: any, align?: 'center' | 'begin', alignPoint?: IPoint, stack?: boolean): void; /** * 销毁布局,changeData 时不会再使用原来的布局方法对新数据进行布局 */ destroyLayout(): void; /** * 重新以当前示例中配置的属性进行一次布局 */ layout(): void; /** * 收起指定的 combo * @param {string | ICombo} combo combo ID 或 combo item */ collapseCombo(combo: string | ICombo, stack?: boolean): void; /** * 展开指定的 combo * @param {string | ICombo} combo combo ID 或 combo item */ expandCombo(combo: string | ICombo, stack?: boolean): void; collapseExpandCombo(combo: string | ICombo, stack?: boolean): void; /** * 根据 comboTree 结构整理 Combo 相关的图形绘制层级,包括 Combo 本身、节点、边 * @param {GraphData} data 数据 */ protected sortCombos: () => void; /** * 获取节点所有的邻居节点 * * @param {(string | INode)} node 节点 ID 或实例 * @returns {INode[]} * @memberof IAbstractGraph */ getNeighbors(node: string | INode, type?: 'source' | 'target' | undefined): INode[]; /** * 获取 node 的度数 * * @param {(string | INode)} node 节点 ID 或实例 * @param {('in' | 'out' | 'total' | 'all' | undefined)} 度数类型,in 入度,out 出度,total 总度数,all 返回三种类型度数的对象 * @returns {Number | Object} 该节点的度数 * @memberof IAbstractGraph */ getNodeDegree(node: string | INode, type?: 'in' | 'out' | 'total' | 'all' | undefined, refresh?: boolean): Number | Object; getUndoStack(): Stack; getRedoStack(): Stack; /** * 获取 undo 和 redo 栈的数据 */ getStackData(): { undoStack: any[]; redoStack: any[]; }; /** * 清空 undo stack & redo stack */ clearStack(): void; /** * 将操作类型和操作数据入栈 * @param action 操作类型 * @param data 入栈的数据 * @param stackType 栈的类型 */ pushStack(action?: string, data?: unknown, stackType?: string): void; /** * 获取邻接矩阵 * * @param {boolean} cache 是否使用缓存的 * @param {boolean} directed 是否是有向图,默认取 graph.directed * @returns {Matrix} 邻接矩阵 * @memberof IAbstractGraph */ getAdjMatrix(cache?: boolean, directed?: boolean): Number | Object; /** * 获取最短路径矩阵 * * @param {boolean} cache 是否使用缓存的 * @param {boolean} directed 是否是有向图,默认取 graph.directed * @returns {Matrix} 最短路径矩阵 * @memberof IAbstractGraph */ getShortestPathMatrix(cache?: boolean, directed?: boolean): Number | Object; /** * 重新定义监听函数,复写参数类型 */ on(eventName: G6Event, callback: (e: T) => void, once?: boolean): this; /** * 销毁画布 */ destroy(): void; /** * 创建凸包或凹包轮廓 * @param cfg HullCfg 轮廓配置项 */ createHull(cfg: HullCfg): any; /** * 获取当前 graph 中存在的包裹轮廓 * @return {[key: string]: Hull} Hull 的 map,hullId 对应的 hull 实例 */ getHulls(): { [key: string]: Hull; }; /** * 根据 hullId 获取对应的 hull * @return Hull */ getHullById(hullId: string): Hull; removeHull(hull: Hull | string): void; removeHulls(): void; }