vue + gojs 实现拖拽流程图效果

目录
  • 一、流程图效果
  • 二、为什么选go.js流程图插件去开发项目?
  • 三、项目开发
  • 四、当前画布的监听事件名称包括
  • 五、迭代篇
    • (一)、项目的迭代。
    • (二)、整体用的js方法
    • (三)、功能分析

一、流程图效果

最近一段时间在研究go.js,它是一款前端开发画流程图的一个插件,也是一个难点,要说为什么是难点,首先,它是依赖画布canvas知识开发。其次,要依赖于内部API开发需求,开发项目需求的时候就要花费大量的时间去熟悉go.js的API,然后才能进行开发。话不多说,我就先把我最近做的项目案例效果图展示一下:

看到效果图大家可能会想这个挺简单的,会想没什么难点,其实真正开发的时候才会知道的、才会领悟到。

二、为什么选go.js流程图插件去开发项目?

在项目开发一期的时候我用的不是go.js,而用的是一款轻便的流程插件jsplumb.js,它也集成了各种功能性API,但是在开发二期的时候它的内部功能已经满足不了需求了,所以我就开始在网上查找流程插件,看了很多插件,比如:G6,D3 等这些可视化流程插件都是不能满足需求。要说为什么不能满足需求,原因如下:

一、首先,看到效果图里的内置多点和其他模块单点连线问题,其他插件是无法这个满足需求的,可能我没有深入去了解其他的流程插件吧,但是go.js里内置点连线可以让开发者很快的理解代码逻辑,不用耗费大量的时间去想点与点的连线。

二、代码上的数据结构问题,其他插件里的API数据字段繁琐量多,不够清晰明了,而go.js里的数据结构就两个重要字段,一是所有模块的字段集合二是连线字段集合,根据需求可以随意加字段。

三、项目开发

(一)、首先直接使用go.js,画布中是有水印的

其实这个问题不大,替换一行代码就可以去除水印

引入go.js后,直接在编辑器中全局搜索7eba17a4ca3b1a8346,找到类似这样结构的代码

a.ir=b.W[Ra("7eba17a4ca3b1a8346")][Ra("78a118b7")](b.W,ok,4,4);

注:不同的版本代码不是完全相同的,可能是a.jv(属性名是会变的) =‘xxxxx’,将这行代码替换成

a.ir=function(){return true;}; //a.属性名 要保持一致

去除水印的效果

(二)、HTML

<--第一种-->

<template>
    <div id="wrap">
        <div id="chart-wrap">
            <div id="chart-palette"></div><-- 画布一 -->
            <div id="chart-diagram"></div><-- 画布二 -->
        </div>
    </div>
</template>

如图:

第二种

结合vue的拖拽组件vuedraggable 实现业务需求。

<template>
     <div id="chart-wrap">
                <div v-for="tab in tabLIst" :key="tab.id" class="tab">
              //拖动
           <vuedraggable @end.stop="end" @start.stop="move">

                                 <i :class="tab.icon" /> {{ tab.text }}
                                 <el-tooltip effect="dark" :content="tab.tooltip" placement="top">
                                             <i class="el-icon-question" />
                                 </el-tooltip>
                    </vuedraggable>
                  </div>
         <div id="chart-diagram"/> <--画布-->
      </div>
</template>  

如图:

(三)、画布的基本设置 。

