我试图通过更改我提供给 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/