可视化—AntV G6 高亮相邻节点的两种方式
目录
- 内置的高亮节点
- 自定义高亮
- 自定义高亮时保持原始颜色
- 总结
- 案例完整代码
通过官方文档,可知高亮相邻节点分为两种方法,文档描述并不是很清楚,对刚接触这个库的小白并不是很友好,慢慢总结慢慢来吧
内置的高亮节点
是通过内置的Behavior activate-relations
来实现,Behavior 是 G6 提供的定义图上交互事件的机制。与交互模式 Mode
配合使用
activate-relations:当鼠标移到某节点时,突出显示该节点以及与其直接关联的节点和连线;
- 参数:
trigger: 'mouseenter'
。表示出发机制,可以是mouseenter
、click
;activeState: 'active'
。活跃节点状态,默认为active
,可以与 graph 实例的xxxStateStyles
结合实现丰富的视觉效果。inactiveState: 'inactive'
。非活跃节点状态,默认值为inactive
。同样可以与 graph 实例的xxxStateStyles
结合实现丰富的视觉效果。- 文档上还提到了另外两个参数,但是本案例中并未使用,暂不做说明 resetSelected、shouldUpdate(e)
- 具体用法
let drawGraph = document.getElementById("drawGraph");
this.graphWidth = drawGraph.scrollWidth;
this.graphHeight = drawGraph.scrollHeight || 1200;
graphG = new this.G6.Graph({
container: "drawGraph",
width: this.graphWidth,
height: this.graphHeight,
modes: {
default: [
{ type: "activate-relations", activeState: 'active', inactiveState: 'inactive' },
],
// default: ['activate-relations'] // 由于活跃节点及非活跃节点状态均采用默认值,因此可以简写为这种形式
},
nodeStateStyles:{}, // 配置节点状态样式
edgeStateStyles:{}, // 配置边状态样式
comboStateStyles:{}, // 配置分组状态样式
}
graphG.data(data);
graphG.render();
如果仅采用内置的高亮节点,会采用默认的样式,最终的渲染效果为:
自定义高亮
这种方式是通过自定义状态
,在通过实例提供的setItemState
、 clearItemStates
设置和清除目标的状态信息,同样需要与graph 实例的 xxxStateStyles
结合实现。
graphG = new this.G6.Graph({
container: "drawGraph",
width: this.graphWidth,
height: this.graphHeight,
nodeStateStyles:{ // 配置节点状态样式,此处就先写一个,后续会有完整的案例分享
highlight: {
fill: "#db4437",
shadowColor: '#fff',
stroke: "#db4437",
cursor: "pointer",
'text-shape': {
lineWidth: 1,
fill: "#db4437",
stroke: "#db4437",
},
},
},
edgeStateStyles:{}, // 配置边状态样式
comboStateStyles:{}, // 配置分组状态样式
}
graphG.data(data);
graphG.render();
graphG.on("combo:mouseenter", (e) => {
let edgeItem = e.item
graphG.setItemState(edgeItem, 'highlight', true)
edgeItem.getEdges().forEach(edge => {
graphG.setItemState(edge.getTarget(), 'highlight', true)
graphG.setItemState(edge.getSource(), 'highlight', true)
graphG.setItemState(edge, 'highlight', true)
})
graphG.paint()
graphG.setAutoPaint(true)
});
graphG.on('combo:mouseleave', (e) => {
graphG.setAutoPaint(false)
graphG.getNodes().forEach(node => {
graphG.clearItemStates(node)
})
graphG.getEdges().forEach(edge => {
graphG.clearItemStates(edge)
})
graphG.getCombos().forEach(combo => {
graphG.clearItemStates(combo)
})
graphG.paint()
graphG.setAutoPaint(true)
})
如果仅采用自定义高亮节点,最终的渲染效果为:
自定义高亮时保持原始颜色
通过上面的案例,可以看出,combo:mouseenter
时相关联的边和点全部高亮,并且统一了连线的颜色,此时可能会与我们的需求相违背,可能连线还是想要保持原来的颜色,因为不同的颜色描述两点之间的不同类型的指向关系。那么此时在处理鼠标事件时,需要获取要节点和连线 原始样式。
graphG.on("combo:mouseenter", (e) => {
let comboItem = e.item;
const originStyle = comboItem._cfg.originStyle["circle-combo"].fill;
comboItem._cfg.styles.highlight.fill = originStyle;
graphG.setItemState(comboItem, "highlight", true);
comboItem.getEdges().forEach((edge) => {
const originStyle = edge._cfg.originStyle["edge-shape"].stroke; // 获取边edge 原始颜色
edge._cfg.styles.highlight.stroke = originStyle;
let edgeSource = edge.getSource();
let edgeTarget = edge.getTarget();
if ( edgeSource._cfg.type === "combo" && edgeSource._cfg.model.id =="100-600" ) {
const originStyle = edgeSource._cfg.originStyle["circle-combo"].fill; // 获取分组combo 原始颜色
edgeSource._cfg.styles.highlight.fill = originStyle;
}
if ( edgeTarget._cfg.type === "combo" && edgeTarget._cfg.model.id =="100-600" ) {
const originStyle = edgeTarget._cfg.originStyle["circle-combo"].fill;
edgeTarget._cfg.styles.highlight.fill = originStyle;
}
graphG.setItemState(edgeSource, "highlight", true);
graphG.setItemState(edgeTarget, "highlight", true);
graphG.setItemState(edge, "highlight", true);
});
});
那么此时最终的效果为:
总结
其实两种方法与异曲同工之妙,都是进行状态的处理,只不过一个是帮我们处理了一部分状态与样式,可以直接拿来用,但往往内置的样式与我们实际使用时不相符,因此可以使用两者结合的方式,最终效果及完整demo,采用随机数来模拟实体与关系。
案例完整代码