一般图布局 Layout

阅读时间约 16 分钟

简介

图布局是指图中节点的排布方式,根据图的数据结构不同,布局可以分为两类:一般图布局、树图布局。F6 为这两类图都内置了一些常用的图布局算法。使用内置的图布局可以完成布局的参数、方法、数据的切换等。F6 还提供了一般图布局的 Web-Worker 机制,在大规模图布局中使用该机制可以使布局计算不阻塞页面。

除了内置布局方法外,一般图布局还支持 自定义布局 机制。

事实上,F6 的布局是自由的,内置布局算法仅仅是操作了数据中节点的 xy 值。因此,除了使用内置布局以及自定义的一般图布局外,用户还可以使用外部图布局算法,计算节点位置后赋值到数据中节点的 xy 字段上,F6 便可以根据该位置信息进行绘制。

本文将逐一介绍内置的布局算法,及其使用方式。

一般图 Graph 布局方法总览

配置一般图布局

用户可以通过在实例化图时使用图的配置项 layout 指定布局方法。下面代码在实例化图时设置了布局方法为 type: 'force',即经典力导向图布局。并设置了参数 preventOverlap: true  和 nodeSize: 30,表示希望节点不重叠。节点大小 nodeSize 用于算法中判断节点是否重叠,更多配置项见各布局的配置项。

const graph = new F6.Graph({
  // ...                      // 其他配置项
  layout: {
    // Object,可选,布局的方法及其配置项,默认为 random 布局。
    type: 'force',
    preventOverlap: true,
    nodeSize: 30,
    // workerEnabled: true, // 是否启用 webworker
    // gpuEnabled: true // 是否使用 gpu 版本的布局算法,F6 4.0 支持,目前仅支持 gForce 及 fruchterman
    // ...                    // 其他配置
  },
});

除了每种布局方法各自的配置项外,所有布局方法都可以在上面代码的 layout 中配置 workerEnabled: true 以开启布局的 web-worker 机制。开启后图的布局计算过程将不会阻塞页面。

当实例化图时没有配置布局时:

  • 若数据中节点有位置信息(xy),则按照数据的位置信息进行绘制;
  • 若数据中节点没有位置信息,则默认使用 Random Layout 进行布局。

一般图布局方法

图布局通用 API:Layout API

Random

img


描述:随机布局。
APIRandom API
参数

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
widthNumber300图的宽
heightNumber300图的高
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

GForce

img


描述:F6 4.0 支持的经典力导向布局。能够更加自由地支持设置节点质量、群组中心力等。更重要的是,它支持 GPU 并行计算。
APIForce API
参数

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
linkDistanceNumber / Function示例 1: 50 
示例 2:
d => {
  // d 是一条边
  if (d.id === 'edge1') {
    return 100;
  }
  return 50;
}
1边长。可以使用回调函数的形式对不同对边定义不同边长(如示例 2)
nodeStrengthNumber / Function示例 1: -30 
示例 2:
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return -100;
  }
  return -30;
} / 1000
1000节点作用力,正数代表节点之间的斥力作用,负数代表节点之间的引力作用(注意与 'force' 相反)(如示例 2)
edgeStrengthNumber / Function示例 1: 1 
示例 2:
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 10;
  }
  return 1;
}
200边的作用力,默认根据节点的出入度自适应。可以使用回调函数的形式对不同对节点定义不同边作用力(如示例 2)
preventOverlapBooleanfalsefalse是否防止重叠,必须配合属性 nodeSize ,只有设置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测。若未设置 nodeSize ,则根据节点数据中的 size 进行碰撞检测。若二者都未设置,则默认以 10 为节点大小进行碰撞检测
nodeSizeArray / Number20undefined节点大小(直径)。用于碰撞检测。
若不指定,则根据传入的数据节点中的 size  字段计算。若即不指定,节点中也没有 size,则默认大小为 10
nodeSpacing

