2016-09-16 18 views
1

私は、ユーザーがそれが必要その後、ここD3.js棒グラフのアニメーションが正しく

クリックバー

を削除すると言うAPタグをクリックするとD3.jsで棒グラフを持って出ません最も左のバーを取り除きます。アニメーションでは、バーが画面の左側に飛び出し、他のバーが正しい位置に配置されます。私が問題にしているのは、最も右の棒グラフが代わりに削除され、別の棒がグラフの外に押し出され、もはや見ることができなくなり、棒の値が切り替わるように見えるということです。ここでjsFiddle

もjavascriptの作成を実行しているコード、および棒グラフのアニメーションです:私はこの問題を再作成することができjsfiddleを作成

// chart dimensions 
var margin = { top: 20, right: 30, bottom: 20, left: 70 }, 
    width = $('#chart').width() - margin.left - margin.right, 
    height = $(window).height()/3.5 - margin.top - margin.bottom; 

// color palette for graph 
var colors = [ '#4398B5', '#ADC4CC', '#92B06A', '#E09D2A', '#DE5F32' ]; 

var dataset = [ 100, 200, 300, 400, 500 ]; 

var xScale = d3.scaleBand() 
       .domain(d3.range(dataset.length)) 
       .range([ 0, width ]) 
       .padding(0.1); 


var yScale = d3.scaleLinear() 
       .domain([ 0, d3.max(dataset) ]) 
       .range([ height, 0 ]); 


var xAxis = d3.axisBottom(xScale); 
var yAxis = d3.axisLeft(yScale); 

var svg = d3.select('#chart svg') 
      .attr('width' , width + margin.left + margin.right ) 
      .attr('height' , height + margin.top + margin.bottom) 
      .append('g') 
       .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

svg.selectAll('rect') 
    .data(dataset) 
    .enter() 
    .append('rect') 
     .attr('x', function (d, i) { 
      return xScale(i); 
     }) 
     .attr('width', xScale.bandwidth()) 
     .attr('fill', function(d, i) { 
      return colors[ i ]; 
     }) 
     .attr('y', function(d, i) { 
      return yScale(d); 
     }) 
     .attr('height', function(d) { 
      return height - yScale(d); 
     }); 

svg.append('g') 
    .attr('class', 'yAxis') 
    .attr('transform', 'translate(0, ' + (-1) + ')') 
    .call(yAxis); 

d3.select("p") 
     .on("click", function() { 

      dataset.shift(); 
      //Update scale domains 
      xScale.domain(d3.range(dataset.length)); 
      yScale.domain([ 0 , d3.max(dataset) ]); 

      //Select… 
      var bars = svg.selectAll("rect") 
          .data(dataset); 

      bars.transition() 
       .duration(500) 
       .attr("x", function(d, i) { 
        return xScale(i); 
       }) 
       .attr("y", function(d) { 
        return height - yScale(d); 
       }) 
       .attr("width", xScale.bandwidth()) 
       .attr("height", function(d) { 
        return yScale(d); 
       }); 

      bars.exit() 
       .transition() 
       .duration(500) 
       .attr("x", -xScale.bandwidth()) 
       .remove(); 
      }); 

すべてのヘルプをだろう大変感謝します。

ありがとうございます!

答えて

1

.datakey functionのd3ドキュメントのセクションを読んでください。

デフォルトでは、d3は要素インデックスをキー機能として使用します。あなたのデータが.shiftの場合、長さが1つ減少したため、最後のインデックスが終了要素であると考えます。これを修正する正しい方法は、各データの一部がユニークな識別子になるようにデータを変更することです。あなたは本当にデータがここに駆動されるようにしたいので、私はこのような何かをするだろう:

var dataset = [ 
{ 
    value: 100, 
    color: '#4398B5', 
    id: 1 
},{ 
    value: 200, 
    color: '#ADC4CC', 
    id: 2 
},{ 
    value: 300, 
    color: '#92B06A', 
    id: 3 
},{ 
    value: 400, 
    color: '#E09D2A', 
    id: 4 
},{ 
    value: 500, 
    color: '#DE5F32', 
    id: 5 
}]; 

あなたの重要な機能は次のようになります。

.data(dataset, function(d){ return d.id; }) 

注、私はデータにIDを追加しましたが、あなたは可能性ユニークな限り、色を使用しています。

改良されたデータ配列を持つrefactorをここに示します。

+0

わかりました。しかし、リファクタを使用しても、棒グラフ上のデータセットを切り替えるように見え、間違った棒が出ているように見えています。これはまだ '.shift'関数の産物ですか?代わりに '.splice'を使用してみました。そして、1つの要素を削除した新しい配列を作成しましたが、運がありませんでした。 – ans

+1

@ansの場合、あなたの更新関数で 'y'と' height'の計算が逆になります。上記のフィドルを更新しました。 – Mark

+0

うん、それだった!本当にありがとう! – ans

関連する問題