2014-06-13 6 views
0

"values"라는 데이터 배열에 대한 히스토그램을 생성하는 jsFiddle here에 몇 가지 코드가 있습니다. 그게 다 잘되고 잘됐다.D3로 막대 그래프 애니메이션하기

"newData"라는 새로운 데이터 배열로이 막대 그래프를 업데이트하려고 할 때 문제가 발생합니다. 나는 enter(), update(), exit() D3 전략을 고수하려고 노력하고 있습니다. 애니메이션은 실제로 발생하지만 바이올린으로 볼 수 있듯이 모든 것을 오른쪽 상단 모서리에 밀어 넣습니다. 누군가이 코드의이 부분 (업데이트)에서 내가 잘못하고있는 것을 지적 할 수 있습니까?

//Animations 
d3.select('#new') 
    .on('click', function(d,i) { 
    var newHist = d3.layout.histogram().bins(x.ticks(bins))(newData); 

    var rect = svg.selectAll(".bar") 
    .data(values, function(d) { return d; }); 

    // enter 
    rect.enter().insert("g", "g") 
    .attr("class", "bar") 
    .attr("transform", function(d) { return "translate(" + x(d) + "," + y(d) + ")"; }); 

    rect.enter().append("rect") 
    .attr("x", 1) 
    .attr("width", w) 
    .attr("height", function(d) { return y(d); }); 
    rect.enter().append("text") 
    .attr("dy", ".75em") 
    .attr("y", 6) 
    .attr("x", x(histogram[0].dx)/2) 
    .attr("text-anchor", "middle") 
    .text(function(d) { return formatCount(d); }); 

    // update  
    svg.selectAll('.bar') 
    .data(newHist) 
    .transition() 
    .duration(3000) 
    .attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; }); 
    svg.selectAll("rect") 
    .data(newHist) 
    .transition() 
    .duration(3000) 
    .attr("height", function(d) { return height - y(d.y); }); 
    svg.selectAll("text") 
    .data(newHist) 
    .transition() 
    .duration(3000) 
    .text(function(d) { return formatCount(d.y); }); 
    // exit 
    rect.exit() 
    .remove(); 
}); 

코드 전체가 위에 링크 된 JSFiddle에 있습니다. 감사! 위의 코드와 바이올린을 보면

답변

1

, 몇 가지 나를 밖으로 뛰어 :

  • (라인 85) 당신은 여전히 ​​원래의 데이터
  • (라인 105, 115) 당신은 구속력을 바인딩 데이터를 여러 번 입력
  • (줄 99) 원래의 막대 그래프 변수를 새 데이터로 업데이트하지 않고 계속 참조 함
  • 단일 변경 데이터에 대해 여러 개의 바인드/추가/업데이트/제거 패턴을 선언하고 있습니다.

올바른 길을 가고 있지만 데이터가 변경 될 때 업데이트해야하는 항목과 데이터가 변경 될 때 업데이트/신고해서는 안되는 항목을 구별해야합니다. d3 패턴 (바인딩, 추가, 업데이트, 제거)을 한 번만 선언하면됩니다. 업데이트 된 데이터 세트에서 작동합니다.

그래서 makeHist (values) 함수 외부에서 선언 할 수있는만큼 선언하고 함수 내부에서 변경된 데이터가 필요한 코드 만 가지고 있어야합니다. 여기에는 이전에 선언 된 척도의 도메인과 범위를 수정하는 작업이 포함됩니다. 그런 다음 온 클릭 함수는 단순히 새로운 데이터로 makeHist 함수를 다시 호출 할 수 있습니다. 하지만, 주로 작업 업데이트 바이올린, 그것은 정리 약간의 필요있어 여기

// generate data 

// declare everything that can be static 
// (add svg to dom, declare axes, etc) 

// function that handles everything that new data should modify 
function makeHist(values) { 

    // modify domains of axes, create histogram 

    // bind data 
    var rect = svg.selectAll('rect') 
     .data(histogram); 

    // add new elements 
    rect.enter().append('rect'); 

    // update existing elements 
    rect.transition() 
     .duration(3000) 
     .attr('transform', '...'); 

    // remove old elements 
    rect.exit().remove(); 

} 

// generate initial histogram 
makeHist(initialValues); 

// handle on click event 
d3.select('#new') 
    .on('click', function() { 
    makeHist(newData); 
}); 

:

다음은 대략적인 윤곽의

http://jsfiddle.net/spanndemic/rf4cw/

스포일러 경고 : 두 개의 데이터 세트가 때로 믿을 수 ' 다른 모든 것