删除 svg rect 绘图行中的幻数

removing magic number in drawing rows of svg rect

我有一个 SVG 元素,正在绘制设定大小的矩形。我计算最大列 max_cols 和所需行 min_rows 以匹配数据集。当我到达 SVG canvas 的末尾时,我开始了一个新行,但是我计算 y 坐标的算法使用幻数。我怎样才能摆脱它? 以下是我的 (D3.js) 代码的相关块:

var rw = 17; // rect width
var rh = 17; // rect height
var rm = 2;  // rect margin
var min_rows = Math.ceil(c * (rw + rm) / w );
var max_cols = ( Math.ceil(w / (rh + rm)) ) - 2;

...

.attr('x', function(d, i) {
    var rem = i % max_cols;
    if (i < max_cols){
        return i * (rw + rm);                    
    } else {
        return rem * (rw + rm);
    }
})
.attr('y', function(d, i) {
    if (i < max_cols){
        return rh + rm;                    
    } else if (i < max_cols * 2) {
        return 2 * (rh + rm);
    } else if (i < max_cols * 3){
        return 3 * (rh + rm);
    } else {
        return 4 * (rh + rm);
    }
})

...

如果这有帮助,这是视觉结果:

我会这样做:

        var width = 323,
          height = 400,
          rw = 17,
          rh = 17,
          rm = 2,
          num_cols = parseInt(width / (rw + rm)),

          data = [
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#880", "#880", "#880",
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#008", "#008", "#008", "#008",
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#880", "#880", "#880",
            "#800", "#800", "#800", "#800", "#800", "#800", "#800",
            "#800", "#800", "#800", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#008", "#008", "#008",
            "#008", "#008", "#008", "#008", "#880", "#880", "#880",
            "#888", "#888", "#080", "#880", "#880", "#880", "#880",
            "#880", "#880", "#880", "#880", "#880",
          ];

        var svg = d3.select("#vis").append("svg")
          .attr("width", width)
          .attr("height", height);

        var rects = d3.select("svg").selectAll("rect")
          .data(data)
          .enter().append("rect")
          .attr("width", rw)
          .attr("height", rh)
          .attr("x", function(d, i) {
            return (i % num_cols) * (rw + rm);
          }).attr("y", function(d, i) {
            return parseInt(i / num_cols) * (rh + rm);
          }).style("fill", function(d) {
            return d;
          });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="vis"></div>

基本上,y 位置就是 parseInt(i * (rh + rm) / num_cols)x 位置就是 (i % num_cols) * (rw + rm);