this.diagram = $(go.Diagram, "chart-diagram",
                {
                    // 画布初始位置
                    initialContentAlignment: go.Spot.LeftSide, // 居中显示
                    "undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作
                    // 初始坐标
                    // initialPosition: new go.Point(0, 0),
                    //allowSelect:false,  ///禁止选中
                    // "toolManager.hoverDelay": 100, //tooltip提示显示延时
                    // "toolManager.toolTipDuration": 10000, //tooltip持续显示时间
                    //  isReadOnly:true,//只读

                    //禁止水平拖动画布
                    //禁止水平滚动条
                    allowHorizontalScroll: false,
                    // 禁止垂直拖动画布
                    //禁止垂直滚动条
                    allowVerticalScroll: false,
                    allowZoom: true,//画布是否可以缩放
                    "grid.visible": false, //显示网格
                    // allowMove: true, //允许拖动
                    // allowDragOut:true,
                    allowDelete: true,//禁止删除节点
                    allowCopy: true,//禁止复制
                    // 禁止撤销和重做
                    // "undoManager.isEnabled": false,
                    // 画布比例
                    // scale:1.5,
                    // minScale:1.2,//画布最小比例
                    // maxScale:2.0,//画布最大比例
                    // 画布初始化动画时间
                    // "animationManager.duration": 600,
                    // 禁止画布初始化动画
                    "animationManager.isEnabled": false,
                    // autoScale:go.Diagram.Uniform,//自适应

                    // autoScale:go.Diagram.UniformToFill,//自适应
                    //    "draggingTool.dragsLink": false,//拖动线
                    // autoScale:go.Diagram.None,//默认值不自适应
                    // 画布边距padding
                    // padding:80或者new go.Margin(2, 0)或new go.Margin(1, 0, 0, 1)
                    // validCycle: go.Diagram.CycleDestinationTree,//只允许有一个父节点
                    //节点模块动画  S
                    // "animationManager.initialAnimationStyle":go.Animation.EaseOutExpo,
                    // "animationManager.initialAnimationStyle": go.Animation.EaseInOutQuad,
                    "animationManager.initialAnimationStyle": go.AnimationManager.None,
                    // "animationManager.initialAnimationStyle":go.AnimationManager.AnimateLocations,
                    //节点模块动画   D
                    // validCycle: go.Diagram.CycleNotUndirected,

                    // validCycle: go.Diagram.CycleNotDirected,
                    // validCycle: go.Diagram.CycleSourceTree,
                    //ismodelfied:true //禁止拖拽
                    // 禁止鼠标拖动区域选中
                    // "dragSelectingTool.isEnabled" : false,
                    //允许使用delete键删除模块
                    "commandHandler.deletesTree": true,
                    // "hasHorizontalScrollbar":false,//去除水平滚动条
                    // "hasVerticalScrollbar":false,//去除竖直滚动条
                    // "canStart":false,
                    // allowClipboard: true,
                    // "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小,而不是向上和向下滚动
                    // layout: $(go.TreeLayout,
                    //     { angle: 90, layerSpacing: 80 }),
                }
            );

(三)、整体画布事件及节点的监听

                // 监听连线
                this.diagram.addDiagramListener("LinkDrawn", (e) => {
                    console.log(e.subject.part);
                });
                // 监听删除
                 this.diagram.addDiagramListener("SelectionDeleted", (e) => {
                     e.subject.each(function (n) {
                         console.log(n.data.key);
                     });
                  })
                // 修改节点
                this.diagram.addDiagramListener("TextEdited", (evt) => {
                    console.log(e.subject.part);
                });
                // 监听点击
                this.diagram.addDiagramListener("ObjectSingleClicked", (e) => {
            
                   //这是清除高亮的
                   // e.diagram.commit((d) => {
                    //      d.clearHighlighteds();
                     // }, "no highlighteds");
                });

                // // 移动事件
                this.diagram.addDiagramListener("SelectionMoved", (e) => {
                    console.log(e.diagram.lastInput.documentPoint);
                });

(四)、连线点封装函数

// 节点连接线

            makePort (name, align, spot, output, input) {
                var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom)
                return $(go.Shape, {
                    fill: 'transparent', // 默认透明不现实
                    strokeWidth: 0, // 无边框
                    fromMaxLinks: 1, //
                    width: horizontal ? NaN : 10, // 垂直"port"则8像素宽
                    height: !horizontal ? NaN : 5, // 水平"port"则8像素
                    alignment: align, // 同其模块对齐
                    stretch: horizontal
                        ? go.GraphObject.Horizontal
                        : go.GraphObject.Vertical, // 自动同其模块一同伸缩
                    portId: name, // 声明ID
                    fromSpot: spot, // 声明连线头连出此"port"的位置
                    fromLinkable: output, // 布尔型,是否允许连线从此"port"连出
                    toLinkable: input, // 布尔型,是否允许连线从此"port"连出
                    toSpot: spot, // 声明连线尾连入此"port"的位置
                    cursor: 'pointer', // 鼠标由指针改为手指,表示此处可点击生成连线
                    mouseEnter: function (e, port) {
                        // 鼠标移到"port"位置后,高亮
                        if (!e.diagram.isReadOnly) port.fill = 'rgba(255,0,255,0.3)'
                    },
                    mouseLeave: function (e, port) {
                        // 鼠标移出"port"位置后,透明
                        port.fill = 'transparent'
                    }
                })
            }

