我试图通过改变我提供给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);
}
Run Code Online (Sandbox Code Playgroud)
我使用lineData数组的不同值每2秒调用一次函数changingLines().
我收到错误:Uncaught TypeError:Object没有方法'退出
我究竟做错了什么?
Wex*_*Wex 18
实际上你有这个代码的几个相关问题.当你调用时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.
*/
Run Code Online (Sandbox Code Playgroud)
你应该做的是保存参加由你来计算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);
}
Run Code Online (Sandbox Code Playgroud)
这将删除旧line元素并line在更新属性和样式之前添加新元素.
https://github.com/mbostock/d3/wiki/Selections#wiki-enter
在追加或插入时,输入选择会合并到更新选择中.这种方法减少了输入和更新之间的代码重复.您可以在输入节点后将其应用于更新选择,而不是将运算符分别应用于输入和更新选择.在极少数情况下,您只想在更新节点上运行运算符,您可以在更新选择之前运行它们,然后再输入新节点.
这也应该解决你无法打电话的问题exit().当您lines.selectAll("line")第二次呼叫时,您正在创建新选择,因此您无法访问上次加入时计算的选择.
阅读并重读这篇文章:http://bost.ocks.org/mike/join/