GOJS+VUE实现流程图效果


Posted in Javascript onDecember 01, 2018

前言及展示

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

GOJS+VUE实现流程图效果

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

GOJS+VUE实现流程图效果

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

具体实现

分为两个文件:
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" } 
 ];

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE6/7/8/9不支持exec的简写方式
May 25 Javascript
用javascript作一个通用向导说明
Aug 30 Javascript
jquery 延迟执行实例介绍
Aug 20 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
Oct 23 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
Apr 10 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
Aug 03 Javascript
Canvas 绘制粒子动画背景
Feb 15 Javascript
CodeMirror js代码加亮使用总结
Mar 25 Javascript
js遍历添加栏目类添加css 再点击其它删除css【推荐】
Jun 12 Javascript
详解离线安装npm包的几种方法
Nov 25 Javascript
vue本地打开build后生成的dist文件夹index.html问题
Sep 04 Javascript
原生JS生成指定位数的验证码
Oct 28 Javascript
JavaScript实现简单轮播图效果
Dec 01 #Javascript
jQuery-ui插件sortable实现自由拖动排序
Dec 01 #jQuery
jquery拖拽自动排序插件使用方法详解
Jul 20 #jQuery
vue实现移动端悬浮窗效果
Dec 01 #Javascript
vue拖拽组件使用方法详解
Dec 01 #Javascript
vue实现div拖拽互换位置
Jul 29 #Javascript
vue插件draggable实现拖拽移动图片顺序
Dec 01 #Javascript
You might like
ThinkPHP和UCenter接口冲突的解决方法
2016/07/25 PHP
PHP实现的超长文本分页显示功能示例
2018/06/04 PHP
jQuery 隔行换色 支持键盘上下键,按Enter选定值
2009/08/02 Javascript
高效的表格行背景隔行变色及选定高亮的JS代码
2010/12/04 Javascript
jQuery中将函数赋值给变量的调用方法
2012/03/23 Javascript
jquery 清空file域示例(兼容个浏览器)
2013/10/11 Javascript
深入理解javascript动态插入技术
2013/11/12 Javascript
js window.onload 加载多个函数和追加函数详解
2014/01/08 Javascript
Jquery响应回车键直接提交表单操作代码
2014/07/25 Javascript
Jquery弹出层插件ThickBox的使用方法
2014/12/09 Javascript
Angularjs 基础入门
2014/12/26 Javascript
js实现点击左右按钮轮播图片效果实例
2015/01/29 Javascript
JavaScript中校验银行卡号的实现代码
2016/12/19 Javascript
jQuery Ajax全解析
2017/02/13 Javascript
动态创建类实例代码
2009/10/07 Python
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
Python中的单继承与多继承实例分析
2018/05/10 Python
彻彻底底地理解Python中的编码问题
2018/10/15 Python
python3 实现的对象与json相互转换操作示例
2019/08/17 Python
python 申请内存空间,用于创建多维数组的实例
2019/12/02 Python
python设置代理和添加镜像源的方法
2020/02/14 Python
解决Windows下python和pip命令无法使用的问题
2020/08/31 Python
Html5 canvas画图白板踩坑
2020/06/01 HTML / CSS
Club Monaco加拿大官网:设计师男女服装
2019/09/29 全球购物
乡镇庆八一活动方案
2014/02/02 职场文书
职工趣味运动会方案
2014/02/10 职场文书
《胖乎乎的小手》教学反思
2014/02/26 职场文书
2014年党的群众路线教育实践活动总结
2014/04/25 职场文书
学习党的群众路线对照检查材料
2014/09/29 职场文书
私人房屋买卖协议书
2014/10/04 职场文书
绿色环保倡议书
2015/04/28 职场文书
对领导班子的意见和建议
2015/06/08 职场文书
党务工作者主要事迹材料
2015/11/03 职场文书
redis限流的实际应用
2021/04/24 Redis
详解如何使用Nginx解决跨域问题
2022/05/06 Servers
彻底卸载VMware虚拟机的超详细步骤记录
2022/07/15 Servers