antV G6流程圖在Vue中的使用

<blockquote>最近我司項目中須要加入流程圖製做功能,因而乎百度各類找可視化繪製拓撲圖的輪子,大部分都是國外的,看文檔太吃力,不過好在最終讓我發現了AntV G6流程圖圖表庫,最新版爲2.0,不過編輯器在2.0版本尚未進行開源,因此只能退而求其次,使用了1.2.8版本。但願2.0版本的編輯器儘早開源,在交互方面1.2.8版本仍是差了一些。<p>該組件並<strong><code>非開箱即食</code></strong>,須要根據本身的業務進行修改,右側屬性表單部分若是有時間考慮改成插槽形式,方便之後複用~</p> </blockquote> <a href="http://www.jqhtml.com/24333.html" target="_blank">如何將數據進行數據可視化展示?</a> <h3>技術棧</h3> <ul> <li> <a href="https://cn.vuejs.org/" rel="nofollow noreferrer">Vue</a> <code>v3.0.1</code> </li> <li> <a href="http://element.eleme.io/#/zh-CN" rel="nofollow noreferrer">Element-ui</a> <code>v2.4.5</code> </li> <li> <a href="http://antvis.github.io/g6/api/index.html" rel="nofollow noreferrer">antV G6</a> <code>v1.2.8</code> </li> <li>Sass</li> </ul> <h3>效果圖</h3>css

在這裏插入圖片描述

<h3>引入</h3> <p>在<code>index.html</code>中進行了全局引用</p>html

&lt;script src="./static/plugin/g6.min.js"&gt;&lt;/script&gt;

<h3>實例代碼</h3> <p>仿照2.0版本的編輯器將G6做爲了一個組件使用,代碼:</p>vue

