基于 jsPlumb 的流程图编辑器的实现 (二,连接线的操作)

连接线支持单击选中,backspace 和 delete 可删除;双击可以为连接线添加 label。

完整代码:

        /**
         * 单击删除连线
         *
         */
        clickLine:function(){
            var that = this;
            jsPlumb.bind("click", function (conn, originalEvent) {
                if(!isNew){
                      return false;           
                }  
                // 取消上次延时未执行的方法 
                clearTimeout(lineTimes); 
                //执行延时 
                lineTimes = setTimeout(function(){
                    jsPlumb.repaintEverything();
                    var target = originalEvent.toElement;
                    var isOuter = target.getAttribute('class') ? true : false;
                    if(isOuter){
                        return false;
                    }
                    target.setAttribute('stroke','#409eff');
                    $(document).keydown(function(event){
                        event=event||window.event
                        if(event.keyCode==8 || event.keyCode==46){  //8--backspace;46--delete
                            jsPlumb.detach(conn);
                            return false;                               
                        }  
                    })                                   
                },300);           
            });
            return this;
        },
        /**
         * 双击给线添加label
         *
         */
        dblclickLine:function(){
            var that = this;
            jsPlumb.bind("dblclick", function (conn, originalEvent) {
                if(!isNew){
                    return false;     
                }
                // 取消上次延时未执行的方法 
                clearTimeout(lineTimes ); 
                //如果连接线有label,则获取焦点,如果没有,则添加。                
                var labelInfo = that.lineIsHasLabel(conn);
                if(labelInfo.isHasLabel){
                    labelInfo.currentLabel.removeClass('label-blur').addClass('label-focus');
                        var oldText = labelInfo.currentLabel.children('.label-text').html();
                        var inputDom = $('<input type="text" class="label-input" value="'+oldText+'"/>')
                        setTimeout(function(){
                            inputDom.focus();
                        },50)
                        labelInfo.currentLabel.append(inputDom)
                    return false;
                }
                _index++;  
                var left =  parseInt(originalEvent.clientX-container.offset().left)
                var top =  parseInt(originalEvent.clientY-container.offset().top)
                var id = "label"+_index;
                var labelDom = $('<div class="line-label label-focus" id="' + id + '" data-path="'+conn.id+'"><span class="label-text"></span><input type="text" class="label-input"/></div>')
                labelDom.css("left", left).css("top", top);
                var input = labelDom.children('input.label-input');
                setTimeout(function(){
                    input.focus();
                },50)
                container.append(labelDom);

                labelDom.keydown(function (event) {
                    event=event||window.event;
                    if(event.keyCode==13){
                        var text = input.val();
                        if(!text){
                            labelDom.remove();
                            return false;
                        }
                        labelDom.children('span').html(input.val()); 
                        input.remove();
                        labelDom.removeClass('label-focus').addClass('label-blur');
                        return false;
                    }                              
                });

                // label 可以拖动
                jsPlumb.draggable(id);
                labelDom.draggable({ containment: "parent" });    
            });
            return this;
        },

1.单击删除连接线

jsPlumb.detach(); 可以删除连接的线。

思路:jsPlumb 允许添加事件。这里添加点击事件,之后给 document 添加键盘事件,按下 Backspace 和 Delete 时,删除连线。

            jsPlumb.bind("click", function (conn, originalEvent) {
                if(!isNew){
                      return false;           
                }  
                $(document).keydown(function(event){
                        event=event||window.event
                        if(event.keyCode==8 || event.keyCode==46){  //8--backspace;46--delete
                            jsPlumb.detach(conn);
                            return false;                               
                        }  
                    })           
            });

2.双击添加 Label

思路:双击连线时,在画布中添加 div ,并且根据鼠标点击的位置,设置div 的位置。div 中包含input 输入框,可直接编辑。同时,我这里做了一个限定,即一条线只能添加一个label ,因此在添加之前,需要判断,连线是否有label,有则使原有的处于选中状态,没有则添加。

                //如果连接线有lebel,则获取焦点,如果没有,则添加。                
                var labelInfo = that.lineIsHasLabel(conn);
                if(labelInfo.isHasLabel){
                    labelInfo.currentLabel.removeClass('label-blur').addClass('label-focus');
                        var oldText = labelInfo.currentLabel.children('.label-text').html();
                        var inputDom = $('<input type="text" class="label-input" value="'+oldText+'"/>')
                        setTimeout(function(){
                            inputDom.focus();
                        },50)
                        labelInfo.currentLabel.append(inputDom)
                    return false;
                }
                _index++;  
                var left =  parseInt(originalEvent.clientX-container.offset().left)
                var top =  parseInt(originalEvent.clientY-container.offset().top)
                var id = that.judgeId("label",_index);
                var labelDom = $('<div class="line-label label-focus" id="' + id + '" data-path="'+conn.id+'"><span class="label-text"></span><input type="text" class="label-input"/></div>')
                labelDom.css("left", left).css("top", top);
                var input = labelDom.children('input.label-input');
                setTimeout(function(){
                    input.focus();
                },50)
                container.append(labelDom);

                labelDom.keydown(function (event) {
                    event=event||window.event;
                    if(event.keyCode==13){
                        var text = input.val();
                        if(!text){
                            labelDom.remove();
                            return false;
                        }
                        labelDom.children('span').html(input.val()); 
                        input.remove();
                        labelDom.removeClass('label-focus').addClass('label-blur');
                        return false;
                    }                              
                });

同时,label 也是可以拖动的。

 // label 可以拖动
jsPlumb.draggable(id);
labelDom.draggable({ containment: "parent" });

