Home > OS >  Bind elements of a matrix to grid cell by cell
Bind elements of a matrix to grid cell by cell

Time:04-26

I am trying to create an animation where the elements of a grid appear in left-to-right, top-to-bottom order. So the order would be: A_(1,1), A_(1,2),...A_(1,d)...A_(n,d) .

My current code displays all elements in one column of the grid, followed by a delay, then all the elements in the second column, delay, and so on. I am sure this is because the index element in line 56, which controls the time delay for each element, resets with each row. I'd like to know if there is a way to get around this, such as having a variable that keeps track of the column number of 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;
};

CodePudding user response:

There are several ways to do this. One of my favourites idiomatic D3 ways is to set the index of the parent rows using a local variable...

local.set(this, i);

...and then retrieving that local for setting the delay:

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

Here's your code with a 3x3 matrix:

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>

  • Related