0 场景描述
一个自定义节点,利用 draw 绘制了含有多shape(如:rect,text,image) 的group;
双击当前节点可以进行配置,配置之后的image 根据配置项进行调整。
1、更新节点数据
这一步相对简单,g6 本身提供了多个方法更新
// 1 updateItem
const model = {
id: 'node',
label: 'node',
address: 'cq',
x: 200,
y: 150,
style: {
fill: 'blue',
},
};
// 通过ID查询节点实例
const item = graph.findById('node');
graph.updateItem(item, model);
// 2 refreshItem
// 通过ID查询节点实例
const item = graph.findById('node');
// .... 修改内容
graph.refreshItem(item);
// 3 update
const item = graph.findById('node');
let model = item.getModel();
// ... 修改内容
item.update(model);
2、更新节点shape
// 按照官网( https://g6.antv.vision/zh/docs/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) 说法,
// 有了以下两种方式,这两种方法都需要定义在自定义节点上;
// 1 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
// xx
}
},
// 2 setState -- 官网推荐 -- 官网示例
// 在 G6 中自定义节点/边时在 setState 方法中进行节点状态变化的响应;
// 通过 graph.setItemState() 方法来设置状态。
// 基于 rect 扩展出新的图形
G6.registerNode(
'custom',
{
// 响应状态变化
setState(name, value, item) {
const group = item.getContainer();
const shape = group.get('children')[0]; // 顺序根据 draw 时确定
if (name === 'selected') {
if (value) {
shape.attr('fill', 'red');
} else {
shape.attr('fill', 'white');
}
}
},
},
'rect',
);
// 点击时选中,再点击时取消
graph.on('node:click', (ev) => {
const node = ev.item;
graph.setItemState(node, 'selected', !node.hasState('selected')); // 切换选中
});
3、具体完整样例
// 外部调用
// obj 含有唯一键
updateNode(obj) {
if (!this.graph) return;
const id = obj.id;
const graph = this.graph;
const el = graph.findById(id);
let model = el.getModel();
// 只能修改表间关联关系
model.joinInfo = obj.joinInfo;
model.tableRelationType = obj.tableRelationType;
// imgPath 用于拼装完整路径
model.svgUrl = imgPath(obj.tableRelationType);
el.update(model);
el.setState('setSvgUrl', model.svgUrl);
},
// ....
// 内部实现
G6.registerNode(
'custom',
{
draw(cfg, group) {
let keyShape: IShape;
// ...
if ((cfg as any).svgUrl) {
keyShape = group.addShape('image', {
attrs: {
x: 0,
y: 12,
width: 36,
height: 36,
img: (cfg as any).svgUrl,
},
name: 'relationType',
draggable: true
});
}
// ...
return keyShape;
},
// 响应状态变化
setState(name, value, item) {
const keyShape = item.get('keyShape');
const group = item.getContainer();
// const model = item.getModel();
if (!keyShape) {
return;
}
// relationType
const relationTypeShape = group.get('children').find(item => item.cfg.name === 'relationType');
// 设置svgUrl
if (name === 'setSvgUrl') {
relationTypeShape.attr({
img: value
});
}
}
},
'single-node'
);
},
网友评论