Vue 使用 JSPlumb 绘制推拽流程图

5,550 阅读2分钟

Vue 使用 JSPlumb 绘制推拽流程图

demo 效果图

效果图

JSPlumb

jsPlumb提供了一种可视化的连接web元素的方法,在浏览器种使用SVG,旧的版本(IE8↓)使用VML。

Setup

  • NPM 安装 jquery jquery-ui jsplumb
npm install jquery jquery-ui jsplumb --save
import $ from "jquery"
// 使用 jqueryUi resize  (css记得引入)
import "jquery-ui/themes/base/resizable.css"
import "jquery-ui/ui/widgets/resizable"
// drag drop 功能
import "jquery-ui/ui/widgets/draggable"
import "jquery-ui/ui/widgets/droppable"
// jsPlumb
import { jsPlumb } from "jsplumb"
  • 多个jsPlumb 实例,注意在 mounted 生命周期内实例化
  • this Vue

let plumbIns = jsPlumb.getInstance({ Container: "diagramContainer" })

this.plumbIns = plumbIns

  • 导入默认配置

plumbIns.importDefaults({ ConnectionsDetachable: false //默认情况下,垂直连接将可通过鼠标分离 })

  • 查阅Wiki写入默认配置
export const visoConfig = {}

// 基本连接线样式
visoConfig.connectorPaintStyle = {
  stroke: "#2E79F9",
  strokeWidth: 1,
  lineWidth: 2
}

// 鼠标悬浮在连接线上的样式
visoConfig.connectorHoverStyle = {
  strokeWidth: 2,
  strokeStyle: "#FFCB48"
}

visoConfig.baseStyle = {
  endpoint: [
    "Dot",
    {
      radius: 6,
      cssClass: "endpointcssClass"
    }
  ], // 端点的形状
  connectorStyle: visoConfig.connectorPaintStyle, // 连接线的颜色,大小样式
  connectorHoverStyle: visoConfig.connectorHoverStyle,
  paintStyle: {
    stroke: "#2E79F9",
    fill: "#ffffff",
    radius: 6,
    strokeWidth: 2
  }, // 端点的颜色样式  rgba(46, 121, 249,0.3)  #2E79F9
  hoverPaintStyle: {
    strokeWidth: 4
  },
  isSource: true, // 是否可以拖动(作为连线起点)
  connector: [
    "Flowchart",
    {
      gap: 0,
      coenerRadius: 0,
      alwaysRespectStubs: true,
      midpoint: 0.5
    }
  ], // 连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]
  isTarget: true, // 是否可以放置(连线终点)
  maxConnections: -1, // 设置连接点最多可以连接几条线
  connectorOverlays: [
    [
      "Arrow",
      {
        location: 1,
        visible: true,
        width: 11,
        length: 11,
        direction: 1,
        id: "arrow_forwards"
      }
    ],
    [
      "Label",
      {
        location: 0.5,
        id: "arrowLabel",
        cssClass: "arrowLabel",
        events: {
          mouseover: function() {}
        }
      }
    ]
  ]
}
visoConfig.baseArchors = ["RightMiddle", "LeftMiddle"]

获取基础配置

function getBaseNodeConfig(){
    return Object.assign({}, visoConfig.baseStyle)
}

让元素可以拖拽

  • containment 限制可拖拽的范围
plumbIns.draggable(id, {
    containment: "diagramContainer"
})

为元素添加端点EndPoint

  • maxConnections 最大连接数
  • isSource 只可以被连接,不能连接对方
  • initDimensionNode只有一个端点的元素
  • initRootNode 拥有4个可链接的元素
function initDimensionNode(id) {
  let config = this.getBaseNodeConfig()
  config.isSource = false
  config.maxConnections = 1
  this.plumbIns.addEndpoint(
    id,
    {
      anchors: "Top",
      uuid: id + "-top"
    },
    config
  )
}
function initRootNode(id){
    let config = this.getBaseNodeConfig()
      config.isTarget = false
      config.maxConnections = 4
      this.plumbIns.addEndpoint(
        id,
        {
          anchors: "Bottom",
          uuid: id + "-bottom"
        },
        config
      )
      this.plumbIns.addEndpoint(
        id,
        {
          anchors: "Top",
          uuid: id + "-top"
        },
        config
      )
      this.plumbIns.addEndpoint(
        id,
        {
          anchors: "Right",
          uuid: id + "-right"
        },
        config
      )
      this.plumbIns.addEndpoint(
        id,
        {
          anchors: "Left",
          uuid: id + "-left"
        },
        config
      )
}

双击删除连接

  • error 在vue种调用 detach 报错 is not function
plumbIns.bind("dblclick", conn => {
    if (window.prompt("确定删除所点击的链接吗? 输入1确定") === "1") {
        plumbIns.deleteConnection(conn)
    }
})

修改链接种的label

  • 利用css样式,切换label的class名称,更换连接的label显示
plumbIns.bind("connection", connInfo => {
    // 展示弹窗 选择关系
    this.showRelationModal()
    // console.log(connInfo.connection.getOverlay("arrowLabel"))
    connInfo.connection.getOverlay("arrowLabel").addClass("arrowcen")
})

结语

且学且珍惜