2016-05-07 10 views
0

多かれ少なかれ表示する要素と新しい値を持つことができる新しいデータで円グラフを更新しようとしています。アークを削除して値を更新すると(要素の数が同じ)、OKです。d3.js円グラフに要素を追加する

新しいアークを追加するときに問題があります。パイが遷移しますが、新しいアークがあるはずの空白が残っていて、円の外側にいくつかのアークが描画されます。ここで

は、私はパイ(ommitting arcTween機能、マウスオーバー、クリックなど)

svg.attr('width', width).attr('height', height); 

    let pie = d3.layout.pie() 
      .value(function(d) { return d; }) 
      .sort(null); 

    let arc = d3.svg.arc() 
      .innerRadius(innRadius) 
      .outerRadius(outRadius); 

    svg.append('g') 
     .attr('class', 'donut-chart') 
     .attr('transform', 'translate(' + (width/2) + ',' + (height/1.75) +')'); 

    svg.select('.donut-chart') 
     .selectAll('.donut-arc') 
     .data(pie(values)) 
     .enter() 
     .append('g') 
     .attr('class', 'donut-arc _selected_'); 

    svg.selectAll('.donut-arc') 
     .append('path') 
     .attr('fill', function(d, i) { 
      if (scale === 'linear') return color(d.value); 
      return color(labels[i]); 
     }) 
     .attr('d', arc) 
     .each(function(d) { this._current = d; }); 

    svg.selectAll('.donut-arc') 
     .append('text') 
     .attr('class', 'labelText') 
     .attr("x", function(d) { 
      var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2; 
      d.cx = Math.cos(a) * (outRadius + 75); 
     return d.x = Math.cos(a) * (outRadius + 30); 
     }) 
     .attr("y", function(d) { 
      var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2; 
      d.cy = Math.sin(a) * (outRadius + 75); 
      return d.y = Math.sin(a) * (outRadius + 20); 
     }) 
     .text(function(d, i) { 
      return labels[i]; 
     }) 
     .style("text-anchor", function(d) { 
     var rads = ((d.endAngle - d.startAngle)/2) + d.startAngle + 10; 
     if ((rads > 7 * Math.PI/4 && rads < Math.PI/4) || (rads > 3 * Math.PI/4 && rads < 5 * Math.PI/4)) { 
      return "middle"; 
     } else if (rads >= Math.PI/4 && rads <= 3 * Math.PI/4) { 
      return "start"; 
     } else if (rads >= 5 * Math.PI/4 && rads <= 7 * Math.PI/4) { 
      return "end"; 
     } else { 
      return "middle"; 
     } 
     }); 

    svg.selectAll('path').transition().attrTween("d", arcTween); 

を作成する方法であり、これは私がパイ更新方法次のとおりです。

let paths = svg.datum(values).selectAll('path').data(pie); 
    let textLabels = svg.selectAll('.labelText').data(pie(values)); 

    paths.enter() 
     .append('path') 
     .attr('fill', function(d, i) { 
      if (scale === 'linear') return color(d.value); 
      return color(labels[i]); 
     }) 
     .attr('d', arc) 
     .each(function(d) { this._current = d; }); 

    textLabels.enter() 
     .append('text'); 

    paths.transition() 
     .duration(1000) 
     .attrTween('d', arcTween); 

    textLabels.transition() 
     .duration(1250) 
     .attr("x", function(d) { 
      var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2; 
      d.cx = Math.cos(a) * (outRadius + 75); 
      return d.x = Math.cos(a) * (outRadius + 30); 
     }) 
     .attr("y", function(d) { 
      var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2; 
      d.cy = Math.sin(a) * (outRadius + 75); 
      return d.y = Math.sin(a) * (outRadius + 20); 
     }) 
     .style("text-anchor", function(d) { 
     var rads = ((d.endAngle - d.startAngle)/2) + d.startAngle + 10; 
     if ((rads > 7 * Math.PI/4 && rads < Math.PI/4) || (rads > 3 * Math.PI/4 && rads < 5 * Math.PI/4)) { 
      return "middle"; 
     } else if (rads >= Math.PI/4 && rads <= 3 * Math.PI/4) { 
      return "start"; 
     } else if (rads >= 5 * Math.PI/4 && rads <= 7 * Math.PI/4) { 
      return "end"; 
     } else { 
      return "middle"; 
     } 
     }) 
     .text(function(d, i) { 
      return labels[i]; 
     }); 

    paths.exit().remove(); 
    textLabels.exit().remove(); 

    svg.transition().attr({width: width, height: height}); 

を私は間違って何をしていますか?

この円グラフは、エンバー・コンポーネントであり、その完全なコードはhere

を見つけることができ、hereあなたが働いアプリを見つけることができます。任意の地区をクリックして円グラフを表示します。

+4

これを実際のフィドルに置くことができれば、より良い回答が得られます。 – Cyril

+0

申し訳ありませんが、フィドルを作ったことはありません。アプリのURLをリンクしていますので、動作していることがわかります。 – ElXaxe

+0

おそらく、パイを作成して更新するための別のコードは必要ありません。ここのコードは事実上同一で、データを取り込み、パイを更新または更新する単一の関数として書き直すことができると思います。入力要素、更新要素、および終了要素の選択を使用して、新規および更新要素のさまざまな動作を制御します。 https://bost.ocks.org/mike/join/これを行うと問題が解消されるか、少なくとも把握が容易になります。 –

答えて

0

私はすでに解決策を見つけました!

パイに表示される新しいアークの中心を見つけるための変換が欠けていました。また、私は適切な要素を選択していませんでした。たとえば:selectAll( '。labelText')が間違っていました。新しいデータを入力するには、selectAll( 'text')を使用することをお勧めします。

すべてのお返事ありがとうございます!

関連する問題