使用jsplumb时遇到的一些问题及处理办法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzl19870309/article/details/89032109

最近在使用jsplumb做了一个流程图绘制的实现,因为本身不是搞前端出身,布局有点丑,不过大致达到了自己想要的功能效果,具体效果如下:

期间遇到一些问题和自己想要的一些效果,现在记录下来和大家分享一下:

1、监听画图区域组件的拖拽事件,以获取组件的位置,注册stop方法,从event中获取组件ID,从ui获取事件的位置

jsPlumb.draggable(id, {
            containment: 'parent',
            stop:function (event,ui) {
                let dragNodeId = event.target.id;
                let dragNode = flowData.stepMap[dragNodeId];
                dragNode.top = ui.position.top;
                dragNode.left = ui.position.left;
                updateFlag = true;
            }
        })

2、绘制连接线,这里注册了两个监听事件‘beforeDrop’和‘connection’ 。beforeDrop事件用于做绘制前检查,connenction用于监听,连接线连上后的动作,添加了connection监听事件后,发现初始化创建连接线的时候也会触发,这里可以加一个标识,初始化和非初始化时执行不同的方法。

//我这里绑定connection事件主要是为了获取jsplumb自动生成的连接线ID
//info是连接线对象
//flowData.stepMap保存的是我要提交到后来的组件信息,其中的targetMap保存了连接线的信息,即下一个节点的信息
//以下代码中有部分是业务代码,尽供参考
jsPlumb.bind("connection", function (info) {
            let sourceId = info.sourceId;
            let connId = info.connection.id;
            let nodeSource = flowData.stepMap[sourceId];
            let targets = nodeSource.targetMap;

            let index = 0;
            if (targets) {
                for (let i = 0; i < targets.length; i++) {
                    let target = targets[i];
                    //初始化的时候target还没有赋值,或者已经赋值,该连接线已存在,则直接退出
                    if (!target.connId || target.connId === connId) {
                        return;
                    }
                    let temp = parseInt(target.id.substr(target.id.length - 1, 1));
                    if (temp >= index) {
                        index = temp + 1;
                    }
                }
            } else {
                flowData.stepMap[info.sourceId].targetMap = [];
            }       

            flowData.stepMap[info.sourceId].targetMap.push({
                "id" : "target" + index,
                "value" : info.targetId,
                "connId" :connId
            });

        });

3、删除连接线,使用  jsPlumb.detach() 方法,参数是connection对象,前提是先获取connction对象,双击连接线 可以conn对象

jsPlumb.bind('dblclick', function (conn, originalEvent) {
    if (confirm('确定删除所点击的链接吗?')) {
        jsPlumb.detach(editConn);
    }
});

4、在连接线上添加文字

//conn为连接线对象 ,desc文字的内容
conn.addOverlay(['Custom', {
     create: function (component) {
          return $('<span style="background-color: white; padding: 5px;">' + desc + '</span>');
     },
     location: 0.5   //文字的位置
 }]);

5、双击节点可以编辑文字(解决办法是网上查找的)

//areaId为整个画图区域
$(areaId).on('dblclick',function (event) {

    //判断双击事件是否在节点组件上 
    if (event.target.dataset.type === 'action') {
          let element = event.target;
          let oldhtml = $.trim(element.innerHTML);
          //如果已经双击过,内容已经存在input,不做任何操作
          if(oldhtml.indexOf('type="text"') > 0){
                return;
          }
          //创建新的input元素
          let newobj = document.createElement('input');
          //为新增元素添加类型
          newobj.type = 'text';
          //为新增元素添加value值
          newobj.value = oldhtml;
          //为新增元素添加光标离开事件
          newobj.onblur = function() {
             //当触发时判断新增元素值是否为空,为空则不修改,并返回原有值
             if(this.value && this.value.trim()!==""){
                 element.innerHTML = this.value === oldhtml ? oldhtml : this.value;
                 let stepNode = flowData.stepMap[_deNode.id];
                 stepNode.desc = element.innerHTML;
                 jsPlumb.setSuspendDrawing(false,true);  //文字修改后,节点的宽度可能会改变,这里设置进行重绘
             } else {
                 element.innerHTML = oldhtml;
             }
          };
          //设置该标签的子节点为空
          element.innerHTML = '';
          //添加该标签的子节点,input对象
          element.appendChild(newobj);
          //设置选择文本的内容或设置光标位置(两个参数:start,end;start为开始位置,end为结束位置;如果开始位置和结束位置相同则就是光标位置)
          newobj.setSelectionRange(0, oldhtml.length);
          //设置获得光标
          newobj.focus();
      }
});

6、删除节点,执行remove方法后,及诶但和相关联的连接线都会一并被删除

//id为节点的 ID,即添加节点时设置的ID
//执行remove方法后,节点和相关联的连接线都会一并删除
function emptyNode (id) {
    jsPlumb.remove(id);

}

7、添加节点,添加节点需要几个步骤:设置节点可拖动、添加入口点、添加出口点

 function initSetNode (template, position) {
        addDraggable(position.id);
        setEnterPoint(position.id);
        setExitPoint(position.id);
    }


// 让元素可拖动
    function addDraggable (id) {
        jsPlumb.draggable(id, {
            containment: 'parent',
            stop:function (event,ui) {
                let dragNodeId = event.target.id;
                let dragNode = flowData.stepMap[dragNodeId];
                dragNode.top = ui.position.top;
                dragNode.left = ui.position.left;
                updateFlag = true;
            }
        })
    }

// 设置入口点
    function setEnterPoint (id) {
        let config = getBaseNodeConfig();
        config.isSource = true;
        config.maxConnections = -1;
        config.allowLoopback = false ;//禁止回环
        jsPlumb.addEndpoint(id, {
            // anchors: ['Top'],
            anchor:'AutoDefault',
            uuid: id + '-in'
        }, config)
    }

    // 设置出口点
    function setExitPoint (id, position) {
        let config = getBaseNodeConfig();
        config.isTarget = true;
        config.maxConnections = -1;
        config.allowLoopback = false ;//禁止回环
        jsPlumb.addEndpoint(id, {
            // anchors: position || 'Bottom',
            anchor:'AutoDefault',
            uuid: id + '-out'
        }, config)
    }

不和后台交互的源码:

github下载链接:https://github.com/wongxl/jsplumb-flow-editor

csdn下载链接:https://download.csdn.net/download/wzl19870309/11103445

猜你喜欢

转载自blog.csdn.net/wzl19870309/article/details/89032109