how to draw a grid incrementally in d3?












2















Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid with 0 or 1; then fills a 1d array called nodes with x, y, and color; then draws nodes with d3. They all appear. They look like this:



grid of squares



How do I instead have nodes drawn (i.e. appear) one at a time, in the order given by the nodes array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?



I tried fiddling with the transition function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.



The code:



<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);

// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}

// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}

// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill", function(d) { return d.color; })
}

// function has to execute after dom is loaded
window.onload = draw_function
</script>

<style>rect { color: black; }</style>
</head>

<body><div id="graph"/></body>
</html>









share|improve this question



























    2















    Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid with 0 or 1; then fills a 1d array called nodes with x, y, and color; then draws nodes with d3. They all appear. They look like this:



    grid of squares



    How do I instead have nodes drawn (i.e. appear) one at a time, in the order given by the nodes array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?



    I tried fiddling with the transition function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.



    The code:



    <html>
    <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    <script>
    function draw_function() {
    var vis = d3.select("#graph")
    .append("svg")
    .attr("width", 200).attr("height", 200);

    // fill the_grid
    var shape=[10,10];
    var the_grid=;
    for (var idx = 0; idx < shape[0]; idx++) {
    var row = ;
    for (var jdx = 0; jdx < shape[1]; jdx++) {
    var val = (idx+jdx)/2;
    row.push(Math.floor(val)==val ? 1 : 0);
    }
    the_grid.push(row);
    }

    // fill nodes
    var rectwidth = 10;
    var nodes = ;
    for (var idx = 0; idx < the_grid.length; idx++) {
    for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
    var node = {x: idx * (rectwidth+1),
    y: jdx * (rectwidth+1),
    color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
    nodes.push(node);
    }
    }

    // draw nodes
    vis.selectAll("rect.nodes")
    .data(nodes)
    .enter()
    .append("svg:rect")
    .attr("x", function(d) { return d.x; })
    .attr("y", function(d) { return d.y; })
    .attr("height", rectwidth)
    .attr("width", rectwidth)
    .attr("fill", function(d) { return d.color; })
    }

    // function has to execute after dom is loaded
    window.onload = draw_function
    </script>

    <style>rect { color: black; }</style>
    </head>

    <body><div id="graph"/></body>
    </html>









    share|improve this question

























      2












      2








      2








      Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid with 0 or 1; then fills a 1d array called nodes with x, y, and color; then draws nodes with d3. They all appear. They look like this:



      grid of squares



      How do I instead have nodes drawn (i.e. appear) one at a time, in the order given by the nodes array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?



      I tried fiddling with the transition function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.



      The code:



      <html>
      <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <script>
      function draw_function() {
      var vis = d3.select("#graph")
      .append("svg")
      .attr("width", 200).attr("height", 200);

      // fill the_grid
      var shape=[10,10];
      var the_grid=;
      for (var idx = 0; idx < shape[0]; idx++) {
      var row = ;
      for (var jdx = 0; jdx < shape[1]; jdx++) {
      var val = (idx+jdx)/2;
      row.push(Math.floor(val)==val ? 1 : 0);
      }
      the_grid.push(row);
      }

      // fill nodes
      var rectwidth = 10;
      var nodes = ;
      for (var idx = 0; idx < the_grid.length; idx++) {
      for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
      var node = {x: idx * (rectwidth+1),
      y: jdx * (rectwidth+1),
      color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
      nodes.push(node);
      }
      }

      // draw nodes
      vis.selectAll("rect.nodes")
      .data(nodes)
      .enter()
      .append("svg:rect")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .attr("height", rectwidth)
      .attr("width", rectwidth)
      .attr("fill", function(d) { return d.color; })
      }

      // function has to execute after dom is loaded
      window.onload = draw_function
      </script>

      <style>rect { color: black; }</style>
      </head>

      <body><div id="graph"/></body>
      </html>









      share|improve this question














      Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid with 0 or 1; then fills a 1d array called nodes with x, y, and color; then draws nodes with d3. They all appear. They look like this:



      grid of squares



      How do I instead have nodes drawn (i.e. appear) one at a time, in the order given by the nodes array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?



      I tried fiddling with the transition function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.



      The code:



      <html>
      <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <script>
      function draw_function() {
      var vis = d3.select("#graph")
      .append("svg")
      .attr("width", 200).attr("height", 200);

      // fill the_grid
      var shape=[10,10];
      var the_grid=;
      for (var idx = 0; idx < shape[0]; idx++) {
      var row = ;
      for (var jdx = 0; jdx < shape[1]; jdx++) {
      var val = (idx+jdx)/2;
      row.push(Math.floor(val)==val ? 1 : 0);
      }
      the_grid.push(row);
      }

      // fill nodes
      var rectwidth = 10;
      var nodes = ;
      for (var idx = 0; idx < the_grid.length; idx++) {
      for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
      var node = {x: idx * (rectwidth+1),
      y: jdx * (rectwidth+1),
      color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
      nodes.push(node);
      }
      }

      // draw nodes
      vis.selectAll("rect.nodes")
      .data(nodes)
      .enter()
      .append("svg:rect")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .attr("height", rectwidth)
      .attr("width", rectwidth)
      .attr("fill", function(d) { return d.color; })
      }

      // function has to execute after dom is loaded
      window.onload = draw_function
      </script>

      <style>rect { color: black; }</style>
      </head>

      <body><div id="graph"/></body>
      </html>






      d3.js






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 31 '18 at 18:49









      dfrankowdfrankow

      8,7413198152




      8,7413198152
























          1 Answer
          1






          active

          oldest

          votes


















          4














          To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay(), you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:



          selection.transition()
          .delay(function(d,i) { return i * 100; })
          .attr(...


          Above and in the snippet below I've used the index:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          And below I've used the datum to create a random transition order:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>








          share|improve this answer


























          • great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

            – dfrankow
            Dec 31 '18 at 19:34











          • I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

            – Andrew Reid
            Dec 31 '18 at 19:35













          • will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

            – dfrankow
            Dec 31 '18 at 19:37






          • 1





            If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

            – Andrew Reid
            Dec 31 '18 at 19:39











          • FYI I ended up using this in github.com/dfrankow/d3maze.

            – dfrankow
            Jan 1 at 18:36











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990545%2fhow-to-draw-a-grid-incrementally-in-d3%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          4














          To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay(), you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:



          selection.transition()
          .delay(function(d,i) { return i * 100; })
          .attr(...


          Above and in the snippet below I've used the index:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          And below I've used the datum to create a random transition order:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>








          share|improve this answer


























          • great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

            – dfrankow
            Dec 31 '18 at 19:34











          • I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

            – Andrew Reid
            Dec 31 '18 at 19:35













          • will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

            – dfrankow
            Dec 31 '18 at 19:37






          • 1





            If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

            – Andrew Reid
            Dec 31 '18 at 19:39











          • FYI I ended up using this in github.com/dfrankow/d3maze.

            – dfrankow
            Jan 1 at 18:36
















          4














          To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay(), you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:



          selection.transition()
          .delay(function(d,i) { return i * 100; })
          .attr(...


          Above and in the snippet below I've used the index:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          And below I've used the datum to create a random transition order:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>








          share|improve this answer


























          • great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

            – dfrankow
            Dec 31 '18 at 19:34











          • I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

            – Andrew Reid
            Dec 31 '18 at 19:35













          • will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

            – dfrankow
            Dec 31 '18 at 19:37






          • 1





            If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

            – Andrew Reid
            Dec 31 '18 at 19:39











          • FYI I ended up using this in github.com/dfrankow/d3maze.

            – dfrankow
            Jan 1 at 18:36














          4












          4








          4







          To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay(), you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:



          selection.transition()
          .delay(function(d,i) { return i * 100; })
          .attr(...


          Above and in the snippet below I've used the index:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          And below I've used the datum to create a random transition order:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>








          share|improve this answer















          To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay(), you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:



          selection.transition()
          .delay(function(d,i) { return i * 100; })
          .attr(...


          Above and in the snippet below I've used the index:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          And below I've used the datum to create a random transition order:






          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>








          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return i * 100; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>





          function draw_function() {
          var vis = d3.select("#graph")
          .append("svg")
          .attr("width", 200).attr("height", 200);

          // fill the_grid
          var shape=[10,10];
          var the_grid=;
          for (var idx = 0; idx < shape[0]; idx++) {
          var row = ;
          for (var jdx = 0; jdx < shape[1]; jdx++) {
          var val = (idx+jdx)/2;
          row.push(Math.floor(val)==val ? 1 : 0);
          }
          the_grid.push(row);
          }

          // fill nodes
          var rectwidth = 10;
          var nodes = ;
          for (var idx = 0; idx < the_grid.length; idx++) {
          for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
          var node = {
          delay: Math.random()*2000,
          x: idx * (rectwidth+1),
          y: jdx * (rectwidth+1),
          color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
          nodes.push(node);
          }
          }

          // draw nodes
          vis.selectAll("rect.nodes")
          .data(nodes)
          .enter()
          .append("svg:rect")
          .attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; })
          .attr("height", rectwidth)
          .attr("width", rectwidth)
          .attr("fill","white")
          .transition()
          .duration(1000)
          .delay(function(d,i) { return d.delay; })
          .attr("fill", function(d) { return d.color; })
          }

          // function has to execute after dom is loaded
          window.onload = draw_function

          <html>
          <head>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
          <div id="graph"/>






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 31 '18 at 19:36

























          answered Dec 31 '18 at 19:14









          Andrew ReidAndrew Reid

          17.7k32343




          17.7k32343













          • great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

            – dfrankow
            Dec 31 '18 at 19:34











          • I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

            – Andrew Reid
            Dec 31 '18 at 19:35













          • will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

            – dfrankow
            Dec 31 '18 at 19:37






          • 1





            If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

            – Andrew Reid
            Dec 31 '18 at 19:39











          • FYI I ended up using this in github.com/dfrankow/d3maze.

            – dfrankow
            Jan 1 at 18:36



















          • great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

            – dfrankow
            Dec 31 '18 at 19:34











          • I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

            – Andrew Reid
            Dec 31 '18 at 19:35













          • will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

            – dfrankow
            Dec 31 '18 at 19:37






          • 1





            If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

            – Andrew Reid
            Dec 31 '18 at 19:39











          • FYI I ended up using this in github.com/dfrankow/d3maze.

            – dfrankow
            Jan 1 at 18:36

















          great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

          – dfrankow
          Dec 31 '18 at 19:34





          great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.

          – dfrankow
          Dec 31 '18 at 19:34













          I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

          – Andrew Reid
          Dec 31 '18 at 19:35







          I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to none, I've updated it to white so that d3 can interpolate between start and end values without further modification){

          – Andrew Reid
          Dec 31 '18 at 19:35















          will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

          – dfrankow
          Dec 31 '18 at 19:37





          will it draw in nodes order, or do i have to set the delays to the right values to reveal them in order?

          – dfrankow
          Dec 31 '18 at 19:37




          1




          1





          If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

          – Andrew Reid
          Dec 31 '18 at 19:39





          If using the index of the node in the data array (i * time), the transitions will always start in same order as they are in the array.

          – Andrew Reid
          Dec 31 '18 at 19:39













          FYI I ended up using this in github.com/dfrankow/d3maze.

          – dfrankow
          Jan 1 at 18:36





          FYI I ended up using this in github.com/dfrankow/d3maze.

          – dfrankow
          Jan 1 at 18:36




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990545%2fhow-to-draw-a-grid-incrementally-in-d3%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Monofisismo

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas