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 相关文章推荐
MooBox 基于Mootools的对话框插件
Jan 20 Javascript
Js四则运算函数代码
Jul 21 Javascript
jquery 插件开发 extjs中的extend用法小结
Jan 04 Javascript
JS使用getComputedStyle()方法获取CSS属性值
Apr 23 Javascript
jQuery实现监控页面所有ajax请求的方法
Dec 10 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
Apr 10 Javascript
详解vue路由篇(动态路由、路由嵌套)
Jan 27 Javascript
150行代码带你实现微信小程序中的数据侦听
May 17 Javascript
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
Jul 26 Javascript
js+css实现扇形导航效果
Aug 18 Javascript
详解vue 组件的实现原理
Nov 12 Javascript
Nest.js 授权验证的方法示例
Feb 22 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
模拟flock实现文件锁定
2007/02/14 PHP
PHP中函数内引用全局变量的方法
2008/10/20 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
基于php的CMS中展示文章类实例分析
2015/06/18 PHP
JavaScript 开发中规范性的一点感想
2009/06/23 Javascript
jQuery实现表单input中提示文字value随鼠标焦点移进移出而显示或隐藏的代码
2010/03/21 Javascript
JavaScript中数组对象的那些自带方法介绍
2013/03/12 Javascript
jQuery toggleClass应用实例(附效果图)
2014/04/06 Javascript
Jquery性能优化详解
2014/05/15 Javascript
JavaScript事件学习小结(五)js中事件类型之鼠标事件
2016/06/09 Javascript
jQuery实现的选择商品飞入文本框动画效果完整实例
2016/08/10 Javascript
jQuery实现仿京东防抖动菜单效果示例
2018/07/06 jQuery
react中Suspense的使用详解
2019/09/01 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
2019/09/27 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
Vue实现图书管理小案例
2020/12/03 Vue.js
Python itertools模块详解
2015/05/09 Python
浅析python实现scrapy定时执行爬虫
2018/03/04 Python
python操作openpyxl导出Excel 设置单元格格式及合并处理代码实例
2019/08/27 Python
Flask 上传自定义头像的实例详解
2020/01/09 Python
基于Python爬取爱奇艺资源过程解析
2020/03/02 Python
Python模拟登录和登录跳转的参考示例
2020/10/30 Python
微信小程序canvas实现水平、垂直居中效果
2020/02/05 HTML / CSS
Superdry极度干燥美国官网:英国制造的服装品牌
2018/11/13 全球购物
客户经理岗位职责
2013/12/08 职场文书
白酒业务员岗位职责
2013/12/27 职场文书
安全生产责任书
2014/03/12 职场文书
教学改革实施方案
2014/03/31 职场文书
股份合作协议书
2014/04/12 职场文书
爱牙日活动总结
2014/08/29 职场文书
公民授权委托书范本
2014/09/17 职场文书
测量员岗位职责
2015/02/14 职场文书
2015年销售员工作总结范文
2015/04/07 职场文书
广播体操比赛主持词
2015/06/29 职场文书
浅谈Redis 中的过期删除策略和内存淘汰机制
2022/04/03 Redis