判断连线是否有 label 的方法:

        /**
         * 判断连接线,是否有label
         * @params conn Object 连线对象
         * @return  Object labelInfo
         */
        lineIsHasLabel:function(conn){
            var pathId = conn.id;
            var lebelDoms = $('.line-label');
            var isHasLabel = false;
            var currentLabel;
            for(var i = 0;i<lebelDoms.length;i++){
                var item = lebelDoms.eq(i);
                isHasLabel = item.data('path') == pathId ? true : false;
                if(isHasLabel){
                    currentLabel = item;
                    break;
                }
            }
            return {
                isHasLabel:isHasLabel,
                currentLabel:currentLabel
            };
        },

3.label 的操作

label 的操作和节点操作类似,也是单击获取焦点,可以删除,双击可以改变内容,同时支持拖动改变大小。

        /**
         * label 事件
         *
         */
        labelClick:function(id){
            var currentDom =  $('#'+id);
            // 单击选中,可删除
            currentDom.click(function(){
                clearTimeout(labelTimes);
                labelTimes = setTimeout(function(){ 
                    container.children('.line-label').removeClass('label-focus').addClass('label-blur');
                    currentDom.addClass('label-focus').removeClass('label-blur');
                    var input = $("<input type='text' class='hide-input'/>");
                    setTimeout(function(){
                        input.focus();
                    },50)
                    currentDom.append(input);
                    currentDom.keydown(function (event) {
                        event=event||window.event
                        if(event.keyCode==8 || event.keyCode==46){  //8--backspace;46--delete
                            currentDom.remove();
                            return false;                               
                        }              
                    });
                },300);
            })
            // 双击添加文字
            currentDom.dblclick(function () {
                // 取消上次延时未执行的方法 
                clearTimeout(labelTimes );
                container.children('.line-label').removeClass('label-focus').addClass('label-blur');
                currentDom.addClass('label-focus').removeClass('label-blur');
                var text = currentDom.children('span').text().replace(/(^\s*)|(\s*$)/g, "") || '';
                currentDom.children('span').html("");
                var input = $("<input type='text' class='label-input' value='" + text + "'/>");
                setTimeout(function(){
                    input.focus();
                },50)
                currentDom.append(input);
                currentDom.keydown(function (event) {
                    if(event.keyCode==13){
                        currentDom.children('span').html(currentDom.children("input.label-input").val()); 
                        currentDom.children("input.label-input").remove();
                        currentDom.removeClass('label-focus').addClass('label-blur');
                        return false;                               
                    }              
                });
            });
            // 拖拽改变大小
            currentDom.resizable({
                autoHide: true ,
                containment: "parent",
                minHeight: 40,
                minWidth:70,
            })
        },

但是这里需要注意的是,因为有了 label ,连线在删除的时候,如果此连线有 label ,则也需要把 label 删除掉;节点在删除时,也是如此。

删除连线时,删除 label

 var labelInfo = that.lineIsHasLabel(conn);
 if(labelInfo.isHasLabel){
      labelInfo.currentLabel.remove();
 }

删除节点时,删除 label

                           //如果连线有 label ,也得删除
                            var labelsDom = $('.line-label');
                            var paths = jsPlumb.getAllConnections();
                            if(labelsDom.length == 0){
                                return false;
                            }
                            for(var i=0;i<labelsDom.length;i++){
                                var currentLabelDom = labelsDom.eq(i);
                                var pathId = currentLabelDom.data('path');
                                var pathIsHave = false;
                                for(var j=0;j<paths.length;j++){
                                    var currentPath = paths[j];
                                    if(currentPath.id == pathId){
                                        pathIsHave = true;
                                        break;
                                    }
                                }
                                if(!pathIsHave){
                                    currentLabelDom.remove();
                                    break;
                                }
                            }

 

 

项目地址:https://github.com/smile1828/demo-jsPlumb

基于 jsPlumb 的流程图编辑器的实现 (一,节点的操作)

基于 jsPlumb 的流程图编辑器的实现 (三,document的操作)

基于 jsPlumb 的流程图编辑器的实现 (四,按钮的操作)

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JSPlumb是一个流程图库,可以帮助实现各种流程图的绘制和交互。下面我将以一个简单的例子来说明如何使用JSPlumb实现流程图。 首先,需要引入JSPlumb的库文件: ```html <script src="jsplumb.min.js"></script> ``` 接下来,创建一个容器来放置流程图的元素,例如: ```html <div id="flowchart"></div> ``` 然后,初始化JSPlumb: ```javascript jsPlumb.ready(function() { // 创建一个连接实例 var instance = jsPlumb.getInstance(); // 设置连接线样式 var connectorStyle = { strokeWidth: 2, stroke: '#4178be', joinstyle: 'round', outlineStroke: 'white', outlineWidth: 2 }; // 设置端点的样式 var endpointStyle = { endpoint: 'Dot', paintStyle: { fill: '#4178be', radius: 4 }, isSource: true, connectorStyle: connectorStyle, isTarget: true, connectorHoverStyle: connectorStyle, hoverPaintStyle: { stroke: '#1e8151', strokeWidth: 3 } }; // 在容器中添加节点 var node1 = instance.addEndpoint('flowchart', { anchor: 'Right', endpoint: endpointStyle }); var node2 = instance.addEndpoint('flowchart', { anchor: 'Left', endpoint: endpointStyle }); // 连接两个节点 instance.connect({ source: node1, target: node2, paintStyle: connectorStyle }); }); ``` 在上面的代码中,首先创建了一个连接实例,然后设置了连接线和端点的样式。接下来,在容器中添加了两个节点,并使用`addEndpoint`方法来设置节点的锚点和端点的样式。最后,使用`connect`方法来连接两个节点。 通过以上的步骤,就可以使用JSPlumb实现一个简单的流程图。当然,JSPlumb还有更多的功能和选项可以进行配置,可以根据实际需求进行调整和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值