Javascript 使用D3多次绘制网格单元?

Javascript 使用D3多次绘制网格单元?,javascript,d3.js,time,slider,Javascript,D3.js,Time,Slider,我有一个tsv文件,有100000多行和3列:时间(升序,纳秒);对象颜色在此文件中,每个对象以不同的颜色和时间多次出现。我有一个网格,每个单元格代表一个物体(大约500+)和它们的实际颜色 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> svg { width: 90%

我有一个tsv文件,有100000多行和3列:时间(升序,纳秒);对象颜色在此文件中,每个对象以不同的颜色和时间多次出现。我有一个网格,每个单元格代表一个物体(大约500+)和它们的实际颜色

代码如下:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <style type="text/css">
      svg {
        width: 90%;
        height: 400px;
      }

    </style>
  </head>

  <body>
    <div id="vis">
      <button id="play-button" onclick="runMain()" style="margin-left: 2em; margin-top:2em;">Play </button>
      <label for="inputDelay">delay:</label>
      <input type="text" id="inputDelay" placeholder="20" value="20">
    </div>
    <svg></svg>
  </body>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://d3js.org/d3-timer.v1.min.js"></script>
  <link type="text/css" href="style.css" rel="stylesheet" />
  <script type="text/javascript">
    let nodeColors2 = ["#33b5e5", "#cc0000", "#669900", "#b4e56b", "#ffbb33", "#f540ff", "#aa18ff", "#16ffa9", "gray"]

    var playButton = d3.select("#play-button");
    createSVG();

    function createSVG(numParam) {
      var svg = d3.select("svg");

      var row = svg.selectAll(".row")
        .data(createGrid(numParam))
        .enter().append("g")
        .attr("class", "row");

      var column = row.selectAll(".square")
        .data(function(d) {
          return d;
        })
        .enter().append("rect")
        .attr("class", "square")
        .attr("id", function(d) {
          return "rect" + d.id
        })
        .attr("x", function(d) {
          return d.x;
        })
        .attr("y", function(d) {
          return d.y;
        })
        .attr("width", function(d) {
          return d.width;
        })
        .attr("height", function(d) {
          return d.height;
        })
        .style("fill", "#fff")
        .style("stroke", "#222");
    }

    /**prescan dataSet for further computation **/
    function fileScanning() {
      return new Promise(function(resolve, reject) {
        let parameterList = [];
        setTimeout(() => reject(new Error("setTimeoutError")), 1000);
        d3.tsv('testFile.tsv', function(data) {
          data.forEach(function(d) {
            if (!parameterList.includes(d.param)) {
              parameterList.push(d.param);
            }
          });
          resolve(parameterList.sort((a, b) => a - b));
        });
      });

    }

    /** create grid: cells get a squareID for parameters **/
    function createGrid(numParam = 600) {

      var num_columns = 50;
      var num_rows = Math.ceil(numParam / num_columns);
      var data = new Array();
      var xpos = 10; //starting xpos and ypos at 10 so the stroke will show when we make the grid below
      var ypos = 10;
      var width = 20;
      var height = 20;
      var squareID = 0;

      // iterate for rows
      for (var row = 0; row < num_rows; row++) {
        data.push(new Array());

        // iterate for cells/columns inside rows
        for (var column = 0; column < num_columns; column++) {
          data[row].push({
            x: xpos,
            y: ypos,
            width: width,
            height: height,
            id: "" + squareID
          });
          // each cell gets an ID for further linking to parameters
          squareID++;
          // increment the x position. I.e. move it over by 50 (width variable)
          xpos += width;
        }
        // reset the x position after a row is complete
        xpos = 10;
        // increment the y position for the next row. Move it down 50 (height variable)
        ypos += height;
      }
      return data;

    }

    async function runMain() {

      let delay = document.getElementById('inputDelay').value;
      d3.select("svg").selectAll(".row").remove();
      let parameterList = await fileScanning();
      createSVG(parameterList.length);

      /** run through dataSet and change nodecolors line for line**/
      d3.tsv('testFile.tsv', function(data) {
        for (let i = 0; i < data.length; i++) {
          setTimeout(() => {
            document.querySelector("#rect" + parameterList.indexOf(data[i].param)).setAttribute("style", "fill:" + nodeColors2[data[i].target] + "; stroke: black;");
          }, i * delay);
        }
      });
    }

  </script>

</html>
我想开始可视化(比如youtube:可变速度、滑块、可能播放/暂停、来回),当时间运行时,如果需要更新对象,它应该始终检查文件中的时间。因此,例如,在45秒前,所有对象都应表示其最新的颜色更新

一般来说,作为一名新手,尤其是在D3中,我想知道D3是否是一个好的选择,如果是,我的方法应该是什么样的,或者我是否应该使用D3来满足这些要求?我还没有完全理解更新、进入和退出,但我觉得这应该是答案。如果是这样,我不知道“倒带”的方法应该是什么样子,因为它不应该删除一个对象,而是在选择的时间之前用它的最新颜色重新绘制它

以下是关于plunker的最新信息,其中包含一个非常小的数据集,以便更好地理解。它应该是这样的(缺少youtube中的整个滑块功能)。但它不应该在绘画时使用setTimeout。我想使用tsv文件中的“实时”

最合适的来源是:。 我很难将日期方法更改为纳秒。 如果D3可以工作,你有什么帮助吗?既然我有点迷路了,你如何处理这一切


附言:我的第一个问题:有没有关于这个问题更好的标题的建议?我很乐意编辑我的问题,让每个人都觉得更舒服。

在答案中添加代码,而不是使用外部链接!它将帮助您的问题获得答案!这是我的第一个问题,真的有必要直接否决吗?我想没有小狗保护。。。我正在链接到Plunker,因为我需要上传一个本地csv文件作为数据集。我的主要问题是D3是否符合我的要求?我不是真的有一个特定的代码行显示,但我可以在这里张贴所有你建议。固定。还有,很抱歉。
time    param   target
5396736 0   0
21620736    307000  5
36134400    430000  7
38073600    369000  6
39064064    246000  4
39318784    123000  2
48853504    62000   1
58494720    1000    0
65408512    185000  3
87599616    431000  7
87736832    247000  4
90412544    308000  5
91149568    370000  6
96732416    63000   1
96962816    124000  2
116216064   2000    0
117147392   186000  3