Antv G6动态更新自定义节点数据
背景
由于公司项目需求,最近研究了一下使用蚂蚁的antv G6来构建拓扑图。
成果实例
由于很多个性需求,所以图中的各种edge和node都是使用G6.registerNode和G6.registerEdge两个方法来自定义的。下面贴一下我自定义节点和边的代码片段。
-
G6.registerNode(item.iconName, {
-
draw(cfg, group) {
-
if (item.iconName === 'warning1') {
-
// 警报灯使用字体图标(制作闪烁动画)
-
// 定义字体图标
-
const keyShape = group.addShape('text', {
-
attrs: {
-
x: 0,
-
y: 0,
-
fontFamily: 'iconfont', // 对应css里面的font-family: "iconfont";
-
textAlign: 'center',
-
textBaseline: 'middle',
-
text: '\ue60e', // 具体图标
-
fontSize: item.size,
-
fill: '#eaa153'
-
},
-
// must be assigned in G6 3.3 and later versions. it can be any value you want
-
name: item.type
-
})
-
// 添加闪烁动画
-
keyShape.animate(
-
(ratio) => {
-
const color = ratio > 0.5 ? '#eaa153' : '#f83f3f'
-
return {
-
fill: color
-
}
-
},
-
{
-
repeat: true, // 动画重复
-
duration: 1000,
-
easing: 'easeLinear'
-
}
-
)
-
-
// 强制刷新图标(默认情况刷新页面,图标会变成小方框)
-
setTimeout(() => {
-
keyShape.attr({})
-
}, 0)
-
-
return keyShape
-
} else if (item.type === 9) {
-
// 文本框
-
const keyShape = group.addShape('text', {
-
attrs: {
-
x: 0,
-
y: 0,
-
text: '文本框节点',
-
fontSize: item.size,
-
fill: '#FFF'
-
},
-
name: 'text-box'
-
})
-
return keyShape
-
} else {
-
// 普通图片节点
-
const keyShape = group.addShape('image', {
-
attrs: {
-
x: -(item.width / 2),
-
y: -(item.height / 2),
-
height: item.height,
-
width: item.width,
-
img: require(`@/assets/process_diagram_images/${item.iconName}.svg`)
-
},
-
// must be assigned in G6 3.3 and later versions. it can be any value you want
-
name: item.type
-
})
-
// 给风扇添加转动动画
-
if (item.type === 3) {
-
keyShape.animate(
-
(ratio) => {
-
const toMatrix = G6.Util.transform(
-
[1, 0, 0, 0, 1, 0, 0, 0, 1],
-
[['r', ratio * Math.PI * 4]]
-
)
-
return {
-
matrix: toMatrix
-
}
-
},
-
{
-
repeat: true, // 动画重复
-
duration: 3000,
-
easing: 'easeLinear'
-
}
-
)
-
}
-
return keyShape
-
}
-
},
-
// 自定义选中状态
-
setState(name, value, item) {
-
const group = item.getContainer()
-
const shape = group.get('children')[0]
-
if (name === 'selected') {
-
if (value) {
-
shape.attr('shadowBlur', 6)
-
shape.attr('shadowColor', '#00a5fc')
-
} else {
-
shape.attr('shadowBlur', 0)
-
shape.attr('shadowColor', 'transparent')
-
}
-
}
-
}
-
}
-
)
-
G6.registerEdge(
-
'pipeLine',
-
{
-
afterDraw(cfg, group) {
-
const shape = group.get('children')[0]
-
shape.attr('stroke', 'rgba(255,255,255,0.4)')
-
// 添加管线白底
-
const startPoint = shape.getPoint(0)
-
const endPoint = shape.getPoint(1)
-
group.addShape('path', {
-
attrs: {
-
path: [
-
['M', startPoint.x, startPoint.y],
-
['L', endPoint.x, endPoint.y]
-
],
-
stroke: 'rgb(229,229,229)',
-
lineWidth: 8
-
},
-
// must be assigned in G6 3.3 and later versions. it can be any value you want
-
name: 'line-bg'
-
})
-
// 添加流动动画
-
const flowPath = group.addShape('path', {
-
attrs: {
-
path: [
-
['M', startPoint.x, startPoint.y],
-
['L', endPoint.x, endPoint.y]
-
],
-
stroke: item.color,
-
lineWidth: 6
-
},
-
// must be assigned in G6 3.3 and later versions. it can be any value you want
-
name: 'line-flow'
-
})
-
// 定义流向动画
-
const lineDash = [10, 10, 10, 10]
-
let index = 0
-
flowPath.animate(
-
() => {
-
index = 0.3
-
if (index > 40) {
-
index = 0
-
}
-
const res = {
-
lineDash,
-
lineDashOffset: -index
-
}
-
// returns the modified configurations here, lineDash and lineDashOffset here
-
return res
-
},
-
{
-
repeat: true, // whether executes the animation repeatly
-
duration: 3000 // the duration for executing once
-
})
-
},
-
update: undefined
-
},
-
'line' // extend the built-in edge 'cubic'
-
)
问题
根据需求,需要动态更新节点(node)和边(edge)的样式,比如需要动态修改一个文本节点的文本内容或者动态修改edge的颜色。在修改edge颜色的时候我使用的方法是通过graph.findById方法先查找到对应的节点,在通过点属性直接修改对应的属性值(最后不要忘了使用refreshItem函数重新渲染该元素)
-
const el = this.graph.findById('edgeId')
-
// 修改管道颜色(背景)
-
el._cfg.model.style.stroke = 'rgba(99,99,99,0.77)'
-
// 重新渲染
-
this.graph.refreshItem(el)
但是,我想通过同样的方式修改文本框内容时候,却怎么也不生效
-
const el = this.graph.findById('nodeId')
-
// 修改文本内容
-
el._cfg.keyshape.attrs.text = '我是变化后的文本'
-
// 重新渲染
-
this.graph.refreshItem(el)
最后通过反复阅读官方关于自定义节点部分的文档,终于发现了问题所在
换句话说,我在自定义edge时,使用的是afterDraw方法,并且继承了内置元素line的属性,所以在更新时他会执行line这个内置元素的update方法(具体实现请自行查阅)去修改我们edge数据,但是在我在自定义节点时使用的时使用的是draw方法,并且没有继承内置元素,所以在更新时,会重新执行draw这个方法,执行同样的方法,节点数据当然不会发生改变了。
解决方法
在自定义节点时,需要自己去定义update这个方法,我的代码如下
-
update(cfg, node) {
-
// 若未指定registerNode的第三个参数并且未定义update方法时,则节点更新时会执行 draw 方法,所有图形清除重绘
-
if (item.type === 9 && cfg.attrs) {
-
// 定义更新文本节点的方法
-
node.get('keyShape').attrs.text = cfg.attrs.text
-
node.get('keyShape').attrs.fill = cfg.attrs.fill
-
node.get('keyShape').attrs.font = `normal normal normal ${cfg.attrs.fontSize}px sans-serif`
-
node.get('keyShape').attrs.fontSize = cfg.attrs.fontSize
-
}
-
},
最后在动态更新时,只需要使用graph.updateItem修改节点的数据即可
-
// 动态刷新文本框的节点的内容
-
refreshTextBox(params) {
-
const { id, text, fontSize, fill, variation } = params
-
const node = this.graph.findById(id)
-
// fontSize参数必须为数字
-
this.graph.updateItem(node, {
-
attrs: {
-
text: text || '文本内容出错',
-
fontSize: fontSize || 14,
-
fill: fill || '#FFF',
-
variation: variation || 'test'
-
}
-
})
-
}
核心
解决方案的核心就是在自定义节点时使用update这个方法,另外大家在使用第三方插件时,遇到问题一定要去多阅读文档,答案或许就在文档中。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgaejcf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24