juniper-
juniper-

Reputation: 6552

D3.js div blocks mouseover event in svg

If I create a simple scatter plot using d3.js, I can record the mouseover events on the circle elements by printing 'hey' to the console:

http://jsfiddle.net/pkerpedjiev/opmhaz0n/

<!DOCTYPE html>
<meta charset="utf-8">
<div class="chart" style="position: aboslute; left: 0px: top: 0px; width: 300px; height: 200px;" ></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
    var xVals = [4, 8, 15, 16, 23, 42,72];
    var yVals = [13, 49, 34, 2, 22, 23, 44];

    var data = xVals.map(function(d,i) { return [d, yVals[i]]; });

    var width=300;
    var height=200;

    console.log('data:', data);

    /*
    var div = d3.select(".chart").append("div")
    .style("position", "absolute")
    .style("width", width + "px")
    .style("height", height + "px")
    .style("left", 0 + "px")
    .style("top", 0  + "px")
    .style("opacity", 0.2);
    */ 

    var svg = d3.select(".chart")
    .append("svg")

    svg.selectAll('circle')
    .data(data)
    .enter()
    .append("circle")
    .attr('cx', function(d) { return d[0]; })
    .attr('cy', function(d) { return d[1]; })
    .attr('r', 4)
    .attr('fill', 'black')
    .on('mouseover', function(d) { console.log('hey'); });

</script>

If I add a div behind the svg, however, the mouseover event doesn't get recorded:

http://jsfiddle.net/pkerpedjiev/Lxgbycr8/1/

<!DOCTYPE html>
<meta charset="utf-8">
<div class="chart" style="position: aboslute; left: 0px: top: 0px; width: 300px; height: 200px;" ></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
    var xVals = [4, 8, 15, 16, 23, 42,72];
    var yVals = [13, 49, 34, 2, 22, 23, 44];

    var data = xVals.map(function(d,i) { return [d, yVals[i]]; });

    var width=300;
    var height=200;

    console.log('data:', data);

    var div = d3.select(".chart").append("div")
    .style("position", "absolute")
    .style("width", width + "px")
    .style("height", height + "px")
    .style("left", 0 + "px")
    .style("top", 0  + "px")
    .style("opacity", 0.2);

    var svg = d3.select(".chart")
    .append("svg")

    svg.selectAll('circle')
    .data(data)
    .enter()
    .append("circle")
    .attr('cx', function(d) { return d[0]; })
    .attr('cy', function(d) { return d[1]; })
    .attr('r', 4)
    .attr('fill', 'black')
    .on('mouseover', function(d) { console.log('hey'); });

</script>

Is there a way to register the 'mouseover' event when there's a div in the background behind the svg?

Upvotes: 1

Views: 941

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The positioning of the elements is interfering with what you may expect for mouse events here, in particular you need to set position to absolute for the SVG as well to make it appear in front of the div.

If you want the SVG to "catch" events only on certain elements, set pointer-events to none on the SVG and to all on the elements you want to receive the events.

Upvotes: 1

Related Questions