Javascript d3.js中的拖放操作期间不会触发鼠标悬停事件

Javascript d3.js中的拖放操作期间不会触发鼠标悬停事件,javascript,d3.js,Javascript,D3.js,我试图在另一个圆上拖动一个圆来连接两条路径。问题是,当我将一个圆(c2)拖到另一个圆(c1)上时,如果圆c1是在圆c2之前创建的,则不会触发c1鼠标悬停事件 你能帮我吗 谢谢! 以前 我添加了一些代码,如果用户正在移动圆圈,如果他不打算创建一个新的圆圈,我希望这会有所帮助 var closedRoad = true; var width = 960, height = 500; var points = d3.range(1, 5).map(funct

我试图在另一个圆上拖动一个圆来连接两条路径。问题是,当我将一个圆(c2)拖到另一个圆(c1)上时,如果圆c1是在圆c2之前创建的,则不会触发c1鼠标悬停事件

你能帮我吗

谢谢!
以前

我添加了一些代码,如果用户正在移动圆圈,如果他不打算创建一个新的圆圈,我希望这会有所帮助

    var closedRoad = true;
    var width = 960,
        height = 500;

    var points = d3.range(1, 5).map(function(i) {
        return [i * width / 5, 50 + Math.random() * (height - 100)];
    });

    var points1 = d3.range(1, 5).map(function(i) {
        return [i * width / 5, 50 + Math.random() * (height - 100)];
    });

    var points2 = d3.range(1, 5).map(function(i) {
        return [i * width / 5, 50 + Math.random() * (height - 100)];
    });

    var count = 0;
    var ways =  [];

    var currentWay = null;

    var selected = null;

    var line = d3.svg.line();

    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

    var rect = svg.append("rect")
    .attr("width", width)
    .attr("height", height);

    ways.forEach(function(way, i) {
        svg.append("path")
        .datum(way)
        .attr("id", "p" + way.id)
        .attr("class", "line")
        .call(redraw);
    });

    d3.select(window)
    .on("keydown", keydown)
    //.on("mousemove", mousemove)
    .on("mouseup", mouseup)
    .on("mousedown", mousedown)
    .on("dblclick", dblclick);

    function redraw(way) {
        way.attr("d", function(d) { return line(d.pts); });

        var circle = svg.selectAll(".way" + way.data()[0].id)
        .data(way.data()[0].pts, function(d) { return d; });
        circle.enter().append("circle")
        .attr("class", "way" + way.data()[0].id)
        .attr("r", 1e-6)
        .on("mousedown", function(d) { 
            if (closedRoad) {
                currentWay = way.data()[0];
                selected = d; 

                if (d3.event) {
                    d3.event.preventDefault();
                    d3.event.stopPropagation();
                }
            }
        })
        .on("mouseover", function() { d3.select(d3.event.target).classed("highlight", true); })
        .on("mouseout", function() { d3.select(d3.event.target).classed("highlight", false); })
        .transition()
        .duration(750)
        .ease("elastic")
        .attr("r", 6.5);

        circle
        .attr("cx", function(d) { return d[0]; })
        .attr("cy", function(d) { return d[1]; });

        ////
        var drag = d3.behavior.drag();
        drag.on("dragstart", function(d) {
            console.log('START');
        })
        .on("drag", function(d) {
            console.log('MOVE');

            var m = d3.mouse(svg.node());
            d[0] = Math.max(0, Math.min(width, m[0]));
            d[1] = Math.max(0, Math.min(height, m[1]));

            //redraw(way);
            redrawAll();
        })
        .on("dragend", function(d) {
            console.log('END');
        });

        circle.call(drag);
        ////

        circle.exit().remove();

        /*   if (d3.event) {
            d3.event.preventDefault();
            d3.event.stopPropagation();
        }*/
    }

    function dblclick() {
        currentWay.pts.pop();
        //redraw(svg.select("#p" + currentWay.id));
        redrawAll();

        closedRoad = true;
    }

    function mousedown() {
        start = event.pageX + event.pageY;
        console.log(start);

    }
    function mouseup(){
        if(start >= (event.pageX + event.pageY) - 10 && start <= (event.pageX + event.pageY) + 10){
        if (closedRoad) {
            currentWay = { id: ++count, pts: [] };
            ways.push(currentWay); 

            svg.append("path")
            .datum(currentWay)
            .attr("id", "p" + currentWay.id)
            .attr("class", "line")
            .on("mouseover", function() { 
                d3.select(d3.event.target).classed("highlight", true); 
            })
            .on("mouseout", function() { d3.select(d3.event.target).classed("highlight", false); })
            .call(redraw);

            closedRoad = false;
        }

        currentWay.pts.push(selected = d3.mouse(svg.node()));
        //redraw(svg.select("#p" + currentWay.id));
        redrawAll();
        }else{

        closedRoad = true;
        }
    }
    function redrawAll() {
        ways.forEach(function(way, i) {
            redraw(svg.select("#p" + way.id));
        });
    }

    function mousemove() {

    }


    function keydown() {
        if (!selected) return;
        switch (d3.event.keyCode) {
            case 8: // backspace
            case 46: { // delete
                var i = currentWay.pts.indexOf(selected);
                currentWay.pts.splice(i, 1);
                selected = currentWay.pts.length ? currentWay.pts[i > 0 ? i - 1 : 0] : null;
                redraw(svg.select("#p" + currentWay.id));
                break;
            }
        }
    }
var closedRoad=true;
可变宽度=960,
高度=500;
变量点=d3.范围(1,5).映射(函数(i){
返回[i*宽度/5,50+数学随机()*(高度-100)];
});
变量点1=d3.范围(1,5).映射(函数(i){
返回[i*宽度/5,50+数学随机()*(高度-100)];
});
var points2=d3.范围(1,5).映射(函数(i){
返回[i*宽度/5,50+数学随机()*(高度-100)];
});
var计数=0;
var方法=[];
var currentWay=null;
选择的var=null;
var line=d3.svg.line();
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var rect=svg.append(“rect”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
方法。forEach(函数(方法,i){
追加(“路径”)
.基准(道路)
.attr(“id”,“p”+路径id)
.attr(“类”、“行”)
.呼叫(重画);
});
d3.选择(窗口)
.on(“按键向下”,按键向下)
//.on(“mousemove”,mousemove)
.on(“mouseup”,mouseup)
.on(“mousedown”,mousedown)
.on(“dblclick”,dblclick);
函数重绘(方式){
attr(“d”,函数(d){returnline(d.pts);});
var circle=svg.selectAll(“.way”+way.data()[0].id)
.data(way.data()[0].pts,函数(d){return d;});
circle.enter().append(“circle”)
.attr(“类”、“方式”+way.data()[0].id)
.attr(“r”,1e-6)
.on(“mousedown”,函数(d){
if(closedRoad){
currentWay=way.data()[0];
所选=d;
if(d3.事件){
d3.event.preventDefault();
d3.event.stopPropagation();
}
}
})
.on(“mouseover”,function(){d3.select(d3.event.target).classed(“highlight”,true);})
.on(“mouseout”,function(){d3.select(d3.event.target).classed(“highlight”,false);})
.transition()
.持续时间(750)
.ease(“弹性”)
.attr(“r”,6.5);
圆圈
.attr(“cx”,函数(d){返回d[0];})
.attr(“cy”,函数(d){返回d[1];});
////
var drag=d3.behavior.drag();
drag.on(“dragstart”,函数(d){
console.log('START');
})
.开启(“拖动”,功能(d){
console.log('MOVE');
var m=d3.mouse(svg.node());
d[0]=数学最大值(0,数学最小值(宽度,m[0]);
d[1]=数学最大值(0,数学最小值(高度,m[1]);
//重画(道路);
重画();
})
.on(“dragend”,功能(d){
console.log('END');
});
圆圈。呼叫(拖动);
////
circle.exit().remove();
/*if(d3.事件){
d3.event.preventDefault();
d3.event.stopPropagation();
}*/
}
函数dblclick(){
currentWay.pts.pop();
//重画(svg.select(“#p”+currentWay.id));
重画();
closedRoad=true;
}
函数mousedown(){
开始=event.pageX+event.pageY;
console.log(启动);
}
函数mouseup(){
如果(开始>=(event.pageX+event.pageY)-10&&start 0?i-1:0]:空;
重画(svg.select(“#p”+currentWay.id));
打破
}
}
}

问题很简单,当两个元素相互重叠时,“mouseover”事件只会在最顶端的元素上触发。无论您是否处理最顶端元素的鼠标事件,这都是正确的。更改该行为将需要大量的变通工作,而这些工作都不需要这些都是理想的

一些可能的解决办法:

  • 在拖动功能中,反复检查此处是否有另一个圆

    您可以使用此方法查找给定矩形中的所有元素。请注意,此方法是在SVG节点上调用的,而不是在d3选择上调用的

  • 拖动节点时,通过在其上设置样式
    指针事件:无;
    ,使其对鼠标事件“透明”

    当然,这也将使其对拖动事件透明,因此您必须将拖动事件添加到容器而不是节点,然后确定在“dragstart”事件中拖动的是哪个圆,更改其指针事件样式,并将圆选择存储在
    拖动
    函数可访问的变量中(移动时与当前代码相同)和
    dragend
    函数(将重新设置指针事件样式)。您还需要向指定拖动行为的
    元素添加背景矩形,以便即使鼠标仅在“透明”上,它也会响应鼠标事件圈

  • 拖动节点时,将其移动到绘制顺序的底部,以便在顶部绘制所有其他节点

    由于SVG不像HTML那样具有“z-index”属性,因此实现这一点的唯一方法是使用或纯Javascript
    insertBefore()
    对DOM进行重新排序

  • 或者,承认这只是一个小小的美学缺陷,不会改变代码的功能,因此不值得上述方法带来麻烦和性能影响

    如果您不喜欢某些圆在拖动时会改变颜色,可以在svg上为
        var closedRoad = true;
        var width = 960,
            height = 500;
    
        var points = d3.range(1, 5).map(function(i) {
            return [i * width / 5, 50 + Math.random() * (height - 100)];
        });
    
        var points1 = d3.range(1, 5).map(function(i) {
            return [i * width / 5, 50 + Math.random() * (height - 100)];
        });
    
        var points2 = d3.range(1, 5).map(function(i) {
            return [i * width / 5, 50 + Math.random() * (height - 100)];
        });
    
        var count = 0;
        var ways =  [];
    
        var currentWay = null;
    
        var selected = null;
    
        var line = d3.svg.line();
    
        var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
        var rect = svg.append("rect")
        .attr("width", width)
        .attr("height", height);
    
        ways.forEach(function(way, i) {
            svg.append("path")
            .datum(way)
            .attr("id", "p" + way.id)
            .attr("class", "line")
            .call(redraw);
        });
    
        d3.select(window)
        .on("keydown", keydown)
        //.on("mousemove", mousemove)
        .on("mouseup", mouseup)
        .on("mousedown", mousedown)
        .on("dblclick", dblclick);
    
        function redraw(way) {
            way.attr("d", function(d) { return line(d.pts); });
    
            var circle = svg.selectAll(".way" + way.data()[0].id)
            .data(way.data()[0].pts, function(d) { return d; });
            circle.enter().append("circle")
            .attr("class", "way" + way.data()[0].id)
            .attr("r", 1e-6)
            .on("mousedown", function(d) { 
                if (closedRoad) {
                    currentWay = way.data()[0];
                    selected = d; 
    
                    if (d3.event) {
                        d3.event.preventDefault();
                        d3.event.stopPropagation();
                    }
                }
            })
            .on("mouseover", function() { d3.select(d3.event.target).classed("highlight", true); })
            .on("mouseout", function() { d3.select(d3.event.target).classed("highlight", false); })
            .transition()
            .duration(750)
            .ease("elastic")
            .attr("r", 6.5);
    
            circle
            .attr("cx", function(d) { return d[0]; })
            .attr("cy", function(d) { return d[1]; });
    
            ////
            var drag = d3.behavior.drag();
            drag.on("dragstart", function(d) {
                console.log('START');
            })
            .on("drag", function(d) {
                console.log('MOVE');
    
                var m = d3.mouse(svg.node());
                d[0] = Math.max(0, Math.min(width, m[0]));
                d[1] = Math.max(0, Math.min(height, m[1]));
    
                //redraw(way);
                redrawAll();
            })
            .on("dragend", function(d) {
                console.log('END');
            });
    
            circle.call(drag);
            ////
    
            circle.exit().remove();
    
            /*   if (d3.event) {
                d3.event.preventDefault();
                d3.event.stopPropagation();
            }*/
        }
    
        function dblclick() {
            currentWay.pts.pop();
            //redraw(svg.select("#p" + currentWay.id));
            redrawAll();
    
            closedRoad = true;
        }
    
        function mousedown() {
            start = event.pageX + event.pageY;
            console.log(start);
    
        }
        function mouseup(){
            if(start >= (event.pageX + event.pageY) - 10 && start <= (event.pageX + event.pageY) + 10){
            if (closedRoad) {
                currentWay = { id: ++count, pts: [] };
                ways.push(currentWay); 
    
                svg.append("path")
                .datum(currentWay)
                .attr("id", "p" + currentWay.id)
                .attr("class", "line")
                .on("mouseover", function() { 
                    d3.select(d3.event.target).classed("highlight", true); 
                })
                .on("mouseout", function() { d3.select(d3.event.target).classed("highlight", false); })
                .call(redraw);
    
                closedRoad = false;
            }
    
            currentWay.pts.push(selected = d3.mouse(svg.node()));
            //redraw(svg.select("#p" + currentWay.id));
            redrawAll();
            }else{
    
            closedRoad = true;
            }
        }
        function redrawAll() {
            ways.forEach(function(way, i) {
                redraw(svg.select("#p" + way.id));
            });
        }
    
        function mousemove() {
    
        }
    
    
        function keydown() {
            if (!selected) return;
            switch (d3.event.keyCode) {
                case 8: // backspace
                case 46: { // delete
                    var i = currentWay.pts.indexOf(selected);
                    currentWay.pts.splice(i, 1);
                    selected = currentWay.pts.length ? currentWay.pts[i > 0 ? i - 1 : 0] : null;
                    redraw(svg.select("#p" + currentWay.id));
                    break;
                }
            }
        }