javascript - d3.js - 未捕获的类型错误 : Object has no method 'exit'

标签 javascript d3.js

我试图通过更改我提供给 d3 线函数的 lineData 数组,每 5 秒后绘制一系列线:

以下是相关代码的摘录:

var svg = d3.select("body").append("svg:svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .attr("id", "svgMain")
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .call(drag);

var lines = svg.append("g")
      .attr("id", "lines");

function changingLines() {
      lines.selectAll("line")
        .data(lineData)
        .enter().append("line")
        .attr("x1", function(d, i) { console.log(d[0][0]); return d[0][0];})
        .attr("y1", function(d, i) { console.log(d[0][1]); return d[0][1];})
        .attr("x2", function(d, i) { return d[1][0];})
        .attr("y2", function(d, i) { return d[1][1];})
        .style("stroke", "#000")
        .style("stroke-width", "0.5")
        .attr("class", "lines");

     lines.selectAll("line").exit().remove();
     setTimeout(changingLines, 2000);
 }

我每 2 秒使用不同的 lineData 数组值调用函数 changingLines()。

我收到错误:Uncaught TypeError: Object has no method 'exit

我做错了什么?

最佳答案

您实际上遇到了一些与此代码相关的问题。当您调用 changingLines , 唯一会更新其属性的元素是 enter 中的元素选择(调用 .enter() 返回 enter 选择`)。

请记住,默认情况下,.data()只会将元素添加到 enter如果您传递给它的数组中有新元素,则选择,例如

// Old data array:
var data = [1, 2, 3, 4];

// New data array:
var newData = [5, 6, 7, 8, 9];

/*
The first 4 elements in newData will replace the first 4 elements of oldData.
The number of new elements (which will be in the enter() selection) is only 1.
*/

您应该做的是保存由 data 计算的连接调用,并使用它来单独访问 enter , exit , 和 update选择。

var linesContainer = svg.append("g").attr("id", "lines");

function changingLines() {

    /* Compute the data join */
    var lines = linesContainer.selectAll("line").data(lineData);

    /* Enter */
    lines.enter().append("line");

    /* Exit */
    lines.exit().remove();

    /* Update */
    lines
         .attr("x1", function(d, i) { console.log(d[0][0]); return d[0][0];})
         .attr("y1", function(d, i) { console.log(d[0][1]); return d[0][1];})
         .attr("x2", function(d, i) { return d[1][0];})
         .attr("y2", function(d, i) { return d[1][1];})
         .style("stroke", "#000")
         .style("stroke-width", "0.5")
         .attr("class", "lines");

    setTimeout(changingLines, 2000);
}

这将删除旧的 line元素并添加新的 line元素更新属性和样式之前。

https://github.com/mbostock/d3/wiki/Selections#wiki-enter

The enter selection merges into the update selection when you append or insert. This approach reduces code duplication between enter and update. Rather than applying operators to both the enter and update selection separately, you can now apply them to the update selection after entering the nodes. In the rare case that you want to run operators only on the updating nodes, you can run them on the update selection before entering new nodes.

这也应该可以解决您无法调用 exit() 的问题.当你调用 lines.selectAll("line")第二次,您正在创建一个新选择,因此您将无法访问上一次加入时计算出的选择。

阅读并重读这篇文章:http://bost.ocks.org/mike/join/

关于javascript - d3.js - 未捕获的类型错误 : Object has no method 'exit' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13832625/

相关文章:

d3.js - 传递给d3.js强制刻度回调函数的 `e`参数是什么?

javascript - 是否有类似 node.js 的 Turbolinks 之类的东西?

javascript - 如何检测照片/视频是从相机拍摄的还是从 iphone safari 中的相机胶卷导入的

Javascript:从 XML 文件获取值

javascript - D3.js如何编写用户单击元素时出现的弹出框

javascript - 链式转换不会逐步触发

javascript - d3.js 树 - 为指定的子节点设置深度?

Javascript - 将数字变量拆分为函数

javascript - 请解决此错误 - Uncaught TypeError : Cannot read properties of undefined (reading 'map' )

javascript - D3/CSS Dom向上遍历/选择