Grid 网格布局
上一篇
Fruchterman 力导向布局
下一篇
Indented 缩进树
Loading...
网格布局将节点按照网格形式排列,适用于需要整齐排列节点的场景。该布局支持自动计算行列数,也可以手动指定行列数,并支持防止节点重叠。
createGraph({data: {nodes: Array.from({ length: 25 }, (_, i) => ({id: `node-${i}`,data: {value: Math.random() * 100,},})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 25)}`,target: `node-${Math.floor(Math.random() * 25)}`,})),},autoFit: 'view',node: {style: {size: 20,label: true,labelText: (datum) => datum.id,labelBackground: true,icon: false,},palette: {type: 'group',field: (datum) => datum.data.value,color: ['#1783FF', '#00C9C9', '#F08F56', '#D580FF'],},},edge: {style: {stroke: '#bfbfbf',},},behaviors: ['drag-canvas'],layout: {type: 'grid',cols: 5,rows: 5,width: 400,height: 400,preventOverlap: true,nodeSize: 30,condense: false,},},{ width: 600, height: 400 },(gui, graph) => {const options = {type: 'grid',cols: 5,rows: 5,width: 400,height: 400,preventOverlap: true,nodeSize: 30,condense: false,};const optionFolder = gui.addFolder('Grid Layout Options');optionFolder.add(options, 'type').disable(true);optionFolder.add(options, 'cols', 2, 10, 1);optionFolder.add(options, 'rows', 2, 10, 1);optionFolder.add(options, 'width', 200, 600, 50);optionFolder.add(options, 'height', 200, 600, 50);optionFolder.add(options, 'preventOverlap');optionFolder.add(options, 'nodeSize', 10, 50, 5);optionFolder.add(options, 'condense');optionFolder.onChange(({ property, value }) => {graph.setLayout({type: 'grid',[property]: value,});graph.layout();});},);
const graph = new Graph({layout: {type: 'grid',begin: [0, 0],cols: 5,rows: 5,width: 300,height: 300,preventOverlap: true,nodeSize: 30,condense: false,},});
属性 | 描述 | 类型 | 默认值 | 必选 |
---|---|---|---|---|
type | 布局类型 | grid | - | ✓ |
begin | 网格开始位置(左上角),默认为 [0, 0] | [number, number] | [0, 0] | |
cols | 网格的列数,为 undefined 时算法根据节点数量、布局空间、rows(若指定)自动计算 | number | undefined | |
rows | 网格的行数,为 undefined 时算法根据节点数量、布局空间、cols(若指定)自动计算 | number | 10 | |
width | 布局区域宽度,在 G6 中使用当前容器的宽度作为默认值 | number | 300 | |
height | 布局区域高度,在 G6 中使用当前容器的高度作为默认值 | number | 300 | |
condense | 为 false 时表示利用所有可用画布空间,为 true 时表示利用最小的画布空间 | boolean | false | |
nodeSize | 节点大小(直径),用于防止节点重叠时的碰撞检测 | Size | ((nodeData: Node) => Size) | - | |
nodeSpacing | 节点间距,用于调整节点之间的间隔 | ((node?: Node) => number) | number | - | |
position | 指定每个节点所在的行和列 | (node?: Node) => { row?: number; col?: number; } | undefined | |
preventOverlap | 是否防止节点重叠,需要配合 nodeSize 或节点数据中的 size 属性使用 | boolean | false | |
preventOverlapPadding | 避免重叠时节点的间距 padding,preventOverlap 为 true 时生效 | number | 10 | |
sortBy | 指定排序的依据(节点属性名),数值越高则该节点被放置得越中心。若为 undefined,则会计算节点的度数,度数越高,节点将被放置得越中心 | string | undefined |
boolean Default:
false
是否防止重叠
必须配合下面属性 nodeSize 或节点数据中的 data.size 属性,只有在数据中设置了 data.size 或在该布局中配置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测
number Default:
10
避免重叠时节点的间距 padding,preventOverlap 为 true 时生效
string Default:
undefined
指定排序的依据(节点属性名),数值越高则该节点被放置得越中心。若为 undefined,则会计算节点的度数,度数越高,节点将被放置得越中心
在 G6 中使用当前容器的宽度作为 grid 布局 width 的默认值。单独使用此布局时默认值为 300
最简单的配置方式:
const graph = new Graph({layout: {type: 'grid',cols: 5,rows: 5,},data: {nodes: Array.from({ length: 25 }, (_, i) => ({id: `node-${i}`,data: {value: Math.random() * 100,},})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 25)}`,target: `node-${Math.floor(Math.random() * 25)}`,})),},});
效果如下:
createGraph({layout: {type: 'grid',cols: 5,rows: 5,},data: {nodes: Array.from({ length: 25 }, (_, i) => ({id: `node-${i}`,data: {value: Math.random() * 100,},})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 25)}`,target: `node-${Math.floor(Math.random() * 25)}`,})),},node: {style: {size: 20,label: true,labelText: (datum) => datum.id,labelBackground: true,},},edge: {style: {stroke: '#bfbfbf',},},},{ width: 600, height: 400 },);
可以通过多种方式自定义网格布局:
const graph = new Graph({layout: {type: 'grid',begin: [50, 50], // 从坐标 [50, 50] 开始布局cols: 4, // 指定 4 列rows: 6, // 指定 6 行width: 400, // 布局区域宽度height: 600, // 布局区域高度preventOverlap: true, // 防止节点重叠nodeSize: 30, // 节点大小condense: true, // 使用最小空间sortBy: 'value', // 按 value 属性排序},data: {nodes: Array.from({ length: 24 }, (_, i) => ({id: `node-${i}`,data: {value: Math.random() * 100, // 用于排序的属性},})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 24)}`,target: `node-${Math.floor(Math.random() * 24)}`,})),},});
效果如下:
createGraph({layout: {type: 'grid',begin: [50, 50],cols: 4,rows: 6,width: 400,height: 600,preventOverlap: true,nodeSize: 30,condense: true,sortBy: 'value',},data: {nodes: Array.from({ length: 24 }, (_, i) => ({id: `node-${i}`,data: {value: Math.random() * 100,},})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 24)}`,target: `node-${Math.floor(Math.random() * 24)}`,})),},node: {style: {size: 20,label: true,labelText: (datum) => datum.id,labelBackground: true,},palette: {type: 'group',field: (datum) => datum.data.value,color: ['#1783FF', '#00C9C9', '#F08F56', '#D580FF'],},},edge: {style: {stroke: '#bfbfbf',},},},{ width: 600, height: 400 },);
可以通过 position
属性为特定节点指定位置:
const graph = new Graph({layout: {type: 'grid',cols: 5,rows: 5,position: (node) => {// 为特定节点指定位置if (node.id === 'node-0') return { row: 0, col: 0 }; // 左上角if (node.id === 'node-1') return { row: 0, col: 4 }; // 右上角if (node.id === 'node-2') return { row: 4, col: 0 }; // 左下角if (node.id === 'node-3') return { row: 4, col: 4 }; // 右下角return undefined; // 其他节点自动布局},},data: {nodes: Array.from({ length: 25 }, (_, i) => ({id: `node-${i}`,})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 25)}`,target: `node-${Math.floor(Math.random() * 25)}`,})),},});
效果如下:
createGraph({layout: {type: 'grid',cols: 5,rows: 5,position: (node) => {if (node.id === 'node-0') return { row: 0, col: 0 };if (node.id === 'node-1') return { row: 0, col: 4 };if (node.id === 'node-2') return { row: 4, col: 0 };if (node.id === 'node-3') return { row: 4, col: 4 };return undefined;},},data: {nodes: Array.from({ length: 25 }, (_, i) => ({id: `node-${i}`,})),edges: Array.from({ length: 20 }, (_, i) => ({id: `edge-${i}`,source: `node-${Math.floor(Math.random() * 25)}`,target: `node-${Math.floor(Math.random() * 25)}`,})),},node: {style: {size: 20,label: true,labelText: (datum) => datum.id,labelBackground: true,},},edge: {style: {stroke: '#bfbfbf',},},},{ width: 600, height: 400 },);