2022-05-18 g6 更新自定义节点

0 场景描述

一个自定义节点,利用 draw 绘制了含有多shape(如:rect,text,image) 的group;
双击当前节点可以进行配置,配置之后的image 根据配置项进行调整。
base version: ^4.2.x

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'
        );
    },

你可能感兴趣的:(2022-05-18 g6 更新自定义节点)