如何在d3中增量绘制网格?

时间:2018-12-31 18:49:32

标签: d3.js

下面是一个HTML文件,该文件将绘制一个10x10的正方形网格,交替显示浅灰色和深灰色。它使用0或1填充称为the_grid的2d数组;然后用nodesxy填充一个名为color的1d数组;然后用d3绘制nodes。它们全部出现。他们看起来像这样:

grid of squares

我该如何按照nodes数组给出的顺序一次绘制nodes一次(即出现)(这样我可以绘制不同的图案,例如垂直划像,水平划像,什么)?

我尝试摆弄transition函数没有成功。它只是绘制整个网格并将其滑动到位。正方形在外观上并不会一一出现。

代码:

<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>

1 个答案:

答案 0 :(得分:4)

要错开从同一数据数组中同时输入的多个元素的转换,可以使用transition.delay(),可以指定一个常数(它将同时开始所有转换),也可以指定一个函数作为基础每个元素或其索引在基准面上的延迟:

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

在上面的代码段中,我使用了索引:

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"/>