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

[라인 접근 코드] (https://github.com/mbostock/d3/wiki/SVG-Shapes#wiki-line_x)에 문제가있는 것 같습니다. 'line' 변수를 초기화하는 방법을 포함하도록 코드를 업데이트 할 수 있습니까? –

+0

전체 요점 : https://gist.github.com/Majella/202df0a4a5a3ad20fb92 – Newbie

답변

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 
}]; 

하기 : values 필드는 원래의 데이터 항목을 함께 축적 배열이다

[ 
    { 
     "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 
      } 
     ] 
    } 
] 

을 . rollupvalues의 배열을 인수로 취하여 합계 메트릭을 계산하고 (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;})};}) 

지금 결과 배열이 좋아하는 것 : 나는 그것을 읽어야 생각 values 키가 mean 포함되어 그 안에 또 다른 목적을 가지고

[ 
    { 
     "key": "2013-01-01 12:00:00", 
     "values": { 
      "mean": 100 
     } 
    }, 
    { 
     "key": "2013-01-02 12:00:01", 
     "values": { 
      "mean": 101 
     } 
    } 
] 

참고. 당신이 valuesobjects을 통해 최대 값을 계산하기 위해 D3를 요구하고 있기 때문에

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

최대 값이 잘못된 이유는 다음과 같습니다 당신과 y 축에 대한 범위를 계산합니다. 이러한 작업의 결과는 잘못 정의되어 있습니다. 대신 values.mean을 통해 최대 요청해야합니다 :

이 작동이 jsFiddle에서와 같이 정확한 결과를 생성
y.domain([0, d3.max(newdata, function(d) { return d.values.mean; })]); 

: http://jsfiddle.net/XLNeP/

결론

둥지를 만드는 방법에 대해습니다 그리고 롤 루퍼스가 올바르게 작동합니다. 이제 몇 가지 다른 문제를 해결하십시오.

svg.append("path") 
    .attr("class", "line") 
    .attr("d", line(data)); 

그러나, newdata는 최상위 수준에 keyvalues를 가지고 위의 형태이다 :

var line = d3.svg.line() 
.x(function(d) { return x(d.dateTimeTaken); }) 
    .y(function(d) { return y(d.reading); }); 

이것은 당신이 전화를 시간 동안 완벽하게 작동합니다 : 귀하의 line 변수는 다음과 같은 접근이있다 dateTimeTaken 또는 reading이 아닙니다. 따라서 selectedData은 단지 data으로 필터링하고 데이터 구조를 보존하는 것이 더 나을 것입니다. 그러나 다른 줄 (예 : mean)을 그리려면 다른 접근자를 사용하여 새로운 d3.svg.line() 라인 생성기를 정의해야합니다.

+0

고맙습니다 - 당신이 스타입니다! :) 나는 평균을위한 라인이 필요하며 그게 내가 어려움을 겪고있는 것입니다. 그래서 새로운 줄을 정의 할 필요가있다. var meanline = d3.svg.line() .x (function (d) {return x (d.key);}). values.mean);}); - 업데이트하려면 - svg.select ("path.meanline"). attr ("d", line (newdata)); ??? – Newbie

+0

아마'svg.select ("path.meanline"). attr ("d", meanline (newdata));를 의미 할 것이다. –

+0

고마워 :) 구문 분석 오류가 사라졌지만 몇 가지 이유로 y 축만 업데이트 중입니다. 데이터가 sortKeys를 사용하여 정렬되지 않고 최대 값을 반환하지 않는 x 도메인 - 키 값으로 익스텐트가 작동하지 않습니까? 업데이트 된 요지 : https : //gist.github.com/Majella/202df0a4a5a3ad20fb92 – Newbie