2013-03-10 123 views
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); 
+0

看起来像是[line accessors]的问题(https://github.com/mbostock/d3/wiki/SVG-Shapes#wiki-line_x)。你能否更新你的代码来包含你如何初始化'line'变量? – 2013-03-10 12:22:35

+0

全部要点:https://gist.github.com/Majella/202df0a4a5a3ad20fb92 – Newbie 2013-03-10 12:55:32

回答

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/

结论

这是关于如何使嵌套和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是上面显示的形式,它具有keyvalues在顶层的而不是dateTimeTakenreading。因此,您最好使用selectedData这只是data过滤和保留数据结构。但是,如果要绘制不同的行(例如,使用mean),则应该定义一个具有不同访问器的新行d3.svg.line()行发生器。

+0

谢谢你 - 你是一个明星!:)我确实需要一条线的意思,这就是我遇到的困难。所以我需要定义一个新行,例如var meanline = d3.svg.line()。x(function(d){return x(d.key);})。y(function(d){return y(d。 values.mean);}); - 然后更新 - svg.select(“path.meanline”)。attr(“d”,line(newdata)); ??? – Newbie 2013-03-10 15:28:59

+0

你可能是指'svg.select(“path.meanline”)。attr(“d”,meanline(newdata));'但是,是的,看起来正确。 – 2013-03-10 15:53:22

+0

谢谢:)解析错误消失了,但由于某种原因只有y轴更新。数据没有使用sortKeys进行排序,而x域没有返回最大值 - 是否使用键值无法使用?更新的要点:https://gist.github.com/Majella/202df0a4a5a3ad20fb92 – Newbie 2013-03-10 16:58:04