Number / Function示例 1 : 10
示例 2 : 
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
preventOverlaptrue 时生效,防止重叠时节点边缘间距的最小值。可以是回调函数,为不同节点设置不同的最小间距,如示例 2 所示
minMovementNumber0.10.5当一次迭代的平均移动长度小于该值时停止迭代。数字越小,布局越收敛,所用时间将越长
maxIterationNumber5001000最大迭代次数。当迭代次数超过该值,但平均移动长度仍然没有达到 minMovement,也将强制停止迭代
dampingNumber0.990.9阻尼系数,取值范围 [0, 1]。数字越大,速度降低得越慢
maxSpeedNumber101000一次迭代的最大移动长度
coulombDisScaleNumber0.0030.005库伦系数,斥力的一个系数,数字越大,节点之间的斥力越大
getMassFunctiond => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
undefined每个节点质量的回调函数,若不指定,则默认使用度数作为节点质量。使用方法与 nodeSpacing 类似,每个回调函数返回一个数值作为该节点的质量
getCenterFunction(d, degree) => {
  // d 是一个节点, degree 为该节点度数
  if (d.degree === 0') {
    return [100, 100, 10]; // x, y, 强度
  }
  return [210, 150, 5]; // x, y, 强度
}
undefined每个节点中心力的 x、y、强度的回调函数,若不指定,则没有额外中心力
gravityNumber2010中心力大小,指所有节点被吸引到 center 的力。数字越大,布局越紧凑
onTickFunction{}每一次迭代的回调函数
onLayoutEndFunction{}布局完成后的回调函数
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互
gpuEnabledBooleantrue / falsefalse是否启用 GPU 并行计算,F6 4.0 支持。若用户的机器或浏览器不支持 GPU 计算,将会自动降级为 CPU 计算

Force

img


描述:经典力导向布局。
APIForce API
参数:与 d3.js 的力导布局参数相对应。

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
linkDistanceNumber / Function示例 1: 50 
示例 2:
d => {
  // d 是一条边
  if (d.id === 'edge1') {
    return 100;
  }
  return 50;
}
50边长。可以使用回调函数的形式对不同对边定义不同边长(如示例 2)
nodeStrengthNumber / Function示例 1: -30 
示例 2:
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return -100;
  }
  return -30;
} / null
-30节点作用力,正数代表节点之间的引力作用,负数代表节点之间的斥力作用。可以使用回调函数的形式对不同对节点定义不同节点作用力(如示例 2)
edgeStrengthNumber / Function示例 1: 1 
示例 2:
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 10;
  }
  return 1;
}
null边的作用力,范围是 0 到 1,默认根据节点的出入度自适应。可以使用回调函数的形式对不同对节点定义不同边作用力(如示例 2)
preventOverlapBooleanfalsefalse是否防止重叠,必须配合属性 nodeSize ,只有设置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测。若未设置 nodeSize ,则根据节点数据中的 size 进行碰撞检测。若二者都未设置,则默认以 10 为节点大小进行碰撞检测
nodeSizeArray / Number20undefined节点大小(直径)。用于碰撞检测。
若不指定,则根据传入的数据节点中的 size  字段计算。若即不指定,节点中也没有 size,则默认大小为 10
nodeSpacing

Number / Function示例 1 : 10
示例 2 : 
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
preventOverlaptrue 时生效,防止重叠时节点边缘间距的最小值。可以是回调函数,为不同节点设置不同的最小间距,如示例 2 所示
alphaDecayNumber0.030.028迭代阈值的衰减率。范围 [0, 1],0.028 对应迭代数为 300
alphaMinNumber0.030.001停止迭代的阈值
alphaNumber0.10.3当前阈值
collideStrengthNumber0.81防止重叠的力强度,范围 [0, 1]
clusteringBooleanfalsefalse是否按照聚类信息布局
clusterNodeStrengthNumber-1-0.8聚类节点作用力。负数代表斥力
clusterEdgeStrengthNumber0.10.2聚类边作用力
clusterEdgeDistanceNumber10050聚类边长度
clusterNodeSizeNumber1015聚类节点大小 / 直径,直径越大,越分散
clusterFociStrengthNumber0.80.5用于 foci 的力
forceSimulationObjectnull自定义 force 方法,若不指定,则使用 d3 的方法。
onTickFunction{}每一次迭代的回调函数
onLayoutEndFunction{}布局完成后的回调函数
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

