将矩阵的元素逐个单元格地绑定到网格

Bind elements of a matrix to grid cell by cell

我正在尝试创建一个动画,其中网格元素以从左到右、从上到下的顺序出现。所以顺序是:A_(1,1), A_(1,2),...A_(1,d)...A_(n,d) .

我当前的代码显示网格的一列中的所有元素,然后是延迟,然后是第二列中的所有元素,延迟,依此类推。我确信这是因为第 56 行中控制每个元素的时间延迟的索引元素随每一行重置。我想知道是否有办法解决这个问题,比如有一个变量来跟踪 d 的列号。

var data = [[0,1],[2,3]];

function myMatrix2(data) {

    var margin = {top: 50, right: 100, bottom: 50, left: 100},
        width = 250,
        height = 250;

    const svg = d3
        .select('.grid2')
        .append('svg')
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    numrows = data.length;
    numcols = data[0].length;

    rw=width/numrows;
    hw=height/numcols;

    var x = d3.scaleOrdinal()
        .domain(d3.range(numcols))
        .range(d3.range(0,width,width/numcols));

    var y = d3.scaleOrdinal()
        .domain(d3.range(numrows))
        .range(d3.range(0,height,height/numrows));

    var row = svg.selectAll(".row")
        .data(data)
        .enter().append("g")
        .attr("class", "row")
        .attr("transform", function(d, i) {return "translate(0," + y(i) + ")"; });

    var cell = row.selectAll(".cell")
        .data(function(d) { return d; })
        .enter().append("g")
        .attr("class", "cell")
        .attr("transform", function(d, i) { return "translate(" + x(i) + ", 0)"; });

    cell.append('rect')
        .attr("width", rw)
        .attr("height", hw)
        .style("stroke", "black")
        .style("stroke-width", "2px")
        .style("fill", 'white')

    cell.append("text") //Add matrix elements
        .attr("dy", ".32em")
        .attr("x", rw/2 )
        .attr("y", hw/2 )
        .attr("text-anchor", "middle")
        .style("font-size","14px")
        .transition() //Delay starts here
        .delay(function(d,i) {console.log("D: "+d + " I: "+i); return i*3000;})
        .text(function(d) { return d; })
    return;
};

有几种方法可以做到这一点。我最喜欢的惯用 D3 方法之一是使用局部变量设置父行的索引...

local.set(this, i);

...然后检索该索引以设置延迟:

.delay(function(d, i) {
    const p = local.get(this);
    return i * 1000 + p * (1000 / numrows);
})

这是您使用 3x3 矩阵的代码:

var data = [
  [0, 1, 4],
  [2, 3, 6],
  [7, 8, 9]
];
const local = d3.local();

myMatrix2(data);

function myMatrix2(data) {

  var margin = {
      top: 4,
      right: 10,
      bottom: 4,
      left: 10
    },
    width = 150,
    height = 150;

  const svg = d3
    .select('body')
    .append('svg')
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  numrows = data.length;
  numcols = data[0].length;

  rw = width / numrows;
  hw = height / numcols;

  var x = d3.scaleOrdinal()
    .domain(d3.range(numcols))
    .range(d3.range(0, width, width / numcols));

  var y = d3.scaleOrdinal()
    .domain(d3.range(numrows))
    .range(d3.range(0, height, height / numrows));

  var row = svg.selectAll(".row")
    .data(data)
    .enter().append("g")
    .attr("class", "row")
    .attr("transform", function(d, i) {
      local.set(this, i);
      return "translate(0," + y(i) + ")";
    });

  var cell = row.selectAll(".cell")
    .data(function(d) {
      return d;
    })
    .enter().append("g")
    .attr("class", "cell")
    .attr("transform", function(d, i) {
      return "translate(" + x(i) + ", 0)";
    });

  cell.append('rect')
    .attr("width", rw)
    .attr("height", hw)
    .style("stroke", "black")
    .style("stroke-width", "2px")
    .style("fill", 'white')

  cell.append("text") //Add matrix elements
    .attr("dy", ".32em")
    .attr("x", rw / 2)
    .attr("y", hw / 2)
    .attr("text-anchor", "middle")
    .style("font-size", "14px")
    .transition() //Delay starts here
    .delay(function(d, i) {
      const p = local.get(this);
      return i * 1000 + p * (1000 / numrows);
    })
    .text(function(d) {
      return d;
    })
  return;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>