仅更新已修改基础绑定数据的SVG元素

时间:2017-11-09 15:55:23

标签: d3.js

我有一个使用d3 v4的力模拟图。每个节点都绑定到一些数据,我用它们来确定每个节点的半径。

底层绑定数据会定期更新,对于某些节点,它会更改,而对于其他节点,它会保持不变。

我希望能够仅选择绑定数据发生变化的DOM元素,以便我可以在图表上突出显示这些元素。

例如,假设最初我的数据(绑定到forceSimulation节点)是:
data = [{id: 1, type: 0}, {id: 2, type: 1}] 然后更新为:
data = [{id: 1, type: 1}, {id: 2, type: 1}] 我希望能够只选择与id = 1对应的DOM元素,以便我可以暂时进行颜色更改。

更新选择包含id = 1和id = 2 - 我可以维护先前数据值的内部映射并进行比较,但这似乎效率低下。

谢谢, 亚当

1 个答案:

答案 0 :(得分:1)

如果可以检查单个基准属性以查看绑定数据是否已更改,则可以使用selection.property和自定义属性(如type)将该属性作为属性进行跟踪。附加数据时,您可以非常轻松地定义属性:

  .append("circle")
  .property("type",function(d) { return d.type; });

然后,在更新时,您可以根据与属性匹配或不匹配的数据进行过滤:

  circles.data(newdata)
    .filter(function(d) {
      return d.type != d3.select(this).property("type")
    })

此过滤器将返回已更改其类型的元素。现在我们可以重新分配属性以反映新类型并转换那些过滤后的元素。

下面的代码段应该证明这一点,数据只是一个或两个(用蓝色和橙色表示),用于设置属性类型。点击svg更新数据,只有那些改变其基准的圆圈会暂时改变它们的半径,同时也会改变它们的颜色以反映它们的新数据。

var svg = d3.select("body")
  .append("svg")
  .attr("width",400)
  .attr("height",400);
  
var circles = svg.selectAll("circle")
  .data(data())
  .enter("circle")
  .append("circle")
  .attr("cy",function(d,i) {
    return Math.floor(i/5) * 40 + 20;
  })
  .attr("cx", function(d,i) {
    return i%5 * 40 + 20
  })
  .attr("r", 8)
  .attr("fill",function(d) { return (d) ? "steelblue" : "orange"})
  .property("type",function(d) { return d; });
  
// update on click:
svg.on("click", function() {
  circles.data(data())
    .filter(function(d) {
      return d != d3.select(this).property("type") // filter out unchanged data
    })
    .property("type",function(d) { return d; })  // update to reflect new data
    .transition()
    .attr("r", 20)
    .attr("fill","crimson")
    .duration(500)
    .transition()
    .attr("fill",function(d) { return (d) ? "steelblue" : "orange" })
    .attr("r",8)
    .duration(500);
})
  

function data() {
  var output = [];
  d3.range(20).map(function(d) {
    output.push(Math.round(Math.random()));
  })
  return output;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

相关问题