I'm trying to append a shape dynamically, based on what is contained with the datum. My object is this:
const boom = [
{
shape: 'rect',
color: 'red',
width: 50,
height: 50,
x: 50,
y: 100
}
]
And my code is this:
const stage = d3.select('stageContainer')
.append('svg')
.attr('width', 100)
.attr('height', 100)
.style('border-width', '2')
.style('border-color', 'red')
.style('border-style', 'solid')
stage.selectAll('.group01')
.data(boom)
.enter()
.append(d => document.createElement(d.shape))
.attr('fill', d => d.color)
.attr('width', d => d.width)
.attr('height', d => d.height)
.attr('x', d => d.x)
.attr('y', d => d.y)
I can see that it's adding to the DOM, but it isn't actually rendering.
For creating SVG elements you have to use document.createElementNS:
.append(d => document.createElementNS('http://www.w3.org/2000/svg', d.shape))
Alternatively, you can use the built-in namespaces in d3.namespaces:
.append(d => document.createElementNS(d3.namespaces.svg, d.shape))
Here is your code with that change:
const boom = [{
shape: 'rect',
color: 'blue',
width: 50,
height: 50,
x: 40,
y: 10
}];
const stage = d3.select('body')
.append('svg')
.attr('width', 100)
.attr('height', 100)
.style('border-width', '2')
.style('border-color', 'red')
.style('border-style', 'solid')
stage.selectAll('.group01')
.data(boom)
.enter()
.append(d => document.createElementNS(d3.namespaces.svg, d.shape))
.attr('fill', d => d.color)
.attr('width', d => d.width)
.attr('height', d => d.height)
.attr('x', d => d.x)
.attr('y', d => d.y)
<script src="https://d3js.org/d3.v5.min.js"></script>
PS: change that rectangle's position, otherwise it will fall outside the SVG.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With