如何在d3.js中排列行中的矩形

时间:2017-01-04 14:11:52

标签: javascript jquery d3.js

我想要 10x10 排列 100个矩形。我已经能够安排一行和一列,但我很擅长安排其他九行。 Here is js fiddle:

代码:

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);

结果看起来应该是这样的 enter image description here

2 个答案:

答案 0 :(得分:4)

首先,您可以将数据简化为:

.data(d3.range(100));

要使用矩形制作矩阵,可以使用:

 .attr("x", (d,i) => i%10 * 45)
 .attr("y", (d,i) => Math.floor(i/10)%10 * 45)

这是一个演示:

&#13;
&#13;
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);
&#13;
<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>
&#13;
&#13;
&#13;

此其他代码段显示绑定到每个矩形的数据:

&#13;
&#13;
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);
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

作为替代方法,这里是你如何使用“行”和“列”的方式来做到这一点。使用少一点数学。

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>

JSFiddle version