(五)、节点连线的高亮函数。

isHighlightedFun(link) {
                return $$(go.Shape,
                      "RoundedRectangle", {
                          fill: "rgba(217,236,255,.2)",
                          stroke: "rgba(39,154,242,.1)",
                          strokeWidth: 1,
                      },
                      new go.Binding("stroke", "isHighlighted", (h) => {
                            return h ? "rgba(39,154,242,1)" : "rgba(39,154,242,.8)";
                      }).ofObject(),
                      new go.Binding("strokeWidth", "isHighlighted", (h) => {
                          return h ? 2.5 : 1.3;
                      }).ofObject(),
                )
    }

如图:

(六)、 节点连接线。(方法封装)

makePort(name, align, spot, output, input) {
                var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
                return $$(go.Shape,
                      {
                          fill: "transparent",  // 默认透明
                          strokeWidth: 0,  // 无边框
                          fromMaxLinks: 1,  //最大连接数
                          width: horizontal ? NaN : 10,  // 垂直"port"则8像素宽
                          height: !horizontal ? NaN : 2,  // 水平"port"则8像素
                          alignment: align,  // 同其模块对齐
                          stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),//自动同其模块一同伸缩
                          portId: name,  // 声明ID
                          fromSpot: spot,  // 声明连线头连出此"port"的位置
                          fromLinkable: output,  // 布尔型,是否允许连线从此"port"连出
                          toLinkable: input,  // 布尔型,是否允许连线从此"port"连出
                          toSpot: spot,  // 声明连线尾连入此"port"的位置
                          cursor: "pointer",  // 鼠标由指针改为手指,表示此处可点击生成连线
                          mouseEnter: (e, port) => {  //鼠标移到"port"位置后,高亮
                              if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.3)";
                          },
                          mouseLeave: (e, port) => {// 鼠标移出"port"位置后,透明
                              port.fill = "transparent";
                          }
                      });
            }

注意:要在this.diagram.nodeTemplateMap.add 增加模块里调用。

示例:

this.diagram.nodeTemplateMap.add(type,
                      $$(go.Node, "Auto",
               this.makePort("T", go.Spot.Top, go.Spot.TopCenter, false, true)
))

四、当前画布的监听事件名称包括

"AnimationStarting" :动画渲染前事件,加载图表的动画即将开始;

"AnimationFinished" :动画渲染完事件,加载图表刚刚完成的动画;

"BackgroundSingleClicked": 背景单击事件, 单击图表背景;

"BackgroundDoubleClicked" :背景双击事件, 双击图表背景;

"BackgroundContextClicked" :背景右键事件, 右键单击图表背景;

"ChangingSelection": 改变选择前事件, 一个操作即将改变Diagram.selection图表选择集合,

"ChangedSelection" :改变选择后事件, 一个操作已经改变?Diagram.selection图表选择集合,

"ClipboardChanged" :剪切板改变事件, 零部件已被CommandHandler.copySelection复制到剪贴板上;

"ClipboardPasted" :剪切板粘贴事件,零部件已由CommandHandler.pasteSelection从剪贴板复制到图表中;

"DocumentBoundsChanged": 文档范围改变事件, 图表中各零部件的面积,?Diagram.documentBounds,已经改变了;

"ExternalObjectsDropped" :(节点或线等)零部件拖放生成事件, 零部件已经通过拖拽从图的外部复制到图中;

"GainedFocus" :获得键盘焦点事件, 该图获得了键盘焦点,例如在调用Diagram.focus之后.

"LayoutCompleted" :布局完成事件, 整个图表布局刚刚更新;

"LinkDrawn": 线创建事件,用户刚刚使用LinkingTool创建了一个新链接;?

