当前位置: 移动技术网 > IT编程>开发语言>JavaScript > GOJS+VUE实现流程图效果

GOJS+VUE实现流程图效果

2019年06月01日  | 移动技术网IT编程  | 我要评论

2013偶像运动会完整版,环保局标志,张国荣monica

前言及展示

在项目中需要根据传过来的数据画出流程图,采用了gojs插件,功能很全面,可以根据自己的需要调整,不过建议简单的流程图还是自己手写一个组件,更加便于维护和变换。有一点需要注意的是,gojs是需要收费的,有水印,虽然可以手动去掉,但是公司用的话还是需要买。gojs的官网上有关于在vue中应用gojs的小例子:minimal gojs sample in vue.js。推荐看一下,可以解决大部分简单需求,这个例子可以满足你并行步骤数比较固定的二叉树画法的流程图。

这是官网的例子,其中模块,线,箭头等画布元素都可以交互。
由于我的并行步骤数不固定,于是在图中加入了group(组)。先展示一下成品:

其中批次中可以包含多个项目,表示并行的步骤。

具体实现

分为两个文件:
diagram.vue && stepmap.vue
diagram.vue声明组件,stepmap引用

diagram.vue

基本声明:

<script>
 import go from 'gojs';
 let $ = go.graphobject.make; // 后面很多用到该变量来初始化diagram
 export default{
  name: 'diagram',
  props: ['modeldata'], // accept model data as a parameter
  data() {
   return {
   diagram: null,
   }; 
  }, // provide access to the gojs diagram

初始化diagram:

mounted: function() {
  let self = this;
  let mydiagram =
   $(go.diagram, this.$el,
   {
    'initialcontentalignment': go.spot.center,
    'isenabled': false, // 是否可拖拽,默认为是
    // 'toolmanager.mousewheelbehavior': go.toolmanager.wheelnone,
    'allowlink': false, 
    'allowmove': false,
    'allowrelink': false, // 由于项目只想展示数据,我禁用了大部分图像交互操作,具体可参看官网api
    'layout': $(go.treelayout, {angle: 0, arrangement: go.treelayout.arrangementhorizontal}),  // angle可控制图像展示方向
    'undomanager.isenabled': true,
    // model changedevents get passed up to component users
    'changedselection': function(e) {
     self.$emit('changed-selection', e); 
    },
   });
   
  mydiagram.nodetemplate = // 节点的初始化设置
   $(go.node, 'auto',
   $(go.shape, // 节点形状设置
   {
    fill: 'white', strokewidth: 1,
    portid: '', fromlinkable: true, tolinkable: true, cursor: 'pointer',
   },
    new go.binding('fill', '', this.nodecolorconverter)), // nodecolorconverter是我自定义函数,根据节点状态设置节点的背景颜色
   $(go.textblock, // 节点提示文字设置
    {margin: 16, editable: false},
    new go.binding('text').maketwoway())
   );

  mydiagram.linktemplate =
   $(go.link,
   {relinkablefrom: true, relinkableto: true},
   $(go.shape, // 连线形状设置
   {strokewidth: 2},
   new go.binding('stroke', '', this.linkcolorconverter)), // 连线的颜色设置
   $(go.shape, // arrowhead
   {toarrow: 'triangle', stroke: null, scale: 1.5}, // 箭头设置
   new go.binding('fill', '', this.linkcolorconverter))
   );
  
  mydiagram.grouptemplate = // 分组的初始化
   $(go.group, 'auto',
    { // define the group's internal layout
    layout: $(go.treelayout,
       {angle: 90, arrangement: go.treelayout.arrangementvertical, isrealtime: false}),
    // the group begins unexpanded;
    // upon expansion, a diagram listener will generate contents for the group
    // when a group is expanded, if it contains no parts, generate a subgraph inside of it
    // subgraphexpandedchanged: function(group) {
    // if (group.memberparts.count === 0) {
    //  randomgroup(group.data.key);
    // }
    // },
    },
   $(go.shape, 'rectangle',
    {fill: null, stroke: 'gray', strokewidth: 2}),
   $(go.panel, 'vertical',
    {defaultalignment: go.spot.left, margin: 4},
    $(go.panel, 'horizontal',
    {defaultalignment: go.spot.top},
    $('subgraphexpanderbutton', {alignment: go.spot.top, margin: 5}),
    // the subgraphexpanderbutton is a panel that functions as a button to expand or collapse the subgraph
    $(go.textblock,
     {
     font: 'bold 14px sans-serif',
     margin: 10,
     },
     new go.binding('text', 'text'))
    ),
   // create a placeholder to represent the area where the contents of the group are
    $(go.placeholder,
    {padding: new go.margin(0, 10)}),
   ) // end vertical panel
   ); // end group

   // generate the initial model
  this.diagram = mydiagram;
  this.updatemodel(this.modeldata);

更新图中数据时需要的函数:

watch: {
  modeldata: function(val) { 
   this.updatemodel(val); 
  },
  },
  methods: {
  model: function() { 
   return this.diagram.model; 
  },
  updatemodel: function(val) {
   // no gojs transaction permitted when replacing diagram.model.
   if (val instanceof go.model) {
   this.diagram.model = val;
   } else {
   let m = new go.graphlinksmodel();
   if (val) {
    for (let p in val) {
    if (val[p]) {
     m[p] = val[p];
    }
    }
   }
   this.diagram.model = m;
   }
  },
  updatediagramfromdata: function() {
   this.diagram.starttransaction();
   // this is very general but very inefficient.
   // it would be better to modify the diagramdata data by calling
   // model.setdataproperty or model.addnodedata, et al.
   this.diagram.updateallrelationshipsfromdata();
   this.diagram.updatealltargetbindings();
   this.diagram.committransaction('updated');
  },
  },
 };
</script>

声明后在stepmap调用,比较重要的是这两个方法:

updatediagramfromdata: function() {
   this.$refs.diag.updatediagramfromdata(); // 数据变化时调用组件中的更新方法
  },
changedselection: function(e) {
   let node = e.diagram.selection.first();
   if (node instanceof go.node) {
   this.currentnode = node;
   this.currentnodetext = node.data.text;
   this.selectnode(node.data);
   } else {
   this.currentnode = null;
   this.currentnodetext = '';
   }
  },

最后,将需要展示的数据转化为需要的格式就可以啦。

流程图所需格式如下:

无分组:
 "nodedataarray": [ 
{"key":1, "text":"alpha", "color":"lightblue"},
{"key":2, "text":"beta", "color":"orange"},
{"key":3, "text":"gamma", "color":"lightgreen"},
{"key":4, "text":"delta", "color":"pink"}
 ]
 "linkdataarray": [ 
{"from":1, "to":2},
{"from":1, "to":3},
{"from":3, "to":4}
 ]
有分组:
 var nodedataarray = [
 { key: "alpha" },
 { key: "beta", group: "omega" },
 { key: "gamma", group: "omega" },
 { key: "omega", isgroup: true }, 
 { key: "delta" }
 ];
 var linkdataarray = [
 { from: "alpha", to: "beta" }, 
 { from: "beta", to: "gamma" }, 
 { from: "omega", to: "delta" } 
 ];

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网