Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

107
Vistas
Bind elements of a matrix to grid cell by cell

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;
};
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

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

local.set(this, i);

...and then retrieving that index 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>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda