user736893
user736893

Reputation:

Render d3 SVG graph using HTML

Here is my current fiddle.

I'm using the stock d3 example taken from this page. I'm trying to modify it so that I can apply my custom CSS as well as some Knockout Bindings. I have tried replacing the append("svg:text") with "foreignObject" and "tspan", as recommended in this post. It showed up in the DOM under the "g" element, but did not show up properly in the browser.

I'm currently trying to just remove the .append statements for the circle and the text and step through each "g" element and apply custom classes using addClass, as below, but it doesn't add them at all.

anchorNode.each(function (i, value) {
    $(this).addClass('entity').addClass('relNode');
})

How can I utilize custom HTML/CSS with the d3 library? Specifically, this example.

Upvotes: 0

Views: 266

Answers (1)

cbayram
cbayram

Reputation: 2259

SVG is not a free for all. Each element has permitted children as well as parents. tspan for example goes within a svg text element. When it comes to the group element, here are permitted elements within the g SVG element. To use the tspan, you must embed it within text as per this fiddle

When it comes to the foreignObject, you can use it to embed foreign xml derivitives such as xhtml IF the user-agent (browser) supports it. It's often used with switch statement, where the switch statement will test the requiredExtensions attribute for first true and waterfall down as mentioned in the documentation I linked you to. Here's a fiddle that demonstrates this depending on the support of your user-agent.

var switches = anchorNode.append("svg:switch")
switches.append("svg:foreignObject")
  .attr("requiredExtensions", "http://www.w3.org/1999/xhtml")
  .append("body").attr("xmlns", "http://www.w3.org/1999/xhtml")
  .append("p").text(function(d, i) {
    return "a la foreignObject" + (i % 2 == 0 ? "" : d.node.label) 
  }).style("fill", "#555").style("font-family", "Arial").style("font-size", 12);

switches.append("svg:text").append("svg:tspan").text(function(d, i) {
  return i % 2 == 0 ? "" : d.node.label
}).style("fill", "#555").style("font-family", "Arial").style("font-size", 12);

It's difficult to suggest a solution, without knowing exactly what it is you want to achieve, but hope this helps clarify the issue a bit.

Upvotes: 1

Related Questions