企业开发中,如何在Vue中实现流程图

企业开发中,如何在Vue中实现流程图

这是我在工作中,vue项目中,实现画出业务流程图,使用方法如以下:

1、安装依赖

这里使用第三方插件:@antv/g6

详见官网@antv/g6

$ npm install --save @antv/g6

2、在使用的组件中导入依赖

import G6 from '@antv/g6';

3、在视图模板中创建流程图容器

<div id="流程图容器的id"></div>

4、在data中,创建保存流程图数据的状态变量

data() {
    return {
      // 保存自定义节点的数据  
      // 一般实际开发中,流程图节点样式都是在自定义的
      nodeExtraAttrs: {
        begin: {
          fill: 'rgba(24, 144, 255, 0.1)',
          stroke: '#1890FF',
        },
        end: {
          fill: 'rgba(242, 65, 48, 0.1)',
          stroke: '#F24130',
        },
        接口返回的nodes字段的key: {
          fill: 'rgba(38, 191, 89, 0.1)',
          stroke: '#26BF59',
        }
      },
      // 这块的数据都是后台接口返回的
      // 节后按照g6插件的配置字段返回数据的
      // 所以这块要和后端沟通好
      data: {
        nodes: [
          {
            id: '节点起始id',
            label: 'name',
            key: 'ACTION',
            text: null,
          },
          {
            id: '节点结束id',
            label: 'name',
            key: 'ORIGINAL',
            text: '带标签的字符串',
          },
        ],
        edges: [
          {
            source: '节点起始id',
            target: '节点结束id',
          },
        ],
      },
    };
  },

5、实现画流程的方法

