3

I'm trying to reproduce the behaviour of this SVG explained at this post, but putting the JavaScript in the HTML page, and using D3.js. I try this:

<!DOCTYPE html>
<meta charset="utf-8">

<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
var svg = d3.select("body").append("svg")
    .attr("width", 300)
    .attr("height", 300)
    .attr("id","svgBox");

var svgRect = svg.append("rect")
    .attr("width", 200)
    .attr("height", 200)
    .attr("x", 50)
    .attr("y", 50)
    .attr("id","rect1")
    .style("fill", "#AAFFAA")
    .style("stroke", "#222222");

var root = document.getElementById("svgBox");
var rpos = root.createSVGRect();
rpos.x = 150;
rpos.y = 150;
rpos.width = rpos.height = 1;

var list = root.getIntersectionList(rpos, null);
console.info(list);
</script>

But it doesn't work. When trying it in Firefox, the error is

TypeError: root.getIntersectionList is not a function

And in Chrome, there is no error, but the function doesn't seem to work, since the result in list is always empty.

Is there a way to call the function or I should detect if the point is inside the path by using another method?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Roger Veciana
  • 983
  • 1
  • 12
  • 25

1 Answers1

4

The Firefox error is to be expected since that browser doesn't yet support getInsectionList method: https://bugzilla.mozilla.org/show_bug.cgi?id=501421

Regarding Chrome, I think you have a timing issue where the svg nodes aren't rendered at the time you execute your getIntersectionList call. If you push the code to the end of the event loop it should work:

window.setTimeout(function(){
    // your original code as-is:
    var root = document.getElementById("svgBox");
    var rpos = root.createSVGRect();
    rpos.x = 150;
    rpos.y = 150;
    rpos.width = rpos.height = 1;

    var list = root.getIntersectionList(rpos, null);
    console.info(list);
},0)

Probably you're going to have this inside some other event (e.g. mouse click) anyway, but the above should let you prove out the concept.

Regarding alternate approach to intersection testing (which you'll probably need unless you support only Chrome), see this question: d3 - see what is at a particular x,y position

And one other unrelated suggestion on the efficiency of your code: d3 has a node() method which gives you the underlying DOM node of the selection. Since you already have a reference to d3's svg object, you can change this:

var root = document.getElementById("svgBox");

to this:

var root = svg.node();
Community
  • 1
  • 1
explunit
  • 18,967
  • 6
  • 69
  • 94
  • 8 years later: Firefox still doesn't support `getInsectionList()` and `getEnclosureList()` – David Aug 13 '21 at 11:26