我是d3菜鸟尝试使用以下数据创建条形图:
date, fruit, qty
1/1/14, apple, 10
1/1/14, orange, 0
1/1/14, banana, 20
1/2/14, apple, 12
1/2/14, orange, 5
1/2/14, banana, 30
1/3/14, apple, 16
1/3/14, orange, 15
1/3/14, banana, 40
在这个条形图中,每个水果都会有一个条形,它会以qty
的高度增长,比如说,每天1秒(实时)(或csv的行) )。我没有尝试更新点击或任何其他互动。我希望这些酒吧自动增长。
我很容易使用静态数据渲染条形图,但我正在努力解析和循环数据。我引用了this example,但这有点过头了。
我试图使用以下代码解析csv:
var fruits;
d3.csv("faux_data.csv", function(error, data) {
var parse = d3.time.format("%m-%d-%y").parse;
exams = d3.nest()
.key(function(d) {return d.fruit; })
.entries(fruits = data);
exams.forEach(function(s) {
s.values
.forEach(function(d) { d.date = parse (d.date); d.qty = + d.qty; } );
});
});
然后我不知道如何使用此代码更新我正在创建的rect svgs:
var svgContainer = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height", 300);
var rectangles = svgContainer.selectAll("rect")
.data(fruits)
.enter()
.append("rect");
var rectangleAttributes = rectangles
.attr("x", function (d, i) { return (i * 55);})
.attr("y", function(d) { return (250 - d.qty);})
.attr("width", 50)
.attr("height", function(d) {return d.qty;});
有关d3和js如何处理csv数据的任何提示或明确解释(针对noob级别)将非常感激。
答案 0 :(得分:0)
您的目标应该是使用setTimeout
循环重复调用更新fruits
(或exams
)的函数,然后按照常规更新模式中的说明更新视图。像
d3.csv("faux_data.csv", function(error, data) {
setTimeout(function() {
fruits = ... // re-nest all the data
updateView() // render view based on the current values of fruits
}, 500)
});
我认为您可以按照常规更新模式的建议了解如何实施updateView()
。剩下的挑战是如何准备fruits
。
首先,使用.forEach
.rollup()
函数可以实现d3.nest
循环所做的事情。这不是强制性的,但它更清洁。 (请注意,您有d.qty = + d.qty
的错误,可能想要成为d.qty += d.qty
。)
以下是.rollup()
的外观 - 假设我没有错过任何内容,因为我没有在控制台中尝试过它......
fruits = d3.nest()
.key(function(d) {return d.fruit; })
.entries(fruits = data);
.rollup(function(values) {
return d3.sum(values, function(d) {
return d.qty;
});
});
这将总结所有时间内每个水果的所有数量。但是,由于您希望逐步增加时间,因此需要对每次setTimeout
次迭代求和的数量进行一些限制。由您决定如何定义限制标准,但这里有几个想法:
// This sums up the first 5 elements of each fruit.
// Instead of hard-coding the 5, you can set and
// increment a variable at each iteration
.rollup(function(values) {
return d3.sum(values.slice(0, 5), function(d) {
return d.qty;
});
});
或
// This sums up per fruit all values PRIOR to Jan, 1st 2015.
// Instead of hard-coding the date, you can set and increment
// a Date variable at each iteration
.rollup(function(values) {
return d3.sum(values, function(d) {
if(Number(d) < Number(new Date(2015, 0, 1)))
return d.qty;
else
return 0;
});
});
使用d3.sum
意味着JavaScript循环遍历每次迭代的所有数据。还有其他方法可以设置它,以便它不会遍历所有这些,因为实际上所需要的只是将新的d.qty
添加到先前计算的较旧d.qty
的总和中。但除非你的数据集很有意思,否则它不是一个大问题,可能不值得担心。无论如何,最好在你弄清楚如何以天真的方式进行优化之后进行优化。希望有所帮助。