javascript - 使用 key 时无法获取 d3 选择的更新数据

标签 javascript d3.js

我正在尝试使用 d3.js 创建排序算法的可视化。为此,我想创建几个具有不同半径的圆,然后在排序算法工作时将它们一一交换。尝试这样做时,我遇到了以下问题:当我更新与 d3 选择关联的数据,然后尝试使用 .data() 取回它时,我得到了未更改的数据(因为我没有更新它)。仅当我使用 key 函数跟踪对象时才会出现此问题。

代码如下。如果单击“检查”,您会在控制台中看到 [1, 3, 2],这是正确的初始状态。如果然后单击“do”,将调用update函数,并且圆圈将根据新数据更改其位置。但是,如果您再次单击“检查”,您仍然会得到 [1, 3, 2] 而不是预期的 [3, 2, 1]

那么,有两个问题:

  1. 为什么会有这样的行为?
  2. 如何克服这个问题,即从选择中获取更新的数据?

  
    function key(d) {
        return d
      }
    
    function update(data) { 
      return d3.select("#picture")
        .selectAll("circle")
        .data(data, key)
        .transition()
        .attr("cx", function(d, i) {return (i+1)*50;});
    }
    
    $(function() {
      d3.select("#picture")
        .selectAll("circle")
        .data([1, 3, 2], key)
        .enter()
        .append("circle")
        .attr("cx", function(d, i) {return (i+1)*50;})
        .attr("cy", 100)
        .attr("r", function(d) {return (d+1)*10;})
        .style("fill", "none")
        .style("stroke", "steelblue");
      
      $("#do_it").click(function() {
         update([3, 2, 1]);   
      });
      $("#check").click(function() {
         console.log(d3.select("#picture")
                  .selectAll("circle").data());
      });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
   <button id="check">check</button>
   <button id="do_it">do</button><br/>
   <svg id="picture" width=300 height=150></svg>

最佳答案

数据的顺序不会完全发生变化,因为您使用了 key 。如果您没有使用 key ,顺序就会改变。

圆圈是通过以下关系创建的:

  • 01 作为基准
  • 13 作为基准
  • 22作为基准。

每个数据都用作一个键来识别圆。当您更新数据时,这种关系也不会改变,因为您已经设置了 key 。

当您在更新(“执行”)功能后对数据进行 console.log 时,您不会获得有关圆的新位置的数据。事实上,当您在更新后 console.log 数据时,您会得到相同的结果:

  • 01 作为基准
  • 13 作为基准
  • 22作为基准。

这些不是圆圈的位置,而是它们创建的顺序。

但是,如果您将 console.log 放入 update 函数中,您可以看到位置正在发生变化:

console.log("circle at position " + i + ", data: " + d)

查看演示,单击“do”并查看与不同位置的圆圈关联的数据:

function key(d) {
        return d
      }
    
    function update(data) { 
      return d3.select("#picture")
        .selectAll("circle")
        .data(data, key)
        .transition()
        .attr("cx", function(d, i) {
        console.log("circle at position " + i + ", data: " + d)   
        return (i+1)*50;});
    }
    
    $(function() {
      d3.select("#picture")
        .selectAll("circle")
        .data([1, 3, 2], key)
        .enter()
        .append("circle")
        .attr("cx", function(d, i) {return (i+1)*50;})
        .attr("cy", 100)
        .attr("r", function(d) {return (d+1)*10;})
        .style("fill", "none")
        .style("stroke", "steelblue");
      
      $("#do_it").click(function() {
         update([3, 2, 1]);   
      });
      $("#check").click(function() {
         console.log(d3.select("#picture")
                  .selectAll("circle").data());
      });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
   <button id="check">check</button>
   <button id="do_it">do</button><br/>
   <svg id="picture" width=300 height=150></svg>

关于javascript - 使用 key 时无法获取 d3 选择的更新数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42419205/

相关文章:

javascript - 如何向铯 map 添加图标而不是点

javascript - 如何用简单的例子来理解 `interpolateTransformCss` 中的 `interpolateTransformSvg` 、 `d3-interpolate` ?

javascript - 在 D3.js 中设置标记结束箭头的颜色

d3.js - 着色 DC.JS Choropleth 图表

javascript - D3js 外部 JavaScript 文件

javascript - 如何在递归函数中保存递增的值 (Javascript)

javascript - 如何在 Node-RED Node 中使用 NPM 导入?

javascript - 我可以使用 underscore.js 进行多个分组吗?

javascript - 使用 ajax、php 和 javascript 验证通过后插入到数据库

html - Svg-与 d3 放置的foreignObject 不渲染