Reputation: 1656
I noticed then I get mixed results when I append an DOM/SVG elements to an existing object inline and in the separate step when using the D3 javascript library. If I look at the variable referencing the original SVG object it changes, when another object is appended during the creation of the original object. Here is an example:
var body = d3.select("body");
var svg = body.append("svg")
.attr("width", '100%')
.attr("height", '100%')
var html1 = svg.append("foreignObject")
.attr("x", 50)
.attr("y", 25)
.attr("width", 200)
.attr("height", 100)
.attr('id', 'fo1')
.append("xhtml:div")
.html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.");
var html2 = svg.append("foreignObject")
.attr("x", 250)
.attr("y", 25)
.attr("width", 200)
.attr("height", 100)
.attr('id', 'fo2');
html2.append("xhtml:div")
.html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.");
console.log('first fo:', html1[0]);
console.log('first fo id:', d3.select('#fo1')[0]);
console.log('second fo:', html2[0]);
The output looks like :
first fo:
Array[1]
0: div
length: 1
parentNode: html
__proto__: Array[0]
first fo id:
Array[1]
0: foreignobject#fo1.[object SVGAnimatedString]
length: 1
parentNode: html
__proto__: Array[0]
second fo:
Array[1]
0: foreignobject#fo2.[object SVGAnimatedString]
length: 1
parentNode: html
__proto__: Array[0]
After appending the DIV element to the foreignObject element inline during the creation the variable changes from foreignObject to div. Doing this in extra step does not chenges the reference. Here is the corresponding jsfiddle Could someone explain this to me and tell me how to avoid it ?
Upvotes: 0
Views: 1071
Reputation: 109262
The result of an append()
operation in D3 is the element that you have just appended. This is so that you can chain the methods to set attributes, content, etc. If this wasn't the case, then you couldn't use the .html()
function to set the content of your newly-appended div
as the current object would still be the parent foreignObject
.
This behavior is intentional and you cannot prevent it unless you modify the D3 source. If you need to save the references to all the elements, simply append in separate calls. That is
var html1 = svg.append("foreignObject")
...
.attr('id', 'fo1')
.append("xhtml:div")
.html(...);
would become
var html1 = svg.append("foreignObject")
...
.attr('id', 'fo1');
var nested = html1.append("xhtml:div")
.html(...);
Upvotes: 2