&lt;template&gt;
  &lt;div id="flowChart"&gt;
    &lt;div class="operating"&gt;
      &lt;div class="btn-group"&gt;
        &lt;div class="btn" @click="addCircle" title="起始節點"&gt;
          &lt;i class="iconfont icon-circle-oeps"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="addRect" title="常規節點"&gt;
          &lt;i class="iconfont icon-square-oeps"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="addRhombus" title="條件節點"&gt;
          &lt;i class="iconfont icon-square-ling"&gt;&lt;/i&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="btn-group"&gt;
        &lt;div class="btn" @click="addLine" title="直線"&gt;
          &lt;i class="iconfont icon-zhixian"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="addSmooth" title="曲線"&gt;
          &lt;i class="iconfont icon-quxian"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="addArrowLine" title="箭頭直線"&gt;
          &lt;i class="iconfont icon-jiantouzhixian"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="addArrowSmooth" title="箭頭曲線"&gt;
          &lt;i class="iconfont icon-jiantouquxian"&gt;&lt;/i&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="btn-group"&gt;
        &lt;div class="btn" @click="changeMode('edit')" title="選擇模式"&gt;
          &lt;i class="iconfont icon-chose"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="changeMode('drag')" title="拖拽模式"&gt;
          &lt;i class="iconfont icon-move"&gt;&lt;/i&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="btn-group"&gt;
        &lt;div class="btn" @click="del" style="margin-top: 5px;" title="刪除"&gt;
          &lt;i class="el-icon-delete"&gt;&lt;/i&gt;
        &lt;/div&gt;
        &lt;div class="btn" @click="save" title="保存"&gt;
          &lt;i class="iconfont icon-baocun"&gt;&lt;/i&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="btn-group"&gt;
        &lt;el-input size="mini" v-model="workflowName" placeholder="請輸入流圖名稱..."&gt;&lt;/el-input&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="info"&gt;
      &lt;div class="title"&gt;
        &lt;span&gt;{{infoTitle}}屬性&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class="content"&gt;
        &lt;el-checkbox v-if="isBlank === true" v-model="checked"&gt;網格對齊&lt;/el-checkbox&gt;
        &lt;el-form v-else label-position="left" label-width="60px"&gt;
          &lt;el-form-item v-if="isNode !== true" label="動做"&gt;
            &lt;el-select v-model="action" size="mini" filterable placeholder="綁定動做" value=""&gt;
              &lt;el-option
                v-for="item in actionList"
                :key="item.id"
                :label="item.label"
                :value="item.id"&gt;
              &lt;/el-option&gt;
            &lt;/el-select&gt;
          &lt;/el-form-item&gt;   &lt;!-- 線--&gt;
          &lt;el-form-item v-if="isNode === true" label="名稱"&gt;
            &lt;el-input size="mini" v-model="name"&gt;&lt;/el-input&gt;
          &lt;/el-form-item&gt;
          &lt;el-form-item v-if="isNode === true" label="功能"&gt;
            &lt;el-select v-model="func" size="mini" filterable placeholder="綁定功能" value=""&gt;
              &lt;el-option
                v-for="item in funcList"
                :key="item.id"
                :label="item.label"
                :value="item.id"&gt;
              &lt;/el-option&gt;
            &lt;/el-select&gt;
          &lt;/el-form-item&gt;
          &lt;el-form-item v-if="isNode === true" label="帳號"&gt;
            &lt;el-select v-model="account" size="mini" filterable multiple
                       collapse-tags placeholder="綁定帳號" value=""&gt;
              &lt;el-option
                v-for="item in accountList"
                :key="item.id"
                :label="item.label"
                :value="item.id"&gt;
              &lt;/el-option&gt;
            &lt;/el-select&gt;
          &lt;/el-form-item&gt;
          &lt;el-form-item v-if="isNode === true" label="流圖"&gt;
            &lt;el-select v-model="workflow" size="mini" filterable clearable placeholder="綁定流圖" value=""&gt;
              &lt;el-option
                v-for="item in workflowList"
                :key="item.id"
                :label="item.label"
                :value="item.id"&gt;
              &lt;/el-option&gt;
            &lt;/el-select&gt;
          &lt;/el-form-item&gt;
          &lt;el-form-item v-if="isNode === true" label="類型"&gt;
            &lt;el-select v-model="nodeType" size="mini" filterable placeholder="請選擇類型" value=""&gt;
              &lt;el-option
                v-for="item in nodeTypeList"
                :key="item.id"
                :label="item.label"
                :value="item.id"&gt;
              &lt;/el-option&gt;
            &lt;/el-select&gt;
          &lt;/el-form-item&gt;
          &lt;el-form-item label="顏色"&gt;
            &lt;el-color-picker v-model="color"&gt;&lt;/el-color-picker&gt;
          &lt;/el-form-item&gt;
        &lt;/el-form&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;

  export default {
    name: "index",
    components: {},
    mounted() {
      this.initG6();
    },
    props: {
      actionList: {
        type: Array, default: []
      },
      funcList: {
        type: Array, default: []
      },
      accountList: {
        type: Array, default: []
      },
      workflowList: {
        type: Array, default: []
      },
      nodeTypeList: {
        type: Array, default: () =&gt; {
          return [
            {id: 0, label: '普通節點'},
            {id: 1, label: '入口節點'},
            {id: 2, label: '出口節點'}
          ]
        }
      }
    },
    data() {
      return {
        action: '',
        name: '',
        func: '',
        account: '',
        workflow: '',
        nodeType: 0,
        color: '',

        net: '',
        Util: '',
        workflowName: '',
        activation: '', //當前激活的節點
        isNode: false, //當前是節點
        isBlank: true,   //當前是空白區
        checked: true,  //網格對齊
        infoTitle: '畫布',//屬性標題
        oldColor: '',    //獲取節點自己顏色
        type: '',        //有值爲編輯狀態
      }
    },
    methods: {
      initG6() {
        let self = this;
        self.Util = G6.Util;
        let grid;
        if (self.checked) {
          grid = {
            forceAlign: true, // 是否支持網格對齊
            cell: 25,         // 網格大小
          };
        } else {
          grid = null;
        }
        self.net = new G6.Net({
          id: 'flowChart',      // 容器ID
          mode: 'edit',
          grid: grid,
          /*width: 500,    // 畫布寬*/
          height: 800    // 畫布高
        });
        /*self.net.tooltip({
          title: '信息', // @type {String} 標題
          split: ':',  // @type {String} 分割符號
          dx: 0,       // @type {Number} 水平偏移
          dy: 0        // @type {Number} 豎直偏移
        });*/

        /**
         *點擊空白處
         */
        self.net.on('click', (ev) =&gt; {
          if (!self.Util.isNull(ev.item)) {
            self.isBlank = false
          } else {
            self.isBlank = true;
            self.infoTitle = '畫布'
          }
        });
        /**
         *點擊節點
         */
        self.net.on('itemclick', function (ev) {
          self.isNode = self.Util.isNode(ev.item);   //是否爲Node
          self.activation = ev.item;
          if (self.isNode) {
            /* 激活節點後節點名稱input聚焦*/
            self.$nextTick(()=&gt;{
              self.$refs.inputFocus.$el.querySelector('input').focus();
            });
            self.infoTitle = '節點';
            self.name = ev.item.get('model').label;
            self.func = ev.item.get('model').func;
            self.account = ev.item.get('model').account || [];
            self.workflow = ev.item.get('model').workflow;
            self.nodeType = ev.item.get('model').nodeType;
          } else {
            self.infoTitle = '邊';
            self.action = ev.item.get('model').action;
          }
          self.color = self.oldColor;
        });
        /**
         * 鼠標移入移出事件改變顏色
         */
        self.net.on('itemmouseenter', ev =&gt; {
          const item = ev.item;
          self.oldColor = item.get('model').color;     //獲取節點顏色
          self.net.update(item, {
            color: '#108EE9',
          });
          self.net.refresh();
        });
        self.net.on('itemmouseleave', ev =&gt; {
          const item = ev.item;
          self.net.update(item, {
            color: self.oldColor
          });
          self.net.refresh();
        });
        /**
         * 提示信息
         */
       /* self.net.node().tooltip(['label', 'func', 'role', 'color']);
        self.net.edge().tooltip(['label', 'color']);*/
        /**
         * 渲染
         */
        /*self.net.source(self.nodes, self.edges);*/  //加載資源數據
        self.net.render();
      },
      addCircle() {
        this.net.beginAdd('node', {
          shape: 'circle',
          nodeType: 0
        })
      },//添加起始節點
      addRect() {
        this.net.beginAdd('node', {
          shape: 'rect',
          nodeType: 0
        })
      },//添加常規節點
      addRhombus() {
        this.net.beginAdd('node', {
          shape: 'rhombus',
          nodeType: 0
        })
      }, //添加條件節點
      addLine() {
        this.net.beginAdd('edge', {
          shape: 'line'
        });
      }, //添加直線
      addSmooth() {
        this.net.beginAdd('edge', {
          shape: 'smooth'
        })
      },  //添加曲線
      addArrowSmooth() {
        this.net.beginAdd('edge', {
          shape: 'smoothArrow'
        })
      }, //添加箭頭曲線
      addArrowLine() {
        this.net.beginAdd('edge', {
          shape: 'arrow'
        });
      }, //添加箭頭直線
      addPolyLine() {
        this.net.beginAdd('edge', {
          shape: 'polyLineFlow'
        });
      }, //添加折線
      changeMode(mode) {
        this.net.changeMode(mode)
      }, //拖拽與編輯模式的切換
      del() {
        this.net.del()
      },//刪除
      save() {
        /* 驗證流圖名稱*/
        if (this.workflowName !== '') {
          let data = this.net.save();
          if (data.source.nodes.length === 0) {
            this.$message({type: 'error', message: '流圖內容不能爲空'});
            return false
          }
          /* 驗證節點名稱*/
          for (let item of data.source.nodes) {
            if (item.label === '' || item.label === null || item.label === undefined) {
              this.$message({type: 'error', message: '節點名稱不能爲空'});
              return false
            }
          }
          data.source['name'] = this.workflowName;
          /*let json = JSON.stringify(data, null, 2);*/
          this.$emit('saveData', data.source, this.type);
        } else {
          this.$message({type: 'error', message: '流圖名稱不能爲空'})
        }
        /*console.log(saveData, json);*/
      },//保存
      update() {
        if (this.activation.get('type') === 'node') {
          this.net.update(this.activation, {
            label: this.name,
            func: this.func,
            account: this.account,
            workflow: this.workflow,
            nodeType: this.nodeType,
            color: this.color
          });
        } else {
          /* 根據ID取出label*/
          let label = this.actionList.map(item =&gt; {
            if (item.id === this.action) {
              return item.label
            }
          }).join('');
          this.net.update(this.activation, {
            label: label,
            color: this.color,
            action: this.action
          });
        }
      },  //更新節點
      clearView() {
        this.type = '';
        this.workflowName = '';
        this.net.changeData()
      },   //清空視圖
      source(nodes, edges, name, type) {
        this.type = type;
        this.workflowName = name;
        this.net.changeData(nodes, edges)
      },  //更新數據
    },
    watch: {
      /**
       * 監聽輸入框
       */
      action: function () {
        this.update()
      },
      name: function () {
        this.update()
      },
      func: function () {
        this.update()
      },
      account: function () {
        this.update()
      },
      workflow: function () {
        this.update()
      },
      nodeType: function () {
        this.update()
      },
      color: function () {
        this.update()
      },
      /**
       * 網格切換
       */
      checked: function () {
        let _saveData = this.net.save();
        this.net.destroy();  //銷燬畫布
        this.initG6();
        this.net.read(_saveData);
        this.net.render()
      }
    }
  }
