Reputation: 549
I i have 100 rectangles that I want to arrange in 10x10. I have been able to arrange one row and column but I am stuck at arranging the other nine. Here is js fiddle:
code:
var ContainerWidth = document.querySelector('#mainContainer').offsetWidth;
var rectWidth = ContainerWidth / 20
console.log(ContainerWidth)
var svgContainer = d3.select("#boxy")
var rectangle = svgContainer.selectAll("rect")
.data((function() {
var arr = []
for (var i = 1; i <= 100; i++) {
arr.push(i)
}
return arr
}()));
var rectangle = rectangle.enter()
.append("rect")
.style("stroke", "black")
.style("fill", "none")
.attr("x", function(d, i) {
if (i % 10 == 0) {
return 5
} else {
return (i*45) + 3;
}
})
.attr("y", function(d, i) {
if (i % 10 == 0) {
return i*4.2
}
})
.attr("width", rectWidth)
.attr("height", rectWidth);
the result should look something like this
Upvotes: 1
Views: 1036
Reputation: 3577
Just as an alternative method, here's how you could do it using "row" and "column" way. Uses a bit less math.
var svg = d3.select("svg");
var height = svg.attr("height");
var width = svg.attr("width");
var rectWidth = width / 20;
// Creates 10 rows.
var rows = svg.selectAll(".row")
.data(d3.range(10))
.enter().append("g")
.attr("class", "row")
.attr("transform", function(d, i) {
return "translate(0," + (rectWidth * i) + ")";
});
// For each row, create 10 rects.
var rects = rows.selectAll("rect")
.data(d3.range(10))
.enter().append("rect")
.attr("x", function(d, i) {
return rectWidth * i;
})
.attr("height", rectWidth)
.attr("width", rectWidth);
rect {
fill: black;
stroke: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg height="200" width="324"></svg>
Upvotes: 3
Reputation: 102194
Firstly, you can simplify your data to just:
.data(d3.range(100));
To make the matrix with your rectangles, you can use:
.attr("x", (d,i) => i%10 * 45)
.attr("y", (d,i) => Math.floor(i/10)%10 * 45)
Here is a demo:
var ContainerWidth = document.querySelector('#mainContainer').offsetWidth;
var rectWidth = ContainerWidth / 20;
var svgContainer = d3.select("#boxy");
var rectangle = svgContainer.selectAll("rect")
.data(d3.range(100));
rectangle.enter()
.append("rect")
.style("stroke", "black")
.style("fill", "none")
.attr("x", (d,i) => i%10 * 45)
.attr("y", (d,i) => Math.floor(i/10)%10 * 45)
.attr("width", rectWidth)
.attr("height", rectWidth);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='mainContainer'>
<svg id="boxy" viewBox="0 0 960 500" preserveAspectRatio="xMidYMid meet">
</svg>
</div>
This other snippet show you the data bound to each rectangle:
var ContainerWidth = document.querySelector('#mainContainer').offsetWidth;
var rectWidth = ContainerWidth / 20;
var svgContainer = d3.select("#boxy");
var rectangle = svgContainer.selectAll("rect")
.data(d3.range(100));
rectangle.enter()
.append("rect")
.style("stroke", "black")
.style("fill", "none")
.attr("x", (d,i) => i%10 * 45)
.attr("y", (d,i) => Math.floor(i/10)%10 * 45)
.attr("width", rectWidth)
.attr("height", rectWidth);
rectangle.enter()
.append("text")
.attr("x", (d,i) => i%10 * 45 + 4)
.attr("y", (d,i) => Math.floor(i/10)%10 * 45 + 16)
.text((d,i)=>d);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='mainContainer'>
<svg id="boxy" viewBox="0 0 960 500" preserveAspectRatio="xMidYMid meet">
</svg>
</div>
Upvotes: 4