ant G6+Vue画简单流程图

7,896 阅读2分钟

背景

要用JS写出一个流程图 如图所示

根据现有开源项目 选择了ANT G6

添加功能

于是借鉴了项目vue-g6-editor

GitHub链接为:github.com/caoyu48/vue…

线上访问地址为:http://62.234.69.136/

g6官方API文档:antv-g6.gitee.io/zh/docs/man…

设置上下左右四个方向设置输入输出点

位置:src/components/itemPanel/item.vue文件中的data.list

{
          name: "双输入双输出节点",
          label: "双输入双输出节点",
          size: "170*34",
          type: "node",
          x: 0,
          y: 0,
          shape: "customNode",
          color: "#1890ff",
          inPoints: [[0.5, 0], [0, 0.5]],
          outPoints: [[1, 0.5], [0.5,1]]
        },

位置:src/components/Flow/customNode.js中

if (cfg.inPoints) {
          for (let i = 0; i < cfg.inPoints.length; i++) {
            let x,
              y = 0;
            if (cfg.inPoints[i][0] === 0) {
              y = 0;
              x = width * cfg.inPoints[i][1];
            } else if((cfg.inPoints[i][0] === 1)) {
              y = height;
              x = width * cfg.inPoints[i][1];
            } else if((cfg.inPoints[i][1] === 0)){
              x = 0,
              y = height * cfg.inPoints[i][0];
            } else if((cfg.inPoints[i][1] === 1)){
              x = height,
              y = height * cfg.inPoints[i][0];
            }
            x = width * cfg.inPoints[i][1];
            const id = 'circle' + uniqueId()
            group.addShape("circle", {
              attrs: {
                id: 'circle' + uniqueId(),
                parent: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 10,
                isInPointOut: true,
                fill: "#1890ff",
                opacity: 0
              }
            });
            group.addShape("circle", {
              attrs: {
                id: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 3,
                isInPoint: true,
                fill: "#fff",
                stroke: "#1890ff",
                opacity: 0
              }
            });
          }
        }
        if (cfg.outPoints) {
          for (let i = 0; i < cfg.outPoints.length; i++) {
            let x,y
            //0为顶 1为底
            if (cfg.outPoints[i][0] === 0) {
              y = 0;
              x = width * cfg.outPoints[i][1];
            } else if((cfg.outPoints[i][0] === 1)) {
              y = height;
              x = width * cfg.outPoints[i][1];
            } else if((cfg.outPoints[i][1] === 0)){
              x = 0,
              y = height * cfg.outPoints[i][0];
            } else if((cfg.outPoints[i][1] === 1)){
              x = height,
              y = height * cfg.outPoints[i][0];
            }
            x = width * cfg.outPoints[i][1];
            const id = 'circle' + uniqueId()
            group.addShape("circle", {
              attrs: {
                id: 'circle' + uniqueId(),
                parent: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 10,
                isOutPointOut: true,
                fill: "#1890ff",
                opacity: 0//默認0 需要時改成0.3
              }
            });
            group.addShape("circle", {
              attrs: {
                id: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 3,
                isOutPoint: true,
                fill: "#fff",
                stroke: "#1890ff",
                opacity: 0
              }
            });
          }
        }

给连线加上文字

位置 src/components/DetailPanel/index.vue

<div v-if="status === 'edge-selected'" id="edge_detailpannel" class="pannel">
    <div class="pannel-title">连线</div>
    <div class="block-container">
      <el-col :span="8">内容</el-col>
      <el-col :span="16">
        <el-input v-model="edge.label" @change="handleChange" />
      </el-col>
      <el-col :span="8">文字颜色</el-col>
      <el-col :span="16">
        <el-color-picker v-model="textColor" @change="handleChangeColor" />
      </el-col>
    </div>
</div>

data() {
    return {
      status: "canvas-selected",
      showGrid: false,
      page: {},
      graph: {},
      item: {},
      node: {},
&emsp;&emsp;&emsp; //【我添加的】
      edge:{},
      grid: null,
      //【我添加的】
      textColor: 'rgba(19, 206, 102, 0.8)'
    };
  },
  methods: {
    bindEvent() {
      let self = this;
      eventBus.$on("afterAddPage", page => {
        self.page = page;
        self.graph = self.page.graph;
        eventBus.$on("nodeselectchange", item => {
          if (item.select === true && item.target.getType() === "node") {
            self.status = "node-selected";
            self.item = item.target;
            self.node = item.target.getModel();
          } else if (item.select === true && item.target.getType() === "edge") {
            self.status = "edge-selected";
            self.item = item.target;
            self.edge = item.target.getModel();
          } else {
            self.status = "canvas-selected";
            self.item = null;
            self.node = null;
          }
        });
      });
    },
    handleChangeName(e) {
      const model = {
        label: e
      };
      this.graph.update(this.item, model);
    },
    changeGridState(value) {
      if (value) {
        this.grid = new Grid();
        this.graph.addPlugin(this.grid);
      } else {
        this.graph.removePlugin(this.grid);
      }
    },
    handleChange(e) {
      const model = {
        label: e
      };
      this.graph.update(this.item, model);
    },
    handleChangeColor(e) {
      const model = {
        textColor: e
      };
      this.graph.update(this.item, model);
    }
  }

位置src/components/Flow/customEdge.js 加入

G6.registerEdge('customEdge', {
      draw(cfg, group) {
          这里
      }
if (cfg.label) {
          group.addShape('text', {
            attrs: {
              id: 'edgeText' + uniqueId(),
              x: end.x - (end.x - start.x) / 2,
              y: end.y - (end.y - start.y) / 2,
              text: cfg.label,
              fill: cfg.textColor ? cfg.textColor : '#000000'
            }
          })
        }

bug修改

位置:src/behavior/keyboard.js

onKeyDown(e) {
        const code = e.keyCode || e.which;
        switch (code) {
            case this.deleteKeyCode:
            case this.backKeyCode:
                // eventBus.$emit('deleteItem') 注释此行
                break
        }
    },

demo图