I'd like to append a literal SVG element with d3.
So instead of writing
svg.selectAll("circle")
.data(data)
.enter()
.append("circle") // etc etc
I'd like to do:
svg.selectAll("circle")
.data(data)
.enter()
.append('<circle cx="158.9344262295082" cy="200" r="16" fill="red"></circle>')
so that I could create a complex template elsewhere (for example with handlebars), and then compile it with data and append it.
You can do this, although not via the
selection.append()
function. Instead you'd need to use the selection.html() function.This would make it quite difficult to use in the context of data-joins, but not impossible. This is probably the best you could do, which involves adding an additional svg group to the DOM which may not be a bad thing anyway:
I guess taking this answer a bit further, you could actually embed the result that you wish to render directly into your
data
object. So you've add some code that looked like:.html(function(d) { return d.templatedHTML; });
At this point however stop and ask yourself the question: "What am I using D3 for?". D3 is described as
If you're using something like handlebars, then you're taking away one of the core responsibilities that D3 was designed for (building some DOM from some data) and giving it to some other library.
I'm not stating you shouldn't do that (as you did mention complex templates) but do just ask yourself the question to make sure that it's a path you wish to go down.
No, you can't. Don't believe me? Check their docs HERE
What you must do is call
.append()
, followed by several calls of.attr(attr_name, attr_value)
to set each attribute's value. D3 does not work like jQuery.D3 doesn't provide this functionality, and it does not make much sense (when you think about manipulating elements based on data).
But, as a side note, you can implement your own function to append a literal SVG element.
This is a function created by Chris Viau, named
appendSVG
:After extending the prototype, you can use it:
Here is a demo. First, we set the data:
Then, we append our literal SVG element in the usual way:
And finally we set the positions using
translate
:Check the snippet: