我是否错误地映射或嵌套了这些数据?
2013-04-15
4506
我正在寻找一些关于如何修复我的数据以条形图形式可视化的指针。我创建了一个随时间变化的数据的小倍数可视化。由于数据收集方式的性质,数据共享某些属性。例如,您可以在下面看到 .csv 的摘录,其中
group
和
date
重复:
group,date,totals
acid,1641,8438
acid,1641,0
acid,1641,0
beef,1641,977.85
beef,1641,0
beef,1641,0
beef,1641,164
beef,1641,5.25
bird,1641,121
bird,1641,0
bird,1641,12
bird,1641,1558
bird,1641,729
bird,1641,1680
bird,1641,0
bird,1641,343
bird,1641,3
bird,1641,2092
bird,1641,0
bird,1641,0
bird,1641,107
bird,1641,2679
bird,1641,167
bird,1641,649
boar,1641,41
boar,1641,13
cheese,1641,13
cheese,1641,22
cheese,1641,1071
cheese,1641,17195
(您可以在此处查看 整个数据集 。)
我遇到的问题是,无论何时共享
date
,它都会将数据堆叠在一起,而不是对
totals
列求和。例如,请参阅:
我遇到的问题是将数据显示为单个条形图。(我遇到了第二个问题,即 y 轴无法正确缩放)。我尝试使用
nest
来解决年份问题(这适用于
groups
),但我似乎无法通过
date
解决它。
到目前为止,这是我的代码:
var margin = {top: 20, right: 30, bottom: 30, left: 50},
width = 400 - margin.right - margin.left,
height = 150 - margin.top - margin.bottom,
parse = d3.time.format("%Y").parse;
// scales
var x = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([0, height]),
yscaled = d3.scale.linear().range([height, 0]);
// load data
d3.csv("revised.csv", function(error, data) {
// nest values by group
var groups = d3.nest()
.key(function(d) { return d.group; })
.entries(data);
// parse dates and numbers, assume values are sorted by date
// compute the maximum totals per group
groups.forEach(function(s) {
s.values.forEach(function(d) { d.date = parse(d.date); d.totals = +d.totals; });
s.maxtotals = d3.max(s.values, function(d) { return d.totals; });
});
// compute the minimum and maximum date across groups
x.domain([
d3.min(groups, function(s) { return s.values[0].date; }),
d3.max(groups, function(s) { return s.values[s.values.length - 1].date; })
]);
// y.domain([0, d3.max(data, function(d) { return d.totals; })]);
// add an SVG element for each group
var svg = d3.select("body").selectAll("g")
.data(groups)
.enter().append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var canvas_g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.each(function(d) {
var g = d3.select(this);
g.append("g");
// .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
y.domain([0, d3.max(d.values, function(r) { return r.totals; })]);
yscaled.domain([0, d3.max(d.values, function(r) { return r.totals; })]);
// Draw the charts.
g.selectAll("rect.aevents")
.data(d.values)
.enter().append("rect")
.attr("height", function(p) {return y(p.totals)})
.attr("width", 5)
.attr("x", function(p, q) {return x(p.date)})
.attr("y", function(p) {return height - y(p.totals)})
// .on("click", function(p) {console.log(p.date)})
.attr("class", "bar");
});
// draw x axis
canvas_g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
// draw y axis
canvas_g.append("g")
.attr("class", "y axis")
.call(d3.svg.axis().scale(yscaled).orient("left"));
// add a small label for the group name
svg.append("text")
.attr("x", width + 40)
.attr("y", height + 15)
.attr("text-anchor", "end")
.text(function(d) { return d.key; });
});
是否有其他方法可以循环遍历数据?或者,我需要以某种方式重组数据吗?提前谢谢您!
1个回答
首先,您可以阅读
此
答案,如果您想了解有关
d3.nest()
的更多信息,它将对您有所帮助。
对于您的问题,一个好方法是首先使用
d3.nest()
嵌套元素,然后将组映射到所需的形式。 给出:
function formatData(inputData){
var array = d3.nest()
.key(function(d){return d.group})
.key(function(d){return d.date})
.entries(inputData)
.map(function(d){
var group = d.key
var values = d.values.map(function(dd){
var date = dd.key
var total = 0
dd.values.forEach(function(ddd){
total = total + ddd.totals
})
return {date:date, totals:total}
})
return {'group':group, 'values':values}
})
obj = {}
array.forEach(function(d){
obj[d.group] = d.values
})
return obj
}
其中
inputData
是使用
d3.csv()
加载的数据。这样,您就可以充分利用
nest()
和 `map()``
如果您只想为牛肉绘制条形图,现在可以执行以下操作:
var beefData = formatData(myInput).beef
jsFiddle: http://jsfiddle.net/chrisJamesC/FJmMD/3/
Christopher Chiche
2013-04-16