2013-08-30 4 views
3

간단하고 업데이트 가능한 d3.js 막 대형 차트가 생성되었습니다. x 축을 제외하고는 정상적으로 작동합니다.d3.js 서수 축이 올바르게 업데이트되지 않았습니다.

차트에서 막대를 제거하면 해당 축 레이블이 제거되지 않습니다. removed bars first time with wrong axis

initial bars

하지만 두 번째로 막대를 제거 할 때, 첫 번째 실행에서 제거 된 바의 라벨은 축에서 제거됩니다.

removed bard second time with correct axis

여기에 일어나고, 그 이유는 무엇입니까?

var BarChart = function (config) { 

    var data, 
    svg, 
    xScale, 
    yScale, 
    yAxis, 
    xAxis; 

    svg = d3.select('#' + config.targetElement).append('svg'); 

    svg.attr("width", config.width + config.margin.left + config.margin.right) 
     .attr("height", config.height + config.margin.top + config.margin.bottom) 
     .attr("transform", "translate(" + config.margin.left + "," + config.margin.top + ")"); 

    xScale = d3.scale.ordinal(); 
    yScale = d3.scale.linear(); 

    xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickSize(-config.height, 0).tickPadding(6); 
    svg.append('g').classed('x-axis-group axis', true); 

    svg.append("g") 
     .classed("x axis", true) 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 


    // All methods and members defined here are public 
    return { 
     setData: function (newData) { 
      data = newData; 
      this.updateChart(); 
     }, 
     updateChart: function() { 
      var xDomain = data.map(function (d) { 
       return d.name; 
      }), 
       yDomain = data.map(function (d) { 
        return d.value; 
       }); 



      xScale.domain(xDomain) 
       .rangeRoundBands([config.margin.left, config.width], 0.05); 

      yScale.domain([0, d3.max(data, function (d) { 
       return d.value; 
      })]) 
       .range([config.height, 0]); 


      xAxis.scale(xScale) 
       .orient("bottom") 
       .tickSize(-config.height, 0) 
       .tickPadding(6); 

      var dataSections = svg.selectAll("g.bar") 
       .data(data, function (d) { 
       return d.name; 
      }); 


      // adding new bars 
      dataSections.enter() 
       .append('g') 
       .attr('class', 'bar') 
       .append("rect") 
       .attr("height", 0); 

      var transition = svg.transition().duration(750); 

      transition.selectAll("g.bar").select('rect') 
       .attr("x", function (d, i) { 
       return xScale(d.name); 
      }) 
       .attr("y", function (d) { 
       return yScale(d.value); 
      }) 
       .attr("width", xScale.rangeBand()) 
       .attr("height", function (d) { 
       return height - yScale(d.value); 
      }); 


      dataSections.exit().transition().remove(); 



      svg.select('.x.axis') 
       .transition() 
       .duration(500) 
       .attr({ 
       transform: 'translate(0,' + (config.height) + ')' 
      }) 
       .call(xAxis); 




     } 
    }; 
}; 

var margin = { 
    top: 20, 
    right: 20, 
    bottom: 30, 
    left: 40 
}, 
width = 960 - margin.left - margin.right, 
    height = 250 - margin.top - margin.bottom; 


amount = 15; 

function init() { 
    var margin = { 
     top: 20, 
     right: 20, 
     bottom: 30, 
     left: 40 
    }, 
    width = 400 - margin.left - margin.right, 
     height = 250 - margin.top - margin.bottom; 

    var chart = BarChart({ 
     targetElement: 'foo', 
     margin: margin, 
     width: width, 
     height: height 
    }); 

    setRandomData = function() { 
     var data = []; 
     for (var i = 0; i <= amount; i++) { 
      data.push({ 
       name: "a" + i, 
       value: Math.floor((Math.random() * 300) + 1) 
      }); 
     } 
     amount = amount - 5; 

     chart.setData(data); 
    } 
} 

init(); 
setRandomData(); 
setTimeout(setRandomData, 2000); 
setTimeout(setRandomData, 4000); 

답변

1

좋아, 내가 전혀 단서 왜 그러나이 줄 앞에

svg.select('.x.axis') 
    .transition() 
    .duration(500) 
    .attr({transform: 'translate(0,' + (config.height) + ')'}) 
    .call(xAxis); 

이동이 없다 : http://jsfiddle.net/vACua/4/

JS 코드는 다음과 같습니다

여기에 작동하는 데모를 참조하십시오 :

var transition = svg.transition().duration(750); 

은 의도 한대로 작동합니다. http://jsfiddle.net/Y274x/

관련 문제