dvreed77
dvreed77

Reputation: 2387

Strange Behaviour with d3.append()

I am trying to append a rect to an svg element using a function as input to d3.append. The strange thing is that the element shows up in the dom when I inspect the page, but its not being rendered.

I have also enclosed a JSBin with the problem. You can see only 1 rect is being rendered while there should be 2.

https://jsbin.com/folehubita/edit?html,output

Update

I realize that the standard method is to supply a string of the tag type, but my problem is a bit beyond this and I need to build an element within the function.

This capability is documented. https://github.com/d3/d3-selection/blob/master/README.md#selection_append

Upvotes: 1

Views: 107

Answers (1)

Aurelio
Aurelio

Reputation: 25772

Just change your .append method to this:

svg
.append('rect') // <= notice the difference
.attr('x', 0)
.attr('width', 10)
.attr('height', 10)
.attr('fill', 'red')

See this bin for comparison.

EDIT

Apparently the document.createElement('rect'); method does not work (PS - and for a good reason, see end of this answer). If I am getting it, the reason is that actually by using that function the element is indeed created "outside" d3 so you need to explicitly specify the SVG namespace.

D3 does that for you when you use .append('rect') (see source) but you have do it yourself otherwise and use .createElementNS.

It might be worth opening a PR to point that out in the DOCs you are referring if that turns out to be the case (which I am not 100% sure tbh).

Anyway try with:

svg
  .append(function() { 
    return document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  })

This way it will work. See also this Github comment and the whole discussion.

After a bit of research I think what's happening makes sense, as the element is by default created with the xhtml namespace but in this particular case it ends up being the wrong one.

To prove that if in your original bin you inspect the console the svg element is there but it's invisible and takes no space even if you specify it. If you select it from the console and log its namespaceURI you'll see that it actually has the wrong one, "http://www.w3.org/1999/xhtml" instead of http://www.w3.org/2000/svg.

enter image description here

I updated the bin here.

Upvotes: 5

Related Questions