mr kw
mr kw

Reputation: 2113

d3 mouseover on element conflicts with svg mousemove

I have attached a mouseover event to an element - say, a circle - within the SVG element. I also need a "mousemove" event handler associated with the SVG element/"background" itself. However, they seem to conflict: when mousing over the circle, the handler attached to the circle does not supersede that associated with the SVG element itself.

How do I get the circle's mouseover to supersede the SVG element's event handler? I need them both, but only want the mouseover to be triggered over the circle and the mousemove to be triggered by movement anywhere else in the SVG element.

A simplified example can be seen in this JSFiddle: http://jsfiddle.net/aD8x2/ (JS code below). If you click on a circle (starting a line) and then mouse over another circle, you will see the flickering of color associated with both events being triggered when mousing over the circle.

var svg = d3.select("div#design")
            .append("svg")
            .attr("width", "500").attr("height", "500");

svg.selectAll("circle").data([100, 300]).enter().append("circle")
    .attr("cx", function(d) { return d; })
    .attr("cy", function(d) { return d; })
    .attr("r", 30)
    .on("mouseover", function () {
    d3.select(this).attr("fill", "red");
    })
    .on("mouseout", function() {
    d3.select(this).attr("fill", "black");
    })
    .on("click", function() {
    svg.append("line")
       .attr(
        {
        "x1": d3.select(this).attr("cx"),
        "y1": d3.select(this).attr("cy"),
        "x2": d3.select(this).attr("cx"),
        "y2": d3.select(this).attr("cy")
        })
       .style("stroke-width", "10")
       .style("stroke", "rgb(255,0,0)");
    });


    svg.on("mousemove", function() {
        var m = d3.mouse(this);

        svg.selectAll("line")
           .attr("x2", m[0])
           .attr("y2", m[1]);
    });

Upvotes: 3

Views: 5507

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

In your case, it is actually the line causing the problem and not the SVG. That is, you're moving the mouse over the line you're drawing and thus a mouseout event is triggered for the circle.

You can prevent this by setting pointer-events to none for the line so it's "transparent" with respect to mouse events. Modified example here.

Upvotes: 5

Related Questions