经过一段时间的学习,对G6有了初步的了解。下面我将通过一个具体的应用实例,来总结收获。
本次实践意在通过G6构建一个关于“春季流行病”的简单图谱。通过该图谱,用户可以迅速的知晓各类疾病的症状、感染器官、就诊科室等信息。
<div id="mountNode"></div>
//调用G6
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.1.0/build/g6.js"></script>
<script>
//导入数据
const data={
"nodes": [
{"id": "0", "label": "流行性感冒", "class": "disease" },
{"id": "1", "label": "麻疹", "class": "disease" },
/*......*/
],
"edges": [
{"source": "0", "target": "8", "label": "发于", "weight": 1 },
{"source": "0", "target": "13", "label": "产生", "weight": 1 },
/*......*/
]
};
创建一系列节点及边。为了方便后续处理,使节点均分属于不同类(“disease”,“department”…)。通过边的label属性,定义“发于”、“产生”等不同关系。
const graph = new G6.Graph({
container: 'mountNode',
//设置图容器的基本属性
width: 1800,
height: 800,
//对点进行预处理
defaultNode: {
size: 70,
labelCfg: {
style: {
fill: '#fff',
},
},
},
//对边进行预处理
defaultEdge: {
labelCfg: {
autoRotate: true,
},
},
layout: {
......
},
modes: {
......
},
nodeStateStyles: {
......
});
在对边点进行预先处理后,可通过定义布局、交互模式等,使图谱更为生动。
layout: {
type: 'force', //定义布局类型
linkDistance: 300, //指定边距离
preventOverlap: true, //防止节点重合
},
交互模式和工具
modes: {
//允许内置交互机制
//drag-node:拖拽点,drag-canvas:拖拽画布
default: ['drag-canvas', 'zoom-canvas', 'drag-node',
//内置交互工具
//鼠标滑过时,提供详细信息
{type:'tooltip',formatText(model){
return model.label;
},offset: 10},
{type:'edge-tooltip',formatText(model){
return model.label;
},offset: 10},
],
},
nodeStateStyles: {
//当节点被点击后,颜色发生变化,周边加粗
click: {
stroke: '#000',
lineWidth: 3,
},
},
通过设置交互状态,使节点边的状态随着事件改变
交互的实现
交互可以通过事件来“激活”
graph.on('node:click', e => {
const clickNodes = graph.findAllByState('node', 'click');
clickNodes.forEach(cn => {
graph.setItemState(cn, 'click', false);
});
const nodeItem = e.item;
graph.setItemState(nodeItem, 'click', true);
});
当点击节点时,将会“激活”之前设置的交互行为
为了便于区分,可以通过遍历处理使不同类的节点/边呈现不同形式。(本例中,不同类的节点有着不同颜色)
const nodes = data.nodes;
//遍历
nodes.forEach(node => {
if (!node.style) {
node.style = {};
}
node.style.lineWidth = 1;
node.style.stroke = '#666';
//对不同类进行处理
//不同类,不同颜色
switch (node.class) {
case 'disease': {
node.type = 'circle';
node.style.fill = 'steelblue';
break;
}
case 'organ': {
node.type = 'circle';
node.style.fill = 'blue';
break;
}
/*......*/
}
});
graph.data(data);
graph.render();
main();
之后便可浏览器加载
可以看到,在所生成的图中存在节点拥挤的现象。为了方便使用者更好的阅读,我们可以通过分组的方式处理节点。
(本例依据节点的类设置分组)
同一combo中的节点可以同时拖拽;
并且可以将同一combo中节点同时隐藏,便于观看。
(具体实现的gif太大无法上传,可以从
https://antv-g6.gitee.io/zh/docs/manual/middle/combo
查看实例)