Antv-G6 拓扑可视化
首次创建实例使用node()方法能正常修改成功并渲染,
根据页面最新数据changeData时,使用实例方法node()会出现更新不生效。
使用相同的数据,也就是存在相同id的数据,但是坐标、颜色等属性不同,使用changeData会出现更新不生效。
首次渲染数据才能修改成功,之后存在这个节点了,就会出现修改node的某个属性不成功。猜测一波,跟 G6 的更新算法有关。
目前解决思路:使用 data()和render() 或者 read()方法渲染画布(version4.8)。
学习资料 参考 antv g6 文档
一、渲染时机相关
node,edge等实例方法需要在渲染画布之前调用
// 首次创建画布渲染没问题,之后changeData更新时会出现不生效的问题
graph.node(node => {
const nodeId = node.id
if (nodeIds.includes(nodeId)) {
node.comboId = comboIdMap[nodeId]
}
return node
})
// 最终解决
// 手动处理数据,或者封装类、方法优选处理完数据再去交给画布渲染
data.nodes.forEach(node => {
const nodeId = node.id
if (nodeIds.includes(nodeId)) {
node.comboId = comboIdMap[nodeId]
}
})
mockjs假数据,自定义G6节点node组件和边edge组件,下面是需求的demo,代码就不公布了。
二、画布渲染后动态更新
在某些情况,数据庞大功能复杂时,在画布渲染后,通过updateItem或者updateItems 更新或批量更新节点的信息是很有效果的(具体更新哪些树形参考官网或源码)。
三、自定义边和连线
/**
* 处理数据
* 1. 设置(重要,根据需求调整,点参数参考文档:https://g6-v4.antv.vision/manual/middle/elements/nodes/anchorpoint)
* nodeDefault: {
* anchorPoints: [
* [0, 1],
* [0.5, 1],
* ],
* }
*
* 2. 设置2个入点(重要)
* // 该边连入 source 点的第 0 个 anchorPoint
* sourceAnchor: 1,
* // 该边连入 target 点的第 0 个 anchorPoint
* targetAnchor: 1
*
* 3.自定义edge组件(重要)
* 计算贝塞尔曲线的两个控制点
*/
const edgeData = addressResult.systemEdge.map(edge => {
const curArrow = edge.sign
const curStroke = curArrow === 'oneWay' ? SystemAccessRelationTreeRnIG6.CFED350
: curArrow === 'bothWay' ? SystemAccessRelationTreeRnIG6.C00b50
: SystemAccessRelationTreeRnIG6.CE2E2E2
const arrowObj = {
lineWidth: 1
}
if (edge.sign) {
if (curArrow === 'oneWay') {
Object.assign(arrowObj, {
stroke: curStroke,
endArrow: {
path: 'M 0,0 L 5,2.5 L 5,-2.5 Z',
stroke: curStroke,
fill: curStroke
},
startArrow: false
})
} else if (curArrow === 'bothWay') {
Object.assign(arrowObj, {
stroke: curStroke,
endArrow: {
path: 'M 0,0 L 5,2.5 L 5,-2.5 Z',
stroke: curStroke,
fill: curStroke
},
startArrow: {
path: 'M 0,0 L 5,2.5 L 5,-2.5 Z',
stroke: curStroke,
fill: curStroke
}
})
}
}
const newData = {
type: 'edge',
model: edge,
...edge,
type: DIALOG_STATE.CUSTOM_EDGE_CUBIC_HORIZONTAL,
// 该边连入 source 点的第 0 个 anchorPoint
sourceAnchor: 1,
// 该边连入 target 点的第 0 个 anchorPoint
targetAnchor: 1
}
// 根据树形方向设置入点(很重要)
Object.assign(newData, {
sourceAnchor: SystemAccessRelationTreeRnIG6.rightNodeIds.includes(edge.source) ? 1 : 0,
targetAnchor: SystemAccessRelationTreeRnIG6.leftNodeIds.includes(edge.source) ? 1 : 0
})
return newData
})
// 自定义边组件
G6.registerEdge('tree-sql-edge', {
options: {
style: {
cursor: 'pointer',
}
},
// 很重要 计算控制点
getControlPoints: function (cfg) {
const startPoint = cfg.startPoint
const endPoint = cfg.endPoint
const cubicXOffset = 50, cubicRadio = 1 + Math.max(.2, Math.random())
const curOffset = cubicXOffset * cubicRadio
const newPoint = cfg.anchorPoints || [
{
x: startPoint.x + (SystemAccessRelationTreeRnIG6.rightNodeIds.includes(cfg.source) &&!SystemAccessRelationTreeRnIG6.leftNodeIds.includes(cfg.source)? curOffset : -curOffset),
y: startPoint.y
},
{
x: endPoint.x + (SystemAccessRelationTreeRnIG6.rightNodeIds.includes(cfg.target) &&!SystemAccessRelationTreeRnIG6.leftNodeIds.includes(cfg.target)? curOffset : -curOffset),
y: endPoint.y
}
];
return newPoint
}
},'cubic')
四、自定义图形及渐变色
// 当拓扑节点元素需要很炫酷复杂的效果时,就需要使用addShape来定义组合图形,通过zIndex合理控制渲染层级
// 选中节点需要一个高亮效果时,就要用到径向渐变色了,官方文档https://g6-v4.antv.vision/manual/middle/elements/advanced-style/gradient
// 官方示例:使用渐变色描边,渐变角度为 0,渐变的起始点颜色 #ffffff,中点的渐变色为 #7ec2f3,结束的渐变色为 #1890ff
stroke: 'l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
// 经验总结:
// 配合状态切换:https://g6-v4.antv.vision/manual/middle/elements/nodes/custom-node#4-%E8%B0%83%E6%95%B4%E7%8A%B6%E6%80%81%E6%A0%B7%E5%BC%8F
// 径向渐变色示例 渐变色表达式参考下图
'r(0.5, 0.5, 0.7) 0:rgba(173, 225, 251, 0) 0.7:rgba(173, 225, 251, 0) 1:#abe1fc'
// 通过调节 r值来控制颜色的深浅,0-1控制渐变起始位置