"LinkRelinked": 线重新连接事件, 用户刚刚通过RelinkingTool?或?DraggingTool重新连接了现有线;

"LinkReshaped": 线路径改变事件, 用户刚刚通过LinkReshapingTool调整了线的路径;

"LostFocus" :图表失去焦点事件,这个图表失去了键盘焦点,

"Modified" :图表改变事件,?Diagram.isModified?属性已被设置为一个新值——用于将窗口标记为自上次保存以来已被修改;

"ObjectSingleClicked": 对象单击事件, 单击了图形对象(节点和线等);

"ObjectDoubleClicked":双击了图形对象(节点和线等);

"ObjectContextClicked":右键单击了图形对象(节点和线等);

"PartCreated" :Part创建事件,用户通过?ClickCreatingTool插入新的零部件;

"PartResized" :Part大小改变事件, 用户通过ResizingTool 调整工具改变了一个图形对象的大小;

"PartRotated" :Part旋转事件, 用户通过RotatingTool 旋转工具改变了一个图形对象的角度 ;

"SelectionMoved" :拖动事件, 用户通过DraggingTool 拖动工具移动了选定的部分;

"SelectionCopied" :复制事件,户通过DraggingTool 拖动工具复制了选定的部分;

"SelectionDeleted" :删除后事件,用户通过?CommandHandler.deleteSelection?已经删除了选定的部分;

"SelectionDeleting" :删除前事件,用户通过?CommandHandler.deleteSelection即将删除选定的部分;

"SelectionGrouped" :选择创建分组事件, 通过CommandHandler.groupSelection已经从选择的零部件中创建了一个新的组 ;

"SelectionUngrouped":用户已删除选定的组,但通过CommandHandler.ungroupSelection保留其成员;

"SubGraphCollapsed" :子图折叠事件, 用户通过CommandHandler.collapseSubGraph将选定的组折叠;

"SubGraphExpanded" :子图展开事件, 用户通过CommandHandler.expandSubGraph将选定的组展开;

"TextEdited" :文本块修改事件,用户通过文本编辑工具改变了文本块的字符串值;

"TreeCollapsed": 树折叠事件, 用户通过CommandHandler.collapseTree折叠所选节点的子树;

"TreeExpanded" :树展开事件, 用户通过CommandHandler.expandTree展开了所选节点的子树;

"ViewportBoundsChanged":视窗范围改变事件,图表中可见的区域,?Diagram.viewportBounds,发生了改变;

五、迭代篇

(一)、项目的迭代。

从数据结构到ui风格的整体重构,有了新的变化。

整体流程 如图一:

模块流程侧边设置图二:

伸缩当前灰色意图如图三:

为什么收起意图会有多条连线,是因为当前模块下的意图和部分模块有关系线,所以在收起时要知道当前模块下有几个意图和其他模块有关系。

(二)、整体用的js方法

1、画布里的功能js:

2、工具条js 方法:

(三)、功能分析

1、工具条中的功能方法

(1)、查看

注: 是通过gojs 实例中的makeSVG方法打开一个新窗口生成的一个svg

printDiagram() {
    var svgWindow = window.open();
if (!svgWindow) return;
var printSize = new go.Size(3000, 2000);
var bnds = this.diagram.documentBounds;
var x = bnds.x;
var y = bnds.y;
while (y < bnds.bottom) {
        while (x < bnds.right) {
            var svg = this.diagram.makeSVG({scale: 1.0, position: new go.Point(x, y), size: printSize});
svgWindow.document.body.appendChild(svg);
x += printSize.width;
}
        x = bnds.x;
y += printSize.height;
}
}

(2)、居中

这里将调用CommandHandler.scrollToPart,先还原画布初始状态后执行动画以将视口滚动到节点所在的位置。

注:如果节点靠近边缘,除非您增加Diagram.scrollMargin,否则无法滚动视口,以使该节点更靠近视口的中心。

centerDiagram() {
            this.resetCanvas();
            this.diagram.commandHandler.scrollToPart(this.diagram.findNodeForKey(this.initModuleId));
},
 // 还原
        resetCanvas() {
            this.diagram.scale = 1;
            this.$refs.set.zoom = 100;
        },

