我对D3.js和Javascript都很陌生。对不起,如果问一些愚蠢的话。
我刚刚浏览了D3的教程,现在可以绘制保存在 csv-file 中的所有数据。(由d3.csv
函数加载)
我很好奇,有可能逐一绘制点,而不是将它们全部绘制一次?
var dataset;
d3.csv("testcase.csv", function(data) {
dataset = data;
var w = $(window).width();
var h = $(window).height();
var svg = d3.select("body")
.append("svg")
.attr({
width: w,
height: h,
});
function draw(data){
var circle = svg.selectAll("circle")
.data(data);
circle.enter().append("circle")
.attr({
"cx": data["x"],
"cy": data["y"],
"r": data["r"],
"fill": "rgb(0,0,0)",
});
}
draw(dataset[0]);
var index = 1;
setInterval(function() {
if(index<dataset.length){
draw(dataset[index]);
index++;
}
}, 1500);
这是我在此刻绘制点的方法,在csv文件中它保存了点的坐标,以及它的半径。例如:
x,y,r
100,100,50
200,100,30
400,300,20
500,400,50
470,800,40
400,600,40
我尝试使用setInterval
函数让它逐个绘制点,但它没有绘制任何东西(包括应由draw(dataset[0])
触发的第一个)
而且当使用console.log
函数来检查值是否正确时,它似乎完全正常。
the output of console pad
出了什么问题?谢谢你的帮助:/
答案 0 :(得分:3)
继Matthew的回答之后,如果你使用d3过渡而不是setInterval,那么你不必建立一个循环来单独处理节点,也避免了他描述的问题(至少在第一次传递,稍后再添加节点,您将再次需要数据密钥)
var data = "x,y,r\n"+
"100,100,50\n"+
"200,100,30\n"+
"400,300,20\n"+
"500,400,50\n"+
"470,800,40\n"+
"400,600,40\n"
;
var dataset = d3.csv.parse (data);
var svg = d3.select("body")
.append("svg")
.attr({
width: 600,
height: 400,
});
var circle = svg.selectAll("circle")
.data(dataset);
circle.enter().append("circle")
.each (function (d,i) {
d3.select(this).transition()
.delay(i * 1200) // <- this does what you intended setinterval to do
.attr({
"cx": d.x,
"cy": d.y,
"r": d.r,
"fill": "rgb(0,0,0)",
});
});
;
答案 1 :(得分:0)
因此,您遇到了一个相当常见的逻辑错误,它是d3的新手。每次调用绘图函数时,都会重新绑定数据。然而,除了告诉d3关于新数据之外,这还消除了旧数据的d3内存。因此,你有效地告诉d3:这个新数据是真实的,忘记了我过去告诉你的任何数据。
好的,上面的内容有点过分了。
d3实际上并没有忘记你已经告诉过的内容。但是,它需要一种方法来了解什么是新的,已经存在的以及什么是旧的。为此,.data
根据数据数组中的索引为每个数据分配一个键。因为每次绑定一个元素时,它总是得到一个0的键。因此,d3从不认为你要求它绑定一些新的东西。
要解决此问题,请将关键功能传递给data
,as described in in the documentation。
您的代码应该看起来像:
function draw(data, key){
var circle = svg.selectAll("circle")
.data(data, function(d){ return key; });
circle.enter().append("circle")
.attr({
"cx": data["x"],
"cy": data["y"],
"r": data["r"],
"fill": "rgb(0,0,0)",
});
}
draw(dataset[0], 0);
var index = 1;
setInterval(function() {
if(index<dataset.length){
draw(dataset[index], index);
index++;
}
}, 1500);
这有道理吗?我强烈建议您仔细阅读文档。这是我学习的方式,而且随着文档的发展,它的布局非常好,易于理解,并且有很多例子。