Fruchterman

img


描述:Fruchterman 布局,一种力导布局。
APIFruchterman API
参数

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
maxIterationNumber10001000最大迭代次数
gravityNumber1010重力大小,影响布局的紧凑程度
speedNumber11每次迭代节点移动的速度。速度太快可能会导致强烈震荡
clusteringBooleanfalsefalse是否按照聚类布局
clusterGravityNumber3010聚类内部的重力大小,影响聚类的紧凑程度
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互
gouEnabledBooleantrue / falsefalse是否启用 GPU 并行计算,F6 4.0 支持

Circular

img img img


描述:环形布局。
APICircular API
参数

参数名类型示例/可选值默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
radiusNumber50null圆的半径。若设置了 radius,则 startRadiusendRadius 不生效
startRadiusNumber10null螺旋状布局的起始半径
endRadiusNumber100null螺旋状布局的结束半径
clockwiseBooleantruetrue是否顺时针排列
divisionsNumber31节点在环上的分段数(几个段将均匀分布),在 endRadius - startRadius != 0 时生效
orderingStringnull'topology''degree'null节点在环上排序的依据。默认 null 代表直接使用数据中的顺序。'topology' 按照拓扑排序。'degree' 按照度数大小排序
angleRatioNumber11从第一个节点到最后节点之间相隔多少个 2*PI
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

Radial

img


描述:辐射状布局。
APIRadial API
参数

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
linkDistanceNumber5050边长
maxIterationNumber10001000停止迭代到最大迭代数
focusNodeString / Object'node1'null中心点,默认为数据中第一个节点。可以传入节点 id 或节点本身。
unitRadiusNumber10100每一圈距离上一圈的距离。默认填充整个画布,即根据图的大小决定
preventOverlapBooleanfalsefalse是否防止重叠,必须配合属性 nodeSize ,只有设置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测。

若未设置 nodeSize,则将会根据数据中节点的 size 字段数值进行碰撞检测计算。若二者皆未设置,则以节点大小为 10 进行计算。
maxPreventOverlapIterationNumber500200防止重叠步骤的最大迭代次数
nodeSizeNumber1010节点大小(直径)。用于防止节点重叠时的碰撞检测。

若未设置则使用数据中节点的 size 字段数值进行碰撞检测计算。若二者皆未设置,则以节点大小为 10 进行计算。
nodeSpacing
Number / Function示例 1 : 10
示例 2 : 
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
preventOverlaptrue 时生效,防止重叠时节点边缘间距的最小值。可以是回调函数,为不同节点设置不同的最小间距,如示例 2 所示
strictRadialBooleantruefalse是否必须是严格的 radial 布局,即每一层的节点严格布局在一个环上。preventOverlaptrue 时生效。详见 Radial-strictRadial API
- 当 preventOverlaptrue,且 strictRadialfalse 时,有重叠的节点严格沿着所在的环展开,但在一个环上若节点过多,可能无法完全避免节点重叠。
- 当 preventOverlaptrue,且 strictRadialtrue  时,允许同环上重叠的节点不严格沿着该环布局,可以在该环的前后偏移以避免重叠。
sortByString'data' / 'cluster'undefined同层节点布局后相距远近的依据。默认 undefined ,表示根据数据的拓扑结构(节点间最短路径)排布,即关系越近/点对间最短路径越小的节点将会被尽可能排列在一起;'data' 表示按照节点在数据中的顺序排列,即在数据顺序上靠近的节点将会尽可能排列在一起;也可以指定为节点数据中的某个字段名,例如 'cluster''name' 等(必须在数据中存在)
sortStrengthNumber1010同层节点根据 sortBy 排列的强度,数值越大,sortBy 指定的方式计算出距离越小的越靠近。sortBy 不为 undefined 时生效
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

MDS

img
描述:高维数据降维算法布局。
APIMDS API
参数

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
linkDistanceNumber5050边长
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

Dagre

img
描述:层次布局。
APIDagre API
参数