到此这篇关于vue + gojs 实现拖拽流程图的文章就介绍到这了,更多相关vue拖拽 流程图内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • gojs一些实用的高级用法

    目录 1. 取消更新动画 2. 导出图(含可视区外的部分) 3. 禁用 ctrl 相关快捷键 4. 画布滚动模式,无限滚动 or 局部滚动 5. 展开收起多层嵌套的组 6. 给图元素加动画 7. 修改框选的样式 1. 取消更新动画 问题:更新数据的时候,会触发渲染,有渲染动画,用户体验不好. 方案:初始数据绘制,有动画:更新数据绘制,无动画. 代码实现: // 后面所用到的 diagram 都是 gojs 创建的实例 // diagram_container 为图容器dom id diagram

  • GoJs图形绘图模板Shape示例详解

    目录 前言 Shape的使用 width和height属性 fill属性 stroke.strokeWidth.strokeDashArray属性 geometry属性 angle.scale属性 strokeCap strokeJoin属性 拓展 结语 前言 在可视化图形的展示过程中,节点内部往往不只是有文字描述,这样看起来很往往比较枯燥.在这个时候我们就可以在图形的节点内部加入一些几何图形.然后实现图形和文字的结合使用的话,不仅可以让节点内的内容更加形象,而且还可以通过图形标记对不同类型的节

  • GoJs 图片绘图模板Picture使用示例详解

    目录 前言 go.Picture的使用 go.Picture的属性 width.height.desiredSize属性 source属性 flip属性 imageStretch.imageAlignment属性 拓展 结语 前言 前面已经说过了通过go.TextBlock(文本)和go.Shape(集合图形)来丰富节点内部的显示内容.而有些时候需要在节点内部上传一些说明材料,恰好这些材料又是图片材料.如果拿图片和节点信息对照观看的话,一一对照会特别麻烦.如果能够在节点内部显示缩略图的话.在信息

  • GoJs基本使用示例详解

    目录 使用gojs背景 gojs的引入 去除水印 使用gojs背景 因为公司业务需要,需要完成一个树形的关系图,并且在后续过程中会对树形关系图进行很多的交互来拓展树形图的展示.因此在研究了D3,antV G6,cytoscape和go.js之后,决定使用gojs实现.因为gojs的交互功能封装比较完善,能够很快的搭建出想要的关系图之外,还有很多封装好的交互功能.例如可以使用键盘进行节点的复制和粘贴,通过textEdited属性实现节点内文字的双击编辑等等. gojs的引入 我们可以直接引入js的

  • gojs实现蚂蚁线动画效果

    目录 一.gojs 实现 1. 绘图 2. 虚线实现 3. 让虚线动起来 二.虚线及虚线动画背后的原理 三.虚线的一些概念 四.css 绘制边框虚线 在绘制 dag 图时,通过节点和来箭头的连线来表示节点彼此之间的关系.而节点常常又带有状态,为了更好的表示节点之间的流程关系,loading 状态的节点,与后续节点之间,需要用 动画着的虚线 表示,表示正在处理中,处理完才会变成实线.原理同页面没加载出来之间,加个 loading 提示,能提供更好的交互体验. 那么如何用 gojs 实现这个效果呢?

  • vue + gojs 实现拖拽流程图效果

    目录 一.流程图效果 二.为什么选go.js流程图插件去开发项目? 三.项目开发 四.当前画布的监听事件名称包括 五.迭代篇 (一).项目的迭代. (二).整体用的js方法 (三).功能分析 一.流程图效果 最近一段时间在研究go.js,它是一款前端开发画流程图的一个插件,也是一个难点,要说为什么是难点,首先,它是依赖画布canvas知识开发.其次,要依赖于内部API开发需求,开发项目需求的时候就要花费大量的时间去熟悉go.js的API,然后才能进行开发.话不多说,我就先把我最近做的项目案例效果

  • Vue.Draggable实现拖拽效果

    快速实现Vue.Draggable的拖拽效果,供大家参考,具体内容如下 1.下载包:npm install vuedraggable 配置:package.json "dependencies": { "element-ui": "^1.3.4", "less": "^2.7.2", "less-loader": "^4.0.4", "vue":

  • vue.draggable实现表格拖拽排序效果

    本文实例为大家分享了vue.draggable实现表格拖拽排序效果展示的具体代码,供大家参考,具体内容如下 主要使用vuedraggable和sortablejs两个组件. 1.安装组件 npm install vuedraggable npm install sortablejs 2.引入组件 import draggable from 'vuedraggable'; import Sortable from 'sortablejs'; export default { components:

  • Vue实现开关按钮拖拽效果

    本文实例为大家分享了Vue实现开关按钮拖拽效果的具体代码,供大家参考,具体内容如下 css: <style> .box { position: absolute; left: 100px; top: 100px; width: 100px; height: 100px; background: red; } .box2 { position: absolute; left: 400px; top: 100px; width: 100px; height: 100px; background:

  • Vue 实现一个简单的鼠标拖拽滚动效果插件

    最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了. github 地址:github.com/qq449245884- 最近在做一个新的项目,有个需要是这样的: 简单描述一下,就是鼠标拖动页面,整个页面会随着的鼠标的拖拽而移动,如果页面有内容,里面的内容也需要跟着拖动的外层整体移到. 一开始没啥思路,所以就发了个朋友圈,得到的答案挺多的,主要还是用拖拽之类的,但这个拖拽只是单个元素的拖动,我想要的整个视图的拖动. 这里线索又断了.

  • vue实现拖拽排序效果

    本文实例为大家分享了vue实现拖拽排序效果的具体代码,供大家参考,具体内容如下 效果预览 组件 drag.vue <template>   <TransitionGroup name="group-list" tag="ul">     <li       v-for="(item, index) in list"       :key="item.name"       :draggable=&

  • vue实现弹窗拖拽效果

    本文实例为大家分享了vue实现弹窗拖拽效果的具体代码,供大家参考,具体内容如下 前言 实现拖拽其实简单来说就分为三步 一.创建一个js文件 因为本身dialog窗口不具备移动拖拽能力,所以需要以下方法去实现,在src/components同级文件下创建utils文件夹,然后创建名为directives.js的文件. directives.js的代码如下: import Vue from 'vue'   // v-dialogDrag: 弹窗拖拽 Vue.directive('dialogDrag

  • vue实现列表拖拽排序的功能

    在日常开发中,特别是管理端,经常会遇到要实现拖拽排序的效果:这里提供一种简单的实现方案. 此例子基于vuecli3 首先,我们先了解一下js原生拖动事件: 在拖动目标上触发事件 (源元素): ondragstart - 用户开始拖动元素时触发 ondrag - 元素正在拖动时触发 ondragend - 用户完成元素拖动后触发 释放目标时触发的事件: ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件 ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触

  • Vue 实现可视化拖拽页面编辑器

    在线地址 (用梯子会更快些) 可视化页面编辑器,听起来可望不可即是吧,先来张动图观摩观摩一番! 实现这功能之前,在网上参考了很多资料,最终一无所获,五花八门的文章,都在述说着曾经的自己! 那么,这时候就需要自己去琢磨了,如何实现? 需要考虑到: 拖拽的实现 数据结构的定义 组件的划分 可维护性.扩展性 对象的引用:在这里是我感觉最酷的技巧了,来一一讲解其中的细节吧!! 拖拽实现 拖拽事件 这里使用 H5的拖拽事件 ,主要用到: dragstart // 开始拖拽一个元素时触发 draggable

  • vue实现可拖拽的dialog弹框

    本文主要介绍了vue实现可拖拽的dialog弹框,分享给大家,具体如下: element的dialog弹框在项目中挺常用的.但有时候嵌套的话会遮住,体验不好.拖拽形式的弹框会提高用户体验 借助基于 Sortable.js 的 Vue 拖拽组件vuedraggable 安装 npm install vuedraggable --save 在公共组件中新建个js文件,搭配vue自定义指令来实现拖拽的效果 import Vue from 'vue'; // v-dialogDrag: 弹窗拖拽属性 V

随机推荐