AntvG6-graph图谱工具
1 快速上手
1.1 在项目中使用 npm 包引入
Step 1: 使用命令行在项目目录下执行以下命令
npm install --save @antv/g6
Step 2: 在需要用的 G6 的 JS 文件中导入
import G6 from '@antv/g6';
1.2 在 HTML 中使用 CDN 引入
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-{$version}/build/g6.js"></script>
注意
- 在
{$version}
中填写版本号,例如
3.2.0
; - 最新版为 3.2.0,可以在
npm
查看最新版本; - 详情参考 Github 分支:
https://github.com/antvis/g6/tree/master
。
2 快速试用
创建一个 G6 的关系图仅需要下面几个步骤:
- 创建关系图的 HTML 容器;
- 数据准备;
- 创建关系图;
- 配置数据源,渲染。
Step 1: 创建容器
<div id="mountNode"></div>
Step 2: 数据准备
引入 G6 的数据源为 JSON 格式的对象。该对象中需要有节点(nodes)和边(edges)字段,分别用数组表示:
const data = {
// 点集
nodes: [
{
id: 'node1', // String,该节点存在则必须,节点的唯一标识
x: 100, // Number,可选,节点位置的 x 值
y: 200, // Number,可选,节点位置的 y 值
},
{
id: 'node2', // String,该节点存在则必须,节点的唯一标识
x: 300, // Number,可选,节点位置的 x 值
y: 200, // Number,可选,节点位置的 y 值
},
],
// 边集
edges: [
{
source: 'node1', // String,必须,起始点 id
target: 'node2', // String,必须,目标点 id
},
],
};
注意
nodes
数组中包含节点对象,唯一的
id
是每个节点对象中必要的属性,
x
、
y
用于定位;edges
数组中包含边对象,
source
和 target 是每条边的必要属性,分别代表了该边的起始点
id
与 目标点
id
。- 点和边的其他属性参见链接:
图元素配置文档
。
Step 3: 创建关系图
创建关系图(实例化)时,至少需要为图设置容器、宽和高。
const graph = new G6.Graph({
container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
width: 800, // Number,必须,图的宽度
height: 500, // Number,必须,图的高度
});
Step 4: 配置数据源,渲染
创建关系图(实例化)时,至少需要为图设置容器、宽和高。
graph.data(data); // 读取 Step 2 中的数据源到图上
graph.render(); // 渲染图
最终的结果
3 配置
3.1 元素及其配置
图的元素特指图上的节点Node和边Edge,不论是节点还是边,它们的属性分为两种:
- 样式属性
style
:对应 Canvas 中的各种样式,在元素
状态State
发生变化时,可以被改变; - 其他属性
:例如图形(
shape
)、id(
id
)一类在元素
状态State
发生变化时不能被改变的属性。
例如,G6 设定 hover 或 click 节点,造成节点状态的改变,只能自动改变节点的
样式属性
(如
fill
、
stroke
等
)
,
其他属性
(如
shape
等)不能被改变。如果需要改变其他属性,要通过
graph.updateItem
手动配置。
样式属性
是一个名为
style
的对象,
style
字段与其他属性并行。
以节点元素为例,其属性的数据结构如下:
{
id: 'node0', // 元素的 id
shape: 'circle', // 元素的图形
size: 40, // 元素的大小
label: 'node0' // 标签文字
labelCfg: { // 标签配置属性
positions: 'center',// 标签的属性,标签在元素中的位置
style: { // 包裹标签样式属性的字段 style 与标签其他属性在数据结构上并行
fontSize: 12 // 标签的样式属性,文字字体大小
}
}
// ..., // 其他属性
style: { // 包裹样式属性的字段 style 与其他属性在数据结构上并行
fill: '#000', // 样式属性,元素的填充色
stroke: '#888', // 样式属性,元素的描边色
// ... // 其他样式属性
}
}
边元素的属性数据结构与节点元素相似,只是其他属性中多了 source 和 target 字段,代表起始和终止节点的 id
全局配置
适用场景:所有节点统一的属性配置,所有边统一的属性配置。使用方式:使用图的两个配置项:
defaultNode:节点在默认状态下的样式属性(style)和其他属性;
defaultEdge:边在默认状态下的样式属性(style)和其他属性。
defaultNode: {
size: 30, // 节点大小
// ... // 节点的其他配置
// 节点样式配置
style: {
fill: 'steelblue', // 节点填充色
stroke: '#666', // 节点描边色
lineWidth: 1, // 节点描边粗细
},
// 节点上的标签文本配置
labelCfg: {
// 节点上的标签文本样式配置
style: {
fill: '#fff', // 节点标签文字颜色
},
},
},
// 边在默认状态下的样式配置(style)和其他配置
defaultEdge: {
// ... // 边的其他配置
// 边样式配置
style: {
opacity: 0.6, // 边透明度
stroke: 'grey', // 边描边颜色
},
// 边上的标签文本配置
labelCfg: {
autoRotate: true, // 边上的标签文本根据边的方向旋转
},
},
3.2 使用图布局 Layout
当数据中没有节点位置信息,或者数据中的位置信息不满足需求时,需要借助一些布局算法对图进行布局。G6 提供了 7 种一般图的布局和 4 种树图的布局:
一般图:
- Random Layout:随机布局;
- Force Layout:经典力导向布局:
- Circular Layout:环形布局;
- Radial Layout:辐射状布局;
- MDS Layout:高维数据降维算法布局;
- Fruchterman Layout:Fruchterman 布局,一种力导布局;
- Dagre Layout:层次布局。
树图布局:
- Dendrogram Layout:树状布局(叶子节点布局对齐到同一层);
- CompactBox Layout:紧凑树布局;
- Mindmap Layout:脑图布局;
- Intended Layout:缩进布局。
const graph = new G6.Graph({
... // 其他配置项
layout: { // Object,可选,布局的方法及其配置项,默认为 random 布局。
type: 'force', // 指定为力导向布局
preventOverlap: true, // 防止节点重叠
// nodeSize: 30, // 节点大小,用于算法中防止节点重叠时的碰撞检测。由于已经在上一节的元素配置中
linkDistance: 100, // 指定边距离为100设置了每个节点的 size 属性,则不需要在此设置 nodeSize。
center: [500, 300]
}
});
更多属性(
https://g6.antv.vision/zh/docs/api/graphLayout/guide)
3.3 图的交互 Behavior
G6 中的交互行为。G6
内置
了一系列交互行为,用户可以直接使用。简单地理解,就是可以一键开启这些交互行为:
drag-canvas
:拖拽画布;zoom-canvas
:缩放画布。
更多详见:
交互行为 Behavior
const graph = new G6.Graph({
// ... // 其他配置项
modes: {
default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 允许拖拽画布、放缩画布、拖拽节点
},
});
- activate-relations
含义:当鼠标移到某节点时,突出显示该节点以及与其直接关联的节点和连线;
参数:
- trigger: 'mouseenter'。可以是 mousenter,表示鼠标移入时触发;也可以是 click,鼠标点击时触发;
- activeState: 'active'。活跃节点状态。当行为被触发,需要被突出显示的节点和边都会附带此状态,默认值为 active;可以与 graph 实例的 nodeStyle 和 edgeStyle 结合实现丰富的视觉效果。
- inactiveState: 'inactive'。非活跃节点状态。不需要被突出显示的节点和边都会附带此状态。默认值为 * * * inactive。可以与 graph 实例的 nodeStyle 和 edgeStyle 结合实现丰富的视觉效果;
- resetSelected:高亮相连节点时是否重置已经选中的节点,默认为 false,即选中的节点状态不会被 activate-relations 覆盖;
{
type: 'activate-relations',
activeState: 'actives',
inactiveState: 'inactives',
resetSelected: false
},
// 当前节点的多状态样式
nodeStateStyles: {
actives: {
opacity: 1,
lineWidth: 0
},
inactives: {
opacity: 0.2,
lineWidth: 0
}
},
edgeStateStyles: {
actives: {
opacity: 1
},
inactives: {
opacity: 0.2
}
}
(
https://g6.antv.vision/zh/docs/manual/middle/states/defaultBehavior)
3.4 监听和绑定事件
- 全局事件
只要在画布上范围内发生均会被触发,如 mousedown,mouseup,click,mouseenter,mouseleave 等。
graph.on('click', (ev) => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
- canvas 事件
只在 canvas 空白处被触发,如 canvas:mousedown,canvas:click 等,以canvas:eventName 为事件名称。
graph.on('canvas:click', (ev) => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
- 节点/边/combo 上的事件
例如 node:mousedown,edge:click, combo:click 等,以 type:eventName 为事件名称。
graph.on('node:click', (ev) => {
const node = ev.item; // 被点击的节点元素
const shape = ev.target; // 被点击的图形,可根据该信息作出不同响应,以达到局部响应效果
// ... do sth
});
graph.on('edge:click', (ev) => {
const edge = ev.item; // 被点击的边元素
const shape = ev.target; // 被点击的图形,可根据该信息作出不同响应,以达到局部响应效果
// ... do sth
});
graph.on('combo:click', (ev) => {
const combo = ev.item; // 被点击 combo 元素
const shape = ev.target; // 被点击的图形,可根据该信息作出不同响应,以达到局部响应效果
// ... do sth
});
- 图形上的事件
指定图形上的事件,如 circle-shape:mousedown,circle-shape:click 等,以 shapeName:eventName 为事件名称。可用于绑定节点/边/combo 中对局部图形做出响应的场景。效果类似上文 graph.on('node:click', fn) 中通过 target 信息作出不同响应。
关于图形的 name:
内置节点/边/combo 上每个图形的名称在开发过程中可以通过 graph.on('node:click', (ev) => console.log(ev.target.get('name'))) 得知;
自定义节点/边/combo 中通过 addShape 增加的图形,可添加与 attrs 平级的 name 字段指定任意(同元素中唯一)字符串作为 name。请注意同个元素(节点/边/combo)中不同图形尽量给予不同的 name 值。
下面例子为图中所有 name 为 circle-shape 的图形绑定了 click 事件监听:
graph.on('circle-shape:click', (ev) => {
const shape = ev.target; // 被点击的图形
// ... do sth
});
- 时机事件
时机事件指渲染、视口变换、元素增删改、数据变换等时机。所有时机事件详见
G6 的时机事件列表
。如:
beforeadditem
,
afteradditem
等:
- 节点/边/Combo 状态改变时的事件:
beforerefreshitem
与
afterrefreshitem
; - 布局时机:
beforelayout
与
afterlayout
。
下面例子为 graph 绑定了渲染完成时机的监听。时机事件中,afterrender、afterlayout 一类事件必须在
graph.render()
或
graph.read()
之前绑定,方可监听到首次渲染、布局完成后的相关事件。
graph.on('afterrender', (ev) => {
// ... do sth
});
- 自定义事件
G6 允许用户自定义任意事件,可在任意位置通过
graph.emit(customEventName: string, event: IG6GraphEvent)
触发一个事件,第一个参数为自定义事件名称。在触发前,通过
graph.on(customEventName: string, callback: Function)
进行监听。例如:
graph.on('some-custom-event-name', (ev) => {
// ... do sth
});
graph.emit('some-custom-event-name', {
// some params
})
ps:当数据多样化的时候,可以对不同的数据设置不同的节点或者边的样式
data.nodes.forEach((node) => {
node.style = {
fill: node.type === 'company'
? '#EE6666665'
: node.type === 'director'
? '#0F8CFF'
: '#FFC510',
stroke: node.type === 'company'
? '#EE6666665'
: node.type === 'director'
? '#0F8CFF'
: '#FFC510'
}
})
data.edges.forEach((edge) => {
edge.style = {
stroke: edge.typest === 0
? '#EE6666665'
: edge.typest === 1
? '#0F8CFF'
: '#FFC510'
}
edge.label = edge.typest === 0
? '董事'
: edge.typest === 1
? '经理'
: edge.typest === 2
? '职员'
: null
edge.labelCfg = {
style: {
fill: edge.typest === 0
? '#EE6666665'
: edge.typest === 1
? '#0F8CFF'
: '#FFC510'
}
}
})