参数名类型示例/可选值默认值说明
rankdirString'TB' / 'BT' / 'LR' / 'RL''TB'layout 的方向。T:top;B:bottom;L:left;R:right
alignString'UL' / 'UR' / 'DL' / 'DR' / undefinedundefined节点对齐方式。默认值是 undefined,代表对齐到中心。U:upper;D:down;L:left;R:right
nodesepNumber4050rankdir'TB''BT' 时代表节点水平间距(px);在 rankdir'LR''RL' 时代表节点的竖直间距。优先级高于 nodesepFunc
ranksepNumber4050层间距(px)。在rankdir'TB''BT' 时是竖直方向相邻层间距;在rankdir'LR''RL' 时代表水平方向相邻层间距。优先级高于 ranksepFunc
nodesepFunc

Functiond => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
undefined节点水平间距(px)的回调函数,通过该参数可以对不同节点设置不同的节点间距。在rankdir 为 'TB' 或 'BT' 时是节点的水平间距;在rankdir 为 'LR' 或 'RL' 时是节点的竖直间距。优先级高于 nodesep,即若设置了 nodesep,则 nodesepFunc 不生效
ranksepFunc

Functiond => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
undefined层间距(px)的回调函数,通过该参数可以对不同节点设置不同的层间距。在rankdir 为 'TB' 或 'BT' 时是竖直方向相邻层间距;在rankdir 为 'LR' 或 'RL' 时代表水平方向相邻层间距。优先级低于 ranksep,即若设置了 ranksep,则 ranksepFunc 不生效
controlPointsBooleantruetrue是否保留布局连线的控制点
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互
sortByComboBooleantrue / falsefalse同一层节点是否根据每个节点数据中的 comboId 进行排序,以防止 combo 重叠

Concentric

img
注:该算法参考 cytoscape.js,遵守 MIT 开源协议。
描述:同心圆布局。
APIConcentric API
参数
参数名类型示例/可选值默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
nodeSizeNumber3030节点大小(直径)。用于防止节点重叠时的碰撞检测
minNodeSpacingNumber1010环与环之间最小间距,用于调整半径
preventOverlapBooleanfalsefalse是否防止重叠,必须配合属性 nodeSize ,只有设置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测。若未设置 nodeSize ,则将根据节点数据中的 size 进行碰撞检测。若二者都未设置,则默认以 30 为节点大小进行碰撞检测
sweepNumberMath.PIundefined第一个节点与最后一个节点之间的弧度差
equidistantBooleanfalsefalse环与环之间的距离是否相等
startAngleNumber3.143 / 2 * Math.PI开始放置节点的弧度
clockwiseBooleanfalsefalse是否按照顺时针顺序
maxLevelDiffNumber0.5undefined每一层同心值的求和。若为 undefined,则将会被设置为 maxValue / 4 ,其中 maxValue 为最大的排序依据的属性值。例如,若 sortBy='degree',则 maxValue 为所有节点中度数最大的节点的度数
sortByString'degree' / 'property1' / 'weight' / ...undefined指定的节点排序的依据(节点属性名)。该属性值高的放在中心。如果是 sortByundefined 则会计算节点度数,度数最高的放在中心。
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

Grid

img
注:该算法参考 cytoscape.js,遵守 MIT 开源协议。
描述:网格布局。
APIGrid API
参数
参数名类型示例/可选值默认值说明
beginArray[ 0, 0 ][ 0, 0 ]网格开始位置(左上角)
preventOverlapBooleanfalsefalse是否防止重叠,必须配合属性 nodeSize ,只有设置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测。若未设置 nodeSize ,则将根据节点数据中的 size 进行碰撞检测。若二者都未设置,则默认以 30 为节点大小进行碰撞检测
preventOverlapPaddingNumber1010避免重叠时节点的间距 padding。preventOverlaptrue 时生效
nodeSizeNumber3030节点大小(直径)。用于防止节点重叠时的碰撞检测
condenseBooleanfalsefalsefalse 时表示利用所有可用画布空间,为 true 时表示利用最小的画布空间
rowsNumber5undefined网格的行数,为 undefined 时算法根据节点数量、布局空间、cols(若指定)自动计算
colsNumber5undefined网格的列数,为 undefined 时算法根据节点数量、布局空间、rows(若指定)自动计算
sortByString'degree' / 'property1' / 'weight' / ...'degree'指定排序的依据(节点属性名),数值越高则该节点被放置得越中心。若为 undefined,则会计算节点的度数,度数越高,节点将被放置得越中心
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互

