2013-03-10 125 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