jsplum使用(一)

jsplumb的使用

功能:主要用于绘制图表,常见于工作流程图等的绘制

下面讲一下它的具体用法,会实现一个小demo

整体页面

左侧为节点配置 右侧为画布

首先代码结构如下:


<div class="box-content">
    <el-row>
        <el-col :span="6">
            <div class="source">
                <node-config
                    @addNode="addNode"></node-config>
            </div>
        </el-col>
        <el-col :span="18">
          <div id="efContainer" ref="efContainer" class="container">
              <template v-for="node in nodeList">
                  <node-item
                      :node="node"
                      @changeNodeSite="changeNodeSite">
                  </node-item>
              </template>
          </div>
        </el-col>
    </el-row>
</div>

一、左侧节点拖拽实现

1、使用vuedraggable

代码如下:

nodeConfig.vue里的代码

data = [
    {
        id: 1,
        type: 'red',
        name: '功能一'
    },
    {
        id: 2,
        type: 'green',
        name: '功能二'
    },
    {
        id: 3,
        type: 'blue',
        name: '功能三'
    }
]
<draggable @end="end" @start="move" v-model="data">
    <transition-group>
        <li
            v-for="subMenu in data"
            :style="{ borderColor: subMenu.type }"
            class="menu-box"
            :key="subMenu.id"
            :type="subMenu.type">
            {{subMenu.name}}
        </li>
    </transition-group>
</draggable>

这时你会发现左侧配置栏的节点已经可以拖动了,但还不能拖到画布里面

二、将节点拖入画布里面

这里将用到vuedraggable的两个事件start和end

代码如下:

开始: 找到拖动的节点

move(evt, a, b, c) {
    var type = evt.item.attributes.type.nodeValue
    this.nodeMenu = this.data.find(item => item.type === type)
}

结束: 在画布中添加数据,并计算他们的位置

const mousePosition = {
    left: -1,
    top: -1
}

end(evt, e) {
    this.$emit('addNode', evt, this.nodeMenu, mousePosition)
}

主页面代码:

addNode (evt, nodeMenu) {
    console.log(evt.originalEvent)
    // 相对父页面的坐标
    const screenX = evt.originalEvent.clientX
    const screenY = evt.originalEvent.clientY
    const ef = this.$refs.efContainer
    const efRect = ef.getBoundingClientRect()
    console.log(efRect)
    let left = screenX
    let top = screenY
    if (left < efRect.x || left > efRect.width + efRect.x || top < efRect.y || efRect.y > efRect.y + efRect.height) {
        this.$message.error('请把节点拖入到画布中')
        return
    }
    // 相对画布的坐标
    left = left - efRect.x
    top = top - efRect.y
    // 左上角的坐标
    left -= 75
    top -= 30
    const nodeId = this.getUUID()
    // 动态生成名字
    const origName = nodeMenu.name
    let nodeName = origName
    let index = 1
    while (index < 10000) {
        let repeat = false
        for (var i = 0; i < this.nodeList.length; i++) {
            let node = this.nodeList[i]
            if (node.name === nodeName) {
                nodeName = origName + index
                repeat = true
            }
        }
        if (repeat) {
            index++
            continue
        }
        break
    }
    const node = {
        id: nodeId,
        name: nodeName,
        type: nodeMenu.type,
        left: left + 'px',
        top: top + 'px'
    }
    this.nodeList.push(node)
}

数据加入nodeList, 在画布中展示即可

至此,前期工作已经完成,可以将节点拖拽之画布了

原文地址:https://www.cnblogs.com/wangyingblock/p/14786530.html