&lt;/script&gt;

&lt;style rel="stylesheet/scss" lang="scss" scoped&gt;
  #flowChart {
    border: 1px solid #ebeef5;
    position: relative;
    overflow: hidden;
  }

  .operating {
    position: absolute;
    z-index: 99;
    background-color: #ffffff;
    padding: 20px 10px;
    box-shadow: 1px 1px 4px 0 #0a0a0a2e;
  }

  .info {
    position: absolute;
    right: 0;
    z-index: 99;
    box-shadow: 1px 1px 4px 0 #0a0a0a2e;
    .title {
      height: 40px;
      padding-left: 10px;
      border-top: 1px solid #DCE3E8;
      border-bottom: 1px solid #DCE3E8;
      border-left: 1px solid #DCE3E8;
      background: rgb(235, 238, 242);
      line-height: 40px;
      span {
        font-size: 14px;
      }
    }
    .content {
      background: rgba(247, 249, 251, 0.45);
      width: 200px;
      height: 800px;
      border-left: 1px solid #E6E9ED;
      padding: 10px;
    }
  }

  .btn-group {
    border-right: 1px solid #efefef;
    display: inline-block;
    padding-left: 10px;
    padding-right: 14px;
    &amp;:last-of-type {
      border-right: 0;
    }
    .btn {
      display: inline-block;
      margin: 2px;
      width: 30px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      cursor: pointer;
      border: 1px solid rgba(233, 233, 233, 0);
      i {
        font-size: 20px;
      }
      &amp;:hover {
        border: 1px solid #E9E9E9;
        color: #767A85;
        border-radius: 2px;
        background: #FAFAFE;
      }
    }
    .el-form-item {
      margin-bottom: 0 !important;
    }
  }
