热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

vue+jsplumb实现工作流程图的方法

这篇文章主要介绍“vue+jsplumb实现工作流程图的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue+j

这篇文章主要介绍“vue+jsplumb实现工作流程图的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue+jsplumb实现工作流程图的方法”文章能帮助大家解决问题。

先写了一个demo,大概样子如下:

vue+jsplumb实现工作流程图的方法

官网文档Home | jsPlumb Toolkit Documentation

先安装插件

npm install jsplumb --save

安装panzoom,主要用于鼠标滚轮缩放流程图

npm install panzoom --save

在需要的页面引入插件

import panzoom from 'panzoom'
import { jsPlumb } from 'jsplumb'

接下来先写布局

父组件

flowNode是子组件

样式主要是子组件的,父组件样式随意就行

页面样式写完,接下来写插件配置

jsPlumb.ready() 是一个钩子函数,它会在 jsPlumb 准备完毕时执行。

连接线的建立是通过 jsPlumb.connect() 方法实现的。该方法接受一个对象作为配置项。其中包含了与上述概念一一对应的配置项,以及一些额外的样式。

source: 源对象,可以是对象的 id 属性、Element 对象或者 Endpoint 对象。

target: 目标对象,可以是对象的 id 属性、Element 对象或者 Endpoint 对象。

anchor: 是一个数组,数组中每一项定义一个锚点。

初始化方法

