70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
|
|
import { DagreLayout, type DagreLayoutOptions } from '@antv/layout'
|
|||
|
|
|
|||
|
|
export default class Dagre {
|
|||
|
|
static pluginName = 'dagre'
|
|||
|
|
lf: any
|
|||
|
|
option: DagreLayoutOptions | any
|
|||
|
|
render(lf: any) {
|
|||
|
|
this.lf = lf
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* option: {
|
|||
|
|
* rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
|
|||
|
|
* align: undefined, // 节点对齐方式,可选 UL, UR, DL, DR
|
|||
|
|
* nodeSize: undefined, // 节点大小
|
|||
|
|
* nodesepFunc: undefined, // 节点水平间距(px)
|
|||
|
|
* ranksepFunc: undefined, // 每一层节点之间间距
|
|||
|
|
* nodesep: 40, // 节点水平间距(px) 注意:如果有grid,需要保证nodesep为grid的偶数倍
|
|||
|
|
* ranksep: 40, // 每一层节点之间间距 注意:如果有grid,需要保证ranksep为grid的偶数倍
|
|||
|
|
* controlPoints: false, // 是否保留布局连线的控制点
|
|||
|
|
* radial: false, // 是否基于 dagre 进行辐射布局
|
|||
|
|
* focusNode: null, // radial 为 true 时生效,关注的节点
|
|||
|
|
* };
|
|||
|
|
*/
|
|||
|
|
layout(option = {}) {
|
|||
|
|
const { nodes, edges, gridSize } = this.lf.graphModel
|
|||
|
|
// 为了保证生成的节点在girdSize上,需要处理一下。
|
|||
|
|
let nodesep = 40
|
|||
|
|
let ranksep = 40
|
|||
|
|
if (gridSize > 20) {
|
|||
|
|
nodesep = gridSize * 2
|
|||
|
|
ranksep = gridSize * 2
|
|||
|
|
}
|
|||
|
|
this.option = {
|
|||
|
|
type: 'dagre',
|
|||
|
|
rankdir: 'LR',
|
|||
|
|
// align: 'UL',
|
|||
|
|
// align: 'UR',
|
|||
|
|
align: 'DR',
|
|||
|
|
nodesep,
|
|||
|
|
ranksep,
|
|||
|
|
begin: [120, 120],
|
|||
|
|
...option
|
|||
|
|
}
|
|||
|
|
const layoutInstance = new DagreLayout(this.option)
|
|||
|
|
const layoutData = layoutInstance.layout({
|
|||
|
|
nodes: nodes.map((node: any) => ({
|
|||
|
|
id: node.id,
|
|||
|
|
size: {
|
|||
|
|
width: node.width,
|
|||
|
|
height: node.height
|
|||
|
|
},
|
|||
|
|
model: node
|
|||
|
|
})),
|
|||
|
|
edges: edges.map((edge: any) => ({
|
|||
|
|
source: edge.sourceNodeId,
|
|||
|
|
target: edge.targetNodeId,
|
|||
|
|
model: edge
|
|||
|
|
}))
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
layoutData.nodes?.forEach((node: any) => {
|
|||
|
|
// @ts-ignore: pass node data
|
|||
|
|
const { model } = node
|
|||
|
|
model.set_position({ x: node.x, y: node.y })
|
|||
|
|
})
|
|||
|
|
this.lf.fitView()
|
|||
|
|
}
|
|||
|
|
}
|