Vue3 + Vite + G6 流程图自定义节点,自定义边实践总结

8,404 阅读4分钟

G6****流程图自定义配置相关内容

因产品原因,所提供的内置节点无法满足需求,故使用 DOM 自定义节点

这篇文章主要记录,实际使用过程中用到的相关信息及代码。

npm install --save @antv/g6

流程图初始化

template 

<template>
  <div id="workflow"></div></template>

script

const graph = new G6.Graph({  // 图的 DOM 容器,可以传入该 DOM 的 id 或者直接传入容器的 HTML 节点对象  container: "workflow",  // 指定画布宽度,单位为 'px'  width: 500,  // 指定画布高度,单位为 'px'  height: 500,  renderer: "svg",  layout: {    // 层次布局配置    type: "dagre",    // 布局的方向    rankdir: "TB",  },  defaultNode: {    // 此处为自定义节点的 name    type: "dom-node",    size: [310, 158],    color: "#5B8FF9",    style: { fill: "#9EC9FF", lineWidth: 3 },  },  defaultEdge: {    // 此处为自定义边的 name    type: "flow-line",    style: { stroke: "#c2c5cc" },  },  // 指定边是否连入节点的中心  linkCenter: true,  // 开启后,图将会被平移,图的中心将对齐到画布中心,但不缩放。  fitCenter: true,});

自定义节点 (G6.registerNode)

官方 api 示例代码

G6.registerNode(
  'nodeName',
  {
    options: {
      style: {},
      stateStyles: {
        hover: {},
        selected: {},
      },
    },
    /**
     * 绘制节点,包含文本
     * @param  {Object} cfg 节点的配置项
     * @param  {G.Group} group 图形分组,节点中图形对象的容器
     * @return {G.Shape} 返回一个绘制的图形作为 keyShape,通过 node.get('keyShape') 可以获取。
     * 关于 keyShape 可参考文档 核心概念-节点/边/Combo-图形 Shape 与 keyShape
     */
    draw(cfg, group) {},
    /**
     * 绘制后的附加操作,默认没有任何操作
     * @param  {Object} cfg 节点的配置项
     * @param  {G.Group} group 图形分组,节点中图形对象的容器
     */
    afterDraw(cfg, group) {},
    /**
     * 更新节点,包含文本
     * @override
     * @param  {Object} cfg 节点的配置项
     * @param  {Node} node 节点
     */
    update(cfg, node) {},
    /**
     * 更新节点后的操作,一般同 afterDraw 配合使用
     * @override
     * @param  {Object} cfg 节点的配置项
     * @param  {Node} node 节点
     */
    afterUpdate(cfg, node) {},
    /**
     * 响应节点的状态变化。
     * 在需要使用动画来响应状态变化时需要被复写,其他样式的响应参见下文提及的 [配置状态样式] 文档
     * @param  {String} name 状态名称
     * @param  {Object} value 状态值
     * @param  {Node} node 节点
     */
    setState(name, value, node) {},
    /**
     * 获取锚点(相关边的连入点)
     * @param  {Object} cfg 节点的配置项
     * @return {Array|null} 锚点(相关边的连入点)的数组,如果为 null,则没有控制点
     */
    getAnchorPoints(cfg) {},
  },
  // 继承内置节点类型的名字,例如基类 'single-node',或 'circle', 'rect' 等
  // 当不指定该参数则代表不继承任何内置节点类型
  extendedNodeName,
);

自定义 节点 示例代码

G6.registerNode(
  'dom-node',  // 此处名称需填入 初始化配置 defaultNode对象下type中
  {
    draw: (cfg: ModelConfig, group: Group) => {
      return group.addShape('dom', {
        attrs: {
          width: cfg.size[0],
          height: cfg.size[1],
          // 传入 DOM 的 html,带有原生 onclick 事件
          html: `
        <div onclick="alert('Hi')">
          <div style="height: 100%; width: 33%; background-color: #CDDDFD">
            <img alt="img" style="line-height: 100%; padding-top: 6px; padding-left: 8px;" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Q_FQT6nwEC8AAAAAAAAAAABkARQnAQ" width="20" height="20" />  
          </div>
          .....
          <span style="margin:auto; padding:auto; color: #5B8FF9">${cfg.label}</span>
        </div>
          `,
        },
        draggable: true, // 表示允许该图形响应鼠标的拖拽事件
      });
    },
  },
);

 注意事项

自定义边 (G6.registerEdge)

官方 api 示例代码

G6.registerEdge(
  'edgeName',
  {
    /**
     * 绘制边,包含文本
     * @param  {Object} cfg 边的配置项
     * @param  {G.Group} group 图形分组,边中的图形对象的容器
     * @return {G.Shape} 绘制的图形,通过 node.get('keyShape') 可以获取到
     */
    draw(cfg, group) {},
    /**
     * 绘制后的附加操作,默认没有任何操作
     * @param  {Object} cfg 边的配置项
     * @param  {G.Group} group 图形分组,边中的图形对象的容器
     */
    afterDraw(cfg, group) {},
    /**
     * 更新边,包含文本
     * @override
     * @param  {Object} cfg 边的配置项
     * @param  {Edge} edge 边
     */
    update(cfg, edge) {},
    /**
     * 更新边后的操作,一般同 afterDraw 配合使用
     * @override
     * @param  {Object} cfg 边的配置项
     * @param  {Edge} edge 边
     */
    afterUpdate(cfg, edge) {},
    /**
     * 设置边的状态,主要是交互状态,业务状态请在 draw 方法中实现
     * 单图形的边仅考虑 selected、active 状态,有其他状态需求的用户自己复写这个方法
     * @param  {String} name 状态名称
     * @param  {Object} value 状态值
     * @param  {Edge} edge 边
     */
    setState(name, value, edge) {},
  },
  'extendedEdgeName',
);

自定义 边(添加额外图形)示例代码 

G6.registerEdge("flow-line", {  // 绘制边  draw(cfg, group) {    const startPoint = cfg.startPoint;    const endPoint = cfg.endPoint;    const { style } = cfg;    const shape = group.addShape("path", {      attrs: {        stroke: style.stroke,        endArrow: style.endArrow,        path: [          ["M", startPoint.x, startPoint.y],          ["L", startPoint.x, (startPoint.y + endPoint.y) / 2],          ["L", endPoint.x, (startPoint.y + endPoint.y) / 2],          ["L", endPoint.x, endPoint.y],        ],      },    });    return shape;  },  // 额外图形部分代码  afterDraw(cfg, group) {    // 获取图形组中的第一个图形,在这里就是边的路径图形    const shape = group.get("children")[0];    const { targetNode } = cfg;    // 获取路径图形的中点坐标    const midPoint = shape.getPoint(0.5);    const { node_type } = targetNode.getModel();    if (midPoint && node_type !== "trigger") {      group.addShape("image", {        attrs: {          x: midPoint.x - 15,          y: midPoint.y - 15,          width: 30,          height: 30,          cursor: "pointer",          img: add_icon,        },        // must be assigned in G6 3.3 and later versions. it can be any value you want        name: "add-item",      });    }  },});

部署打包遇到的问题

开发环境正常,正式环境下流程图显示失败报错,可在官方文档,教程->FAQ->Vite+G6 报错看到问题解决方案,链接如下:

g6.antv.vision/zh/docs/man…

相关依赖版本

"@antv/g6": "^4.3.7", "vue": "3.2.1",

完结 撒花  ✿✿ヽ(°▽°)ノ✿