1

任何人都可以帮忙吗?我的数据正在通过从两个下拉列表中选择的值进行过滤 - 然后嵌套/汇总以获得这些相同值的每天平均值。我收到以下代码的“问题解析 d 错误”。尽管过滤器和嵌套函数都返回了正确的数据 - 当我尝试将此数据应用于折线图以更新它时会出现问题吗?

    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);
4

1 回答 1

2

您发布的代码中,有两个问题导致了上述问题。这两个问题似乎都源于对数据在 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计算聚合指标,并将其放在键中的数组的位置meanvalues

你的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 计算objectsin的最大值values。这种操作的结果是不明确的。相反,您应该要求最大 over values.mean

y.domain([0, d3.max(newdata, function(d) { return d.values.mean; })]);

这可以工作并产生正确的结果,如以下 jsFiddle 所示:http: //jsfiddle.net/XLNeP/

结论

那是关于如何使嵌套和 rollupus 正常工作。现在来解决一些其他问题。您的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是上面显示的形式,它在顶层有keyand而不是or 。因此,您最好使用刚刚过滤并保留数据结构的 。但是,如果您想绘制不同的线(例如,使用),那么您应该使用不同的访问器定义一个新的线生成器。valuesdateTimeTakenreadingselectedDatadatameand3.svg.line()

于 2013-03-10T14:10:21.270 回答