drawView() {
      // 重写方法
      const _extends =
        Object.assign ||
        function (target) {
          for (let i = 1; i < arguments.length; i++) {
            const source = arguments[i];
            for (const key in source) {
              if (Object.prototype.hasOwnProperty.call(source, key)) {
                target[key] = source[key];
              }
            }
          }
          return target;
        };
      // 自定义节点   内置节点无法满足需求
      // G6.registerNode(typeName: string, nodeDefinition: object, extendedTypeName?: string)
      G6.registerNode(
         // 该新节点类型名称
        'node', 
        // 该新节点类型的定义
        // 当有 extendedTypeName (第三个参数)时,没被复写的函数将会继承 extendedTypeName 的定义
        {
          // cfg  节点身上所有的配置:包括label,size,x,y坐标等 

          // 这个方法,每渲染一个节点,执行一次
          drawShape: (cfg, group) => {
            // ctg上的id key label 都可以决定当前节点的类型
            cfg.size = (cfg.label.length / 10) * 130;
            let widthX = 0;
            if (cfg.label.length / 10 < 1) {
              widthX = 120;
            } else {
              widthX = cfg.size;
            }
            // if(cfg.key==="ORIGINAL")  圆形
            const rect = group.addShape('rect', {
              attrs: _extends(
                {
                  x: -widthX / 2,
                  y: -25,
                  width: widthX,
                  height: 50,
                  radius: 4,
                  fill: '#FFD591',
                  fillOpacity: 1,
                },
                // 相当于:
                // ORIGINAL: {
                //   fill: 'rgba(38, 191, 89, 0.1)',
                //   stroke: '#26BF59',
                // },

                // 属性为fill 和 stroke的对象
                this.nodeExtraAttrs[cfg.key]
              ),
            });
            return rect;
          },
          /**
           * 获取锚点(相关边的连入点)
           * @param  {Object} cfg 节点的配置项
           * @return {Array|null} 锚点(相关边的连入点)的数组,如果为 null,则没有控制点
           */
          // 自定义锚点
          getAnchorPoints: () => {
            return [
              [0, 0.5], // 左侧中间
              [1, 0.5], // 右侧中间
            ];
          },
        },
        // 被继承的节点类型,可以是内置节点类型名,也可以是其他自定义节点的类型名。
        // extendedTypeName 未指定时代表不继承其他类型的节点;
        // 例如基类 'single-node',或 'circle', 'rect' 等
        'single-shape'
      );
      /**
       * 自定义带箭头的贝塞尔曲线 edge
       */
      G6.registerEdge('line-with-arrow', {
        itemType: 'edge',
        draw: (cfg, group) => {
          const startPoint = cfg.startPoint;
          const endPoint = cfg.endPoint;
          const centerPoint = {
            x: (startPoint.x + endPoint.x) / 2,
            y: (startPoint.y + endPoint.y) / 2,
          };
          // 控制点坐标
          const controlPoint = {
            x: (startPoint.x + centerPoint.x) / 2,
            y: startPoint.y,
          };
          // 为了更好的展示效果, 对称贝塞尔曲线需要连到箭头根部
          const path = group.addShape('path', {
            attrs: {
              path: [
                ['M', startPoint.x, startPoint.y],
                ['Q', controlPoint.x, controlPoint.y, centerPoint.x, centerPoint.y],
                ['T', endPoint.x, endPoint.y],
                ['L', endPoint.x, endPoint.y],
              ],
              stroke: '#ccc',
              lineWidth: 1.6,
              endArrow: {
                path: 'M 4,0 L -4,-4 L -4,4 Z',
                d: 4,
              },
            },
          });
          return path;
        },
      });
      const graph = new G6.Graph({
        // 常用配置项 
        // 类型:Boolean;默认:'false'。图是否自适应画布。
        fitView: true,
        // 类型:Number | Array;默认:0。图自适应画布时的四周留白像素值。fitView 为 true 时生效。
        // fitViewPadding : 0
        // 类型:Boolean;默认:'false'。是否平移图使其中心对齐到画布中心。v3.5.1 后支持。
        fitCenter: true,
        // bloodView:流程图容器id
        container: '流程图容器的id',
        //modes 交互行为相关
        // 配置多种交互模式及其包含的交互事件的。
        modes: {
          default: [
            'drag-canvas',
            'zoom-canvas',
            {
              type: 'tooltip',
              formatText(model) {
                const cfg = model.text;
                const text = model.text;
                // cfg.forEach((row) => {
                //   text.push(row.label + ':' + row.value + '<br>');
                // });
                return text;
              },
              offset: 30,
            },
          ],
        },
        // 若数据中不存在节点位置,则默认为随机布局。配置布局类型及其参数。
        layout: {
          // 类型  总共三种:径向:radial   有向分层:dagre     力导:force
          type: 'dagre',
          // 'LR':从左至右布局;
          rankdir: 'LR', // 可选可选值:'TB' | 'BT' | 'LR' | 'RL',默认为图的中心 TB
        },
        // defaultNode类型:Object。默认情况下全局节点的配置项,包括样式属性和其他属性
        // G6 的内置节点包括 
        // circle圆形,rect长方形,ellipse椭圆,diamond菱形,triangle三角形,
        // star五角星,image图片,modelRect卡片,donut圆形(v4.2.5 起支持)。
        defaultNode: {
          type: 'node',  // 这里的type指向自定义节点
          // size:300,
          labelCfg: {
            style: {
              fill: '#595959',
              fontSize: 14,
            },
          },
        },
        // defaultEdge  类型:Object。默认情况下全局边的配置项,包括样式属性和其他属性
        defaultEdge: {
          type: 'line-with-arrow',
          style: {
            endArrow: true,
            lineWidth: 2,
            stroke: '#ccc',
          },
        },
      });
      graph.data(this.data);
      // 渲染
      graph.render();
    },

6、 在获取到数据接口后调用画流程图的方法

this.$nextTick(() => {
 this.drawView();
});

注意: 因为调用接口是异步,不能保证获取到画布的容器元素,所以需要把调用drawView方法放在$nextTick里面

7、实际开发中不同的需求实现

7.1 节点边edge添加图形,且图形上附带文字,如图所示

在这里插入图片描述
代码实现如下

