有人可以帮忙吗?我的数据按照从两个下拉列表中选择的值进行过滤 - 然后嵌套/汇总以获得这些相同值的每日平均值。我为下面的代码得到了“解析d错误的问题”。尽管filter和nest函数都返回了正确的数据 - 当我尝试将这些数据应用到折线图来更新它时会出现问题?
d3.select("#parameterType").on("change", function()
{
d3.select("#dateTimeTaken").on("change", function()
{
var selectedParameter = document.getElementById("parameterType").value;
var selectedMonth = document.getElementById("dateTimeTaken").value;
//filter data by selected parameter and month
var selectedData = data.filter(function(d) {
return d.parameterType == selectedParameter &&
+d.dateTimeTaken.getMonth() == (selectedMonth - 1);});
console.log(selectedData);//returning correct data
//get average reading for each day within selected month
var newdata = d3.nest()
.key(function(d) {return d3.time.day(d.dateTimeTaken);})
.sortKeys(d3.ascending)
.rollup(function(d)
{
return {
mean: d3.mean(selectedData, function(d) {return +d.reading;})};
})
.entries(selectedData);
console.log(newdata);//returning correct data
//UPDATE GRAPH
//not returning correct max values?
x.domain(d3.extent(newdata, function(d) { return d.key; }));
y.domain([0, d3.max(newdata, function(d) { return d.values; })]);
svg.select("path.line")
.attr( "d", line(newdata));
svg.select(".x.axis")
.transition()
.duration(750)
.ease("linear")
.call(xAxis);
svg.select(".y.axis")
.transition()
.duration(750)
.ease("linear")
.call(yAxis);
答案 0 :(得分:2)
在code that you posted中,导致上述问题的问题有两个。这两个问题似乎都源于对D3中数据如何嵌套和汇总的误解。
var newdata = d3.nest()
.key(function(d) {return d.dateTimeTaken;})
.sortKeys(d3.ascending)
.entries(data);
这会转换以下类型的对象:
var data = [{
parameterType: 'a',
dateTimeTaken: '2013-01-01 12:00:00',
reading: 100
}, {
parameterType: 'a',
dateTimeTaken: '2013-01-02 12:00:01',
reading: 101
}];
为:
[
{
"key": "2013-01-01 12:00:00",
"values": [
{
"parameterType": "a",
"dateTimeTaken": "2013-01-01 12:00:00",
"reading": 100
}
]
},
{
"key": "2013-01-02 12:00:01",
"values": [
{
"parameterType": "a",
"dateTimeTaken": "2013-01-02 12:00:01",
"reading": 101
}
]
}
]
values
字段是一个将原始数据条目累加在一起的数组。
rollup然后将数组作为参数values
,从这些数据计算聚合度量(在您的情况下为mean
),将其替换为数组中的数组键values
。
您的rollup
功能:
//AVERAGE READING FOR EACH DAY WITHIN SELECTED MONTH FOR SELECTED PARAMETER
// ...
.rollup(function(d) {
return {mean:d3.mean(selectedData, function(d) {return +d.reading;})};})
完全忽略了这个论点。我认为它应该是:
.rollup(function(d) {
return {mean:d3.mean(d, function(d_) {return +d_.reading;})};})
现在生成的数组会:
[
{
"key": "2013-01-01 12:00:00",
"values": {
"mean": 100
}
},
{
"key": "2013-01-02 12:00:01",
"values": {
"mean": 101
}
}
]
请注意,values
键中还有另一个包含mean
的对象。您将y
轴的范围计算为:
y.domain([0, d3.max(newdata, function(d) { return d.values; })]);
最大值不正确的原因是因为您要求d3计算objects
中values
的最大值。这种操作的结果是不明确的。相反,您应该要求最大值超过values.mean
:
y.domain([0, d3.max(newdata, function(d) { return d.values.mean; })]);
这可以产生正确的结果,如jsFiddle:http://jsfiddle.net/XLNeP/
所示这是关于如何使嵌套和汇总正常工作。现在解决其他一些问题。您的line
变量具有以下访问者:
var line = d3.svg.line()
.x(function(d) { return x(d.dateTimeTaken); })
.y(function(d) { return y(d.reading); });
这适用于你打电话的时间:
svg.append("path")
.attr("class", "line")
.attr("d", line(data));
但是,newdata
的格式如上所示,其顶级key
和values
而非dateTimeTaken
或reading
。因此,最好使用仅selectedData
过滤的data
并保留数据结构。但是,如果要绘制不同的行(例如,使用mean
),则应定义具有不同访问者的新d3.svg.line()
行生成器。