You're successfully creating extra rectangles, but unfortunately they are all nested inside the first three rectangles. If you have a web developer extension on your browser, select one of the rectangles and then view the source to see.
If you want to append the rectangles, rather than nest them inside the original rectangle, you need to append both rectangles to your g
node. When you bind the data and add your g
nodes, assign those nodes to a variable:
var svg = d3.select("body").append("svg");var nodes = svg.selectAll(".rect") .data([10,60,120]) .enter() .append("g") .classed('rect', true)
Then you can append the two rectangles to the g
nodes:
// red rectanglesnodes.append("rect") .attr("width", 20) .attr("height", 20) .attr("x", 20) .attr("y", function(d) {return d}) .attr("fill", "red")// blue onesnodes.append("rect") .attr("width", 20) .attr("height", 20) .attr("x", 120) .attr("y", function(d) {return d}) .attr("fill", "blue")
Note that if you do this:
var nodes = svg.selectAll("rect") .data([10,60,120]) .enter() .append("g") .append("rect") .attr("width", 20) .attr("height", 20) .attr("x", 20) .attr("y", function(d) {return d}) .attr("fill", "red")
nodes
will be a reference to the rect
elements, as they were the last thing added, and anything appended to nodes
will be added inside the rect
elements.
Note also that you only need to bind the data once, to the g
elements; it is automatically inherited by all the child nodes of those g
elements.
Here's the completed example:
var svg = d3.select("body").append("svg");var g = svg.selectAll(".rect") .data([10,60,120]) .enter() .append("g") .classed('rect', true)g.append("rect") .attr("width", 20) .attr("height", 20) .attr("x", 20) .attr("y", function(d) {return d}) .attr("fill", "red")g.append("rect") .attr("width", 20) .attr("height", 20) .attr("x", 120) .attr("y", function(d) {return d}) .attr("fill", "blue")
<script src="https://d3js.org/d3.v5.js"></script>