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 相关文章推荐
js实现简单模态窗口,背景灰显
Nov 14 Javascript
input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
Apr 02 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
Oct 24 Javascript
提高jQuery性能的十个诀窍
Nov 14 Javascript
js实现接收表单的值并将值拼在表单action后面的方法
Nov 23 Javascript
JS运动相关知识点小结(附弹性运动示例)
Jan 08 Javascript
使用原生js写ajax实例(推荐)
May 31 Javascript
js实现Tab选项卡切换效果
Jul 17 Javascript
jQuery实现动态添加节点与遍历节点功能示例
Nov 09 jQuery
layui点击导航栏刷新tab页的示例代码
Aug 14 Javascript
jQuery+css last-child实现选择最后一个子元素操作示例
Dec 10 jQuery
详解Vue源码之数据的代理访问
Dec 11 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
在PHP中利用XML技术构造远程服务(下)
2006/10/09 PHP
PHP实时显示输出
2008/10/02 PHP
PHP面向对象学习笔记之二 生成对象的设计模式
2012/10/06 PHP
避免 showModalDialog 弹出新窗体的原因分析
2010/05/31 Javascript
在Windows上安装Node.js模块的方法
2011/09/25 Javascript
JS操作数据库的实例代码
2013/10/17 Javascript
javascript实现点击商品列表checkbox实时统计金额的方法
2015/05/15 Javascript
JavaScript编程中window的location与history对象详解
2015/10/26 Javascript
javascript Slip.js实现整屏滑动的手机网页
2015/11/25 Javascript
AngularJs学习第五篇从Controller控制器谈谈$scope作用域
2016/06/08 Javascript
JavaScript实现类似拉勾网的鼠标移入移出效果
2016/10/27 Javascript
ES6新特性三: Generator(生成器)函数详解
2017/04/21 Javascript
认识jQuery的Promise的具体使用方法
2017/10/10 jQuery
vue2过滤器模糊查询方法
2018/09/16 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
详解关于webpack多入口热加载很慢的原因
2019/04/24 Javascript
小程序中英文混合排序问题解决
2019/08/02 Javascript
Webpack设置环境变量的一些误区详解
2019/12/19 Javascript
vue-drag-chart 拖动/缩放图表组件的实例代码
2020/04/10 Javascript
微信小程序手动添加收货地址省市区联动
2020/05/18 Javascript
[03:42]2016国际邀请赛中国区预选赛首日现场玩家采访
2016/06/26 DOTA
[55:44]OG vs NAVI 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
使用Python下载Bing图片(代码)
2013/11/07 Python
使用TensorFlow-Slim进行图像分类的实现
2019/12/31 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
基于DOM+CSS3实现OrgChart组织结构图插件
2016/03/02 HTML / CSS
HTML5 canvas实现雪花飘落特效
2016/03/08 HTML / CSS
Shopbop中文官网:美国亚马逊旗下时尚购物网站
2020/12/15 全球购物
团员的自我评价
2013/12/01 职场文书
编辑求职信样本
2013/12/16 职场文书
物理专业大学生职业生涯规划书
2014/02/07 职场文书
毕业生就业意向书
2014/04/01 职场文书
优秀员工演讲稿
2014/05/19 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
2015年宣传部部长竞选演讲稿
2014/11/28 职场文书
python_tkinter事件类型详情
2022/03/20 Python