const graph = new G6.Graph({
  container: 'container',
  defaultEdge: {
    labelCfg: {  // 设置边上的文字
      autoRotate: true,
      style: {
        fill: '#1890ff', // 文字颜色
        fontSize: 14, // 文字大小
        background: {
          fill: '#ffffff',  // 背景填充颜色
          stroke: '#9EC9FF',  // 边
          padding: [2, 2, 2, 2], // 矩形
          radius: 2,  // 圆角
        },
      },
    },
  },
});

不同边上的矩形样式,可以在流程图数据edges数组上区别,如下

this.data.edges.forEach((item, index) => {
  if (item.upstreamKey === 'WORK') {
    item.labelCfg = {
      autoRotate: true,
      style: {
        fill: '#262626', //  文字颜色
        fontSize: 10,
        cursor: 'pointer',
        background: {
          fill: 'rgba(38, 191, 89, 0.1)',
          stroke: '#26BF59',
          padding: [4.5, 16.5, 4.5, 16.5],
          radius: 2,
        },
      },
    };
  } else if (item.upstreamKey === 'ORIGINAL') {
    item.labelCfg = {
      autoRotate: true,
      style: {
        fill: '#262626', //  文字颜色
        fontSize: 10,
        cursor: 'pointer',
        background: {
          fill: 'rgba(255, 167, 64, 0.1)',
          stroke: '#FFA740',
          padding: [4.5, 16.5, 4.5, 16.5],
          radius: 2,
        },
      },
    };
  } else if (item.upstreamKey === 'FINAL') {
    item.labelCfg = {
      autoRotate: true,
      style: {
        fill: '#262626', //  文字颜色
        fontSize: 10,
        cursor: 'pointer',
        background: {
          fill: 'rgba(24, 144, 255, 0.1)',
          stroke: '#1890FF',
          padding: [4.5, 16.5, 4.5, 16.5],
          radius: 2,
        },
      },
    };
  }
});
  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Vue使用mxGraph开发流程图工具的步骤如下: 1. 安装mxGraph库:在Vue项目使用npm或yarn安装mxGraph库,可以通过命令行运行`npm install mxgraph`或`yarn add mxgraph`来安装。 2. 创建Flowchart组件:在Vue项目创建一个Flowchart组件,用于展示和操作流程图。可以使用Vue的单文件组件(.vue)来创建组件。 3. 导入mxGraph库:在Flowchart组件导入mxGraph库,可以使用`import mxgraph from 'mxgraph'`语句来导入。 4. 创建画布:在Flowchart组件的`mounted`生命周期函数,使用mxGraph库创建一个画布。可以使用`var container = this.$refs.flowchart`获取组件的DOM元素,并通过`new mxgraph.mxGraph(container)`来创建画布。 5. 定义节点和边:使用mxGraph库的API来定义流程图的节点和边。可以使用`mxgraph. mxCell`创建一个节点,并使用`mxgraph.mxGeometry`来定义节点的位置和大小。可以使用`graph.addCell`将节点添加到画布。 6. 设置交互操作:使用mxGraph库的API来设置流程图的交互操作,比如节点的拖拽、连接等。可以使用`graph.setConnectable(true)`设置节点可连接,使用`graph.setCellsDisconnectable(false)`设置节点不可断开连接等。 7. 监听事件:使用mxGraph库的API来监听流程图的事件,比如节点的点击、连线的添加等。可以使用`graph.addListener`来添加事件监听器,并在回调函数处理相应的逻辑。 8. 渲染流程图:在Flowchart组件使用mxGraph库的API将流程图渲染到画布上。可以使用`graph.getModel()`获取绘图模型,并使用`graph.view.render()`来渲染流程图。 通过以上步骤,我们就可以在Vue使用mxGraph库来开发流程图工具。可以根据项目需求对mxGraph库进行进一步的封装和拓展,以实现更复杂的流程图功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原谅我很悲

不要打赏哦,加个好友一起学习呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值