D3并更新多维数组的元素

时间:2016-01-20 06:14:05

标签: javascript d3.js rxjs frp

我们说我有一个名为state的名为[[0,1,0],[1,1,0],[1,2,1]]的二维数组。该阵列的成员不断更新。我有D3使用以下代码成功渲染数组的每个成员:

function view(state)
  const vis = d3.select('body')
                .selectAll('div')
                .data(state)
                .enter()
                  .append('div')
                  .attr('style', 'display: flex')
                  .selectAll('span')
                  .data((d,i) => d)
                  .enter()
                    .append('span')
                    .text(d => d)
  return vis
}

现在考虑每次view更改时调用此state函数。如何让D3仅重新渲染自上次渲染以来已更改的元素?目前,页面最初呈现,但D3从不重新呈现任何元素,尽管在每次状态更改时都会调用view函数。

如果您想查看完整的来源,我发布了here

2 个答案:

答案 0 :(得分:1)

是的,要处理这种情况,您需要使用正在执行的enter 来创建新元素,并exit删除当前数组中没有的任何元素

我建议你这样做:

function view(state)
  var visData = d3.select('body')
                .selectAll('div')
                .data(state, function(d){/*uniquely identify each element in array*/return d;});

  const vis =  visData.enter()
                  .append('div')
                  .attr('style', 'display: flex')
                  .selectAll('span')
                  .data((d,i) => d)
                  .enter()
                    .append('span')
                    .text(d => d);
  //remove the unnecessary data divs.
  visData.exit().remove();

  return vis
}

进一步输入exit read

答案 1 :(得分:0)

当您想要渲染数据时,有两种情况:添加新视图元素(div,span和文本)时以及更新数据(文本)时。在您的代码中,您只完成了第一步。你应该做第二个。

d3.js提供两种情况的选择。当你写

var div = d3.select('body').selectAll('div');

您获得了视图中已存在的内容。但是如果你添加.enter(),即

var div = d3.select('body').selectAll('div').enter();

已经是第二种情况了。你正在获得尚不存在的东西,应该被创造出来。

由于您的数据正在发生变化,您应该将代码分为两部分:视图创建,视图更新。

以下是a JSFiddle example如何为您的代码完成。可以改进示例,并且可以将创建/更新代码部分分开并放入相应的函数see there

无论如何,我建议您阅读d {j}的general update pattern