Combo Force

img
APICombo Force API
参数

参数名类型示例默认值说明
centerArray[ 0, 0 ]图的中心布局的中心
maxIterationNumber100100最大迭代次数
linkDistanceNumber / Function示例 1: 50 
示例 2:
d => {
  // d 是一条边
  if (d.id === 'edge1') {
    return 100;
  }
  return 50;
}
10边长。可以使用回调函数的形式对不同对边定义不同边长(如示例 2)
nodeStrengthNumber / Function示例 1: 10 
示例 2:
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 10;
  }
  return 30;
} / null
30节点作用力
edgeStrengthNumber / Function示例 1: 1 
示例 2:
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 10;
  }
  return 1;
}
0.2边的作用力
preventOverlapBooleanfalsefalse是否防止节点之间以及 combo 之间的重叠,若开启,则 preventNodeOverlappreventComboOverlap 将均被开启。详见 preventNodeOverlappreventComboOverlap 介绍
preventNodeOverlapBooleanfalsetrue是否防止节点之间的重叠。必须配合下面属性 nodeSize 或节点数据中的 size 属性,只有在数据中设置了 size 或在该布局中配置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测
preventComboOverlapBooleanfalsetrue是否防止 combo 之间的重叠
collideStrengthNumber0.1undefined统一设置防止节点之间以及 combo 之间重叠的力强度,范围 [0, 1]。若 collideStrength 不为 undefined,则 nodeCollideStrengthcomboCollideStrength 将均被设置为统一的值
nodeCollideStrengthNumber0.40.5设置防止节点之间重叠的力强度,范围 [0, 1]
comboCollideStrengthNumber0.40.5防止 combo 之间重叠的力强度,范围 [0, 1]
nodeSizeArray / Number1010节点大小(直径)。用于碰撞检测。若不指定,则根据传入的节点的 size 属性计算。若即不指定,节点中也没有 size,则默认大小为 10
nodeSpacing

Number / Function示例 1 : 10
示例 2 : 
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
preventNodeOverlappreventOverlaptrue 时生效, 防止重叠时节点边缘间距的最小值。可以是回调函数, 为不同节点设置不同的最小间距, 如示例 2 所示
comboSpacing

Number / Function示例 1 : 10
示例 2 : 
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0preventComboOverlappreventOverlaptrue 时生效, 防止重叠时 combo 边缘间距的最小值。可以是回调函数, 为不同节点设置不同的最小间距, 如示例 2 所示
comboPadding

Number / Function示例 1 : 10
示例 2 : 
d => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0Combo 内部的 padding 值,不用于渲染,仅用于计算力。推荐设置为与视图上 combo 内部 padding 值相同的值
alphaDecayNumber0.030.028迭代阈值的衰减率。范围 [0, 1],0.028 对应迭代数为 300
alphaMinNumber0.030.001停止迭代的阈值
alphaNumber0.11当前阈值
onTickFunction{}每一次迭代的回调函数
onLayoutEndFunction{}布局完成后的回调函数
gravityNumber10重力的大小,影响布局的紧凑程度
comboGravityNumber30每个 combo 内部的重力大小,影响聚类的紧凑程度
optimizeRangeFactorNumber1优化计算性能,两节点间距超过 optimizeRangeFactor * width 则不再计算斥力和重叠斥力。通过合理设置该参数可以较少计算量
depthAttractiveForceScaleNumber0.5根据边两端节点层级差距的调整引力的系数的因子,取值范围 [0, 1]。层级差距越大,引力越小
depthRepulsiveForceScaleNumber2根据边两端节点层级差距的调整斥力系数的因子,取值范围 [1, Infinity]。层级差距越大,斥力越大
velocityDecayNumber0.40.6每个迭代节点运动速度衰减参数
workerEnabledBooleantrue / falsefalse是否启用 web-worker 以防布局计算时间过长阻塞页面交互