&lt;/style&gt;

<h3>流圖屬性</h3> <table> <thead><tr> <th>參數</th> <th>說明</th> <th>類型</th> <th>可選值</th> <th>默認值</th> </tr></thead> <tbody> <tr> <td>actionList</td> <td>動做數據</td> <td>Array</td> <td>——</td> <td>[]</td> </tr> <tr> <td>funcList</td> <td>功能數據</td> <td>Array</td> <td>——</td> <td>[]</td> </tr> <tr> <td>accountList</td> <td>帳號數據</td> <td>Array</td> <td>——</td> <td>[]</td> </tr> <tr> <td>workflowList</td> <td>流圖數據</td> <td>Array</td> <td>——</td> <td>[]</td> </tr> <tr> <td>nodeTypeList</td> <td>節點類型數據</td> <td>Array</td> <td>——</td> <td><code>[{id: 0, label: '普通節點'},{id: 1, label: '入口節點'},{id: 2, label: '出口節點'}]</code></td> </tr> </tbody> </table> <blockquote>全部屬性接收的數據格式須要與<code>nodeTypeList</code>的默認值相同</blockquote> <h3>流圖事件</h3> <table> <thead><tr> <th>事件名</th> <th>說明</th> <th>參數</th> </tr></thead> <tbody><tr> <td>saveData</td> <td>當用戶手動點擊保存觸發事件</td> <td>source,type</td> </tr></tbody> </table> <blockquote>參數<code>type</code>可爲空,在此項目中主要用來區分<code>新建</code>與<code>編輯</code> </blockquote> <h3>流圖方法</h3> <table> <thead><tr> <th>方法名</th> <th>說明</th> <th>參數</th> </tr></thead> <tbody> <tr> <td>clearView</td> <td>清空當前視圖</td> <td>——</td> </tr> <tr> <td>source</td> <td>渲染數據</td> <td>nodes, edges, name, type</td> </tr> </tbody> </table> <blockquote>參數<code>type</code>與事件中相同,參數<code>name</code>的做用是用來取流圖名</blockquote> <h3>參考文檔</h3> <p><a href="https://www.jianshu.com/p/e28c70a3605c" rel="nofollow noreferrer">使用 G6關係圖類庫 開發流程圖工具</a></p> <p><a href="http://antvis.github.io/g6/api/index.html" rel="nofollow noreferrer">舊版本G6 1.x API 文檔</a></p> <p><a href="https://antv.alipay.com/zh-cn/g6/1.x/api/graph.html" rel="nofollow noreferrer">新版本G6 2.x API 文檔</a></p>node

來源:http://www.javashuo.com/article/p-sukucdwq-bm.htmlgit

相關文章
相關標籤/搜索