2
votes

Problem: I'm attempting to wrap text associated with Nodes of a D3 Tree but can't seem to properly assign text to HTML links.

I'm trying to use the approach of appending a "foreignObject" element, where I can then append a "div" element, in order to control width. Once I have the "div", I try to append an HTML "a" element with an HTML link and associated text.

The HTML DOM object shows that the "a" element is constructed properly but it doesn't render in the browser. It doesn't seem to work either wrapped or not wrapped by a "body" element.

Code:

      nodeEnter.append("svg:foreignObject")
          .attr("width", "50")
          //.append("xhtml:body")
          //.attr("xmlns", "http://www.w3.org/1999/xhtml")
        .append("svg:div").attr("class", "NODE_LABEL_DIV")
        .append("svg:a")
          .attr("xlink:href", function(d) { return d.hlink; })
          .text(function(d) { return d.name; })
          .attr("x", function(d) { return d.children || d._children ? horizontalNodeOffset : horizontalNodeOffsetLeaf; })
          .attr("dy", "-10")
          .attr("fill", "Blue")
          .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
          .style("fill-opacity", 1e-6);

My Question: What's the right way to add the HTML "a" element to the "div" within the foreignObject, so it renders properly and so I can wrap the text using the "div" element?

1

1 Answers

3
votes

You're using the wrong namespace for the div and a elements. By prefixing them with svg:, you're asking the browser to interpret them as SVG elements. The whole point of using foreignObject is to be able to use non-SVG elements though -- these are HTML elements and should be declared as such (just omitting the namespace entirely should work as well).

Here is a complete example of using foreignObject in D3. You can specify all the markup in the argument to .html() or append separate elements as you're doing -- the important thing is that you get the namespace right.