init() {
    this.jsPlumb.ready(() => {
      // 导入默认配置
      this.jsPlumb.importDefaults(this.jsplumbSetting)
      // 完成连线前的校验
      this.jsPlumb.bind('beforeDrop', evt => {
        const res = () => { } // 此处可以添加是否创建连接的校验, 返回 false 则不添加;
        return res
      })
 
      this.loadEasyFlow()
      // 会使整个jsPlumb立即重绘。
      this.jsPlumb.setSuspendDrawing(false, true)
    })
    this.initPanZoom()
  },
 // 加载流程图
  loadEasyFlow() {
    // 初始化节点
    for (let i = 0; i < this.data.nodeList.length; i++) {
      const node = this.data.nodeList[i]
      // 设置源点,可以拖出线连接其他节点
      this.jsPlumb.makeSource(node.id, this.jsplumbSourceOptions)
      // // 设置目标点,其他源点拖出的线可以连接该节点
      this.jsPlumb.makeTarget(node.id, this.jsplumbTargetOptions)
      // this.jsPlumb.draggable(node.id);
      this.draggableNode(node.id)
    }
 
    // 初始化连线
    this.jsPlumb.unbind(&#39;connection&#39;) // 取消连接事件
    console.log(this.data.lineList)
    for (let i = 0; i < this.data.lineList.length; i++) {
      const line = this.data.lineList[i]
      const conn = this.jsPlumb.connect(
        {
          source: line.sourceId,
          target: line.targetId,
          paintStyle: {
            stroke: line.cls.linkColor,
            strokeWidth: 2
            // strokeWidth: line.cls.linkThickness
          }
        },
        this.jsplumbConnectOptions
      )
      conn.setLabel({
        label: line.label,
        cssClass: `linkLabel ${line.id}`
      })
    }
    
  },

this.data 是需要渲染的数据,放在文章末尾,具体数据按照接口实际返回的来写

this.jsplumbSourceOptions 是jsplumb配置信息,新建一个文件编写,具体如下:

export const jsplumbSetting = {
  grid: [10, 10],
  // 动态锚点、位置自适应
  anchor: [&#39;TopCenter&#39;, &#39;RightMiddle&#39;, &#39;BottomCenter&#39;, &#39;LeftMiddle&#39;],
  Container: &#39;flow&#39;,
  // 连线的样式 StateMachine、Flowchart,有四种默认类型:Bezier(贝塞尔曲线),Straight(直线),Flowchart(流程图),State machine(状态机)
  Connector: [&#39;Flowchart&#39;, { cornerRadius: 5, alwaysRespectStubs: true, stub: 5 }],
  // 鼠标不能拖动删除线
  ConnectionsDetachable: false,
  // 删除线的时候节点不删除
  DeleteEndpointsOnDetach: false,
  // 连线的端点
  // Endpoint: ["Dot", {radius: 5}],
  Endpoint: [
    &#39;Rectangle&#39;,
    {
      height: 10,
      width: 10
    }
  ],
  // 线端点的样式
  EndpointStyle: {
    fill: &#39;rgba(255,255,255,0)&#39;,
    outlineWidth: 1
  },
  LogEnabled: false, // 是否打开jsPlumb的内部日志记录
  // 绘制线
  PaintStyle: {
    stroke: &#39;#409eff&#39;,
    strokeWidth: 2
  },
  HoverPaintStyle: { stroke: &#39;#409eff&#39; },
  // 绘制箭头
  Overlays: [
    [
      &#39;Arrow&#39;,
      {
        width: 8,
        length: 8,
        location: 1
      }
    ]
  ],
  RenderMode: &#39;svg&#39;
}
 
// jsplumb连接参数
export const jsplumbConnectOptions = {
  isSource: true,
  isTarget: true,
  // 动态锚点、提供了4个方向 Continuous、AutoDefault
  anchor: [&#39;TopCenter&#39;, &#39;RightMiddle&#39;, &#39;BottomCenter&#39;, &#39;LeftMiddle&#39;]
}
 
export const jsplumbSourceOptions = {
  filter: &#39;.node-anchor&#39;, // 触发连线的区域
  /* "span"表示标签,".className"表示类,"#id"表示元素id*/
  filterExclude: false,
  anchor: [&#39;TopCenter&#39;, &#39;RightMiddle&#39;, &#39;BottomCenter&#39;, &#39;LeftMiddle&#39;],
  allowLoopback: false
}
 
export const jsplumbTargetOptions = {
  filter: &#39;.node-anchor&#39;,
  /* "span"表示标签,".className"表示类,"#id"表示元素id*/
  filterExclude: false,
  anchor: [&#39;TopCenter&#39;, &#39;RightMiddle&#39;, &#39;BottomCenter&#39;, &#39;LeftMiddle&#39;],
  allowLoopback: false
}

 在父组件引入配置文件和方法

import { jsplumbSetting, jsplumbConnectOptions, jsplumbSourceOptions, jsplumbTargetOptions } from &#39;./config/commonConfig&#39;

接下来在上面说的初始化方法文件里面配置鼠标滚轮缩放插件的方法 this.initPanZoom():

// 鼠标滚动放大缩小
  initPanZoom() {
    const mainContainer = this.jsPlumb.getContainer()
    const mainContainerWrap = mainContainer.parentNode
    const pan = panzoom(mainContainer, {
      smoothScroll: false,
      bounds: true,
      // autocenter: true,
      zoomDoubleClickSpeed: 1,
      minZoom: 0.5,
      maxZoom: 2,
      // 设置滚动缩放的组合键,默认不需要组合键
      beforeWheel: (e) => {
        // console.log(e)
        // let shouldIgnore = !e.ctrlKey
        // return shouldIgnore
      },
      beforeMouseDown: function(e) {
        // allow mouse-down panning only if altKey is down. Otherwise - ignore
        var shouldIgnore = e.ctrlKey
        return shouldIgnore
      }
    })
    this.jsPlumb.mainContainerWrap = mainContainerWrap
    this.jsPlumb.pan = pan
    // 缩放时设置jsPlumb的缩放比率
    pan.on(&#39;zoom&#39;, e => {
      const { scale } = e.getTransform()
      this.jsPlumb.setZoom(scale)
    })
    pan.on(&#39;panend&#39;, (e) => {
 
    })
 
    // 平移时设置鼠标样式
    mainContainerWrap.style.cursor = &#39;grab&#39;
    mainContainerWrap.addEventListener(&#39;mousedown&#39;, function wrapMousedown() {
      this.style.cursor = &#39;grabbing&#39;
      mainContainerWrap.addEventListener(&#39;mouseout&#39;, function wrapMouseout() {
        this.style.cursor = &#39;grab&#39;
      })
    })
    mainContainerWrap.addEventListener(&#39;mouseup&#39;, function wrapMouseup() {
      this.style.cursor = &#39;grab&#39;
    })
  },

大功告成,data的数据放在这里,测试使用:

 {
  "FlowJson": {
      "nodeList": [
          {
              "type": "start",
              "nodeName": "已新建",
              "id": "start-HiXWf8wsAcrWXjAAXVWc6AQk00000001",
              "node_code": "已新建",
              "trigger_event": "",
              "branch_flow": "",
              "icon": "play-circle",
              "x": 175,
              "y": 60,
              "width": 50,
              "height": 50
          },
          {
              "type": "freedom",
              "nodeName": "待审批",
              "id": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
              "node_code": "待审批",
              "trigger_event": "",
              "branch_flow": "",
              "icon": "sync",
              "x": 330,
              "y": 160,
              "width": 50,
              "height": 120
          },
          {
              "type": "end",
              "nodeName": "已通过",
              "id": "end-JjRvtD5J2GIJKCn8MF7IYwxh00000999",
              "node_code": "已通过",
              "trigger_event": "",
              "branch_flow": "",
              "icon": "stop",
              "x": 330,
              "y": 360,
              "width": 50,
              "height": 50
          },
          {
              "type": "end",
              "nodeName": "审批拒绝",
              "id": "end-J1DMScH5YjSKyk0HeNkbt62F00010001",
              "node_code": "审批拒绝",
              "trigger_event": "",
              "branch_flow": "",
              "icon": "stop",
              "x": 500,
              "y": 350,
              "width": 50,
              "height": 50
          }
      ],
      "linkList": [
          {
              "type": "link",
              "id": "link-BpI6ZuX1bJywz5SEi3R5QaWoi7g3QiSr",
              "sourceId": "start-HiXWf8wsAcrWXjAAXVWc6AQk00000001",
              "targetId": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
              "label": "LINE000000",
              "role": [],
              "organize": [],
              "audit_role": [],
              "audit_organize": [],
              "audit_organize_same": "0",
              "audit_dealer_same": "0",
              "audit_dealers": [],
              "notice": "0",
              "plug": "",
              "pass_option": "pass",
              "row_par_json": "",
              "judge_fields": "",
              "auth_at": "",
              "auth_user": "",
              "auth_stat": "",
              "auth_mark": "",
              "cls": {
                  "linkType": "Flowchart",
                  "linkColor": "#008000",
                  "linkThickness": 4
              }
          },
          {
              "type": "link",
              "id": "link-5xJWzGlkIpUCsjmpfgesJxAOMHwkPlno",
              "sourceId": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
              "targetId": "end-J1DMScH5YjSKyk0HeNkbt62F00010001",
              "label": "LINE000001",
              "role": [],
              "organize": [],
              "audit_role": [
                  "PROJECT_SUPPORT_PLAN_CODE"
              ],
              "audit_organize": [],
              "audit_organize_same": "0",
              "audit_dealer_same": "0",
              "audit_dealers": [],
              "notice": "0",
              "plug": "",
              "pass_option": "reject",
              "row_par_json": "",
              "judge_fields": "",
              "auth_at": "",
              "auth_user": "",
              "auth_stat": "",
              "auth_mark": "",
              "cls": {
                  "linkType": "Flowchart",
                  "linkColor": "#808080",
                  "linkThickness": 1
              }
          },
          {
              "type": "link",
              "id": "link-g05V3usXa86wAtpcMkvGzybdBlpasMjU",
              "sourceId": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
              "targetId": "end-JjRvtD5J2GIJKCn8MF7IYwxh00000999",
              "label": "LINE000002",
              "role": [],
              "organize": [],
              "audit_role": [
                  "PROJECT_SUPPORT_PLAN_CODE"
              ],
              "audit_organize": [],
              "audit_organize_same": "0",
              "audit_dealer_same": "0",
              "audit_dealers": [],
              "notice": "0",
              "plug": "",
              "pass_option": "approve",
              "row_par_json": "",
              "judge_fields": "",
              "auth_at": "",
              "auth_user": "",
              "auth_stat": "",
              "auth_mark": "",
              "cls": {
                  "linkType": "Flowchart",
                  "linkColor": "#808080",
                  "linkThickness": 1
              }
          }
      ]
  }
  
}

关于“vue+jsplumb实现工作流程图的方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程笔记行业资讯频道,小编每天都会为大家更新不同的知识点。


推荐阅读
  • vue使用
    关键词: ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 本文介绍了一些Java开发项目管理工具及其配置教程,包括团队协同工具worktil,版本管理工具GitLab,自动化构建工具Jenkins,项目管理工具Maven和Maven私服Nexus,以及Mybatis的安装和代码自动生成工具。提供了相关链接供读者参考。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • 本文介绍了Python字典视图对象的示例和用法。通过对示例代码的解释,展示了字典视图对象的基本操作和特点。字典视图对象可以通过迭代或转换为列表来获取字典的键或值。同时,字典视图对象也是动态的,可以反映字典的变化。通过学习字典视图对象的用法,可以更好地理解和处理字典数据。 ... [详细]
  • 第8章 使用外部和内部链接
    8.1使用web地址LearnAboutafricanelephants. ... [详细]
  • 本文介绍了一种解析GRE报文长度的方法,通过分析GRE报文头中的标志位来计算报文长度。具体实现步骤包括获取GRE报文头指针、提取标志位、计算报文长度等。该方法可以帮助用户准确地获取GRE报文的长度信息。 ... [详细]
  • 微信民众号商城/小顺序商城开源项目介绍及使用教程
    本文介绍了一个基于WeiPHP5.0开发的微信民众号商城/小顺序商城的开源项目,包括前端和后端的目录结构,以及所使用的技术栈。同时提供了项目的运行和打包方法,并分享了一些调试和开发经验。最后还附上了在线预览和GitHub商城源码的链接,以及加入前端交流QQ群的方式。 ... [详细]
  • loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ... [详细]
author-avatar
popou
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有