2016-04-29 18 views
0

私は、Mike Bostockの例に基づいていますが、複数のデータセット間を移行する、複数系列折れ線グラフを作成しようとしています。私はラインを入れ替えることにしましたが、ラインのラベルは消えてはいけません。 Screenshot at this link.D3は、移行時にmutli-series折れ線グラフのラベルを終了します。

さらに、ラインは奇妙な方法で移行しています。ほとんど同じように同じ行を拡張して新しい行を作成しているようです(Second screenshot at this link)

var line = d3.svg.line() 
 
     .interpolate("basis") 
 
     .x(function(d) { return x(d.Date); }) 
 
     .y(function(d) { return y(d.candidate); }); 
 

 
    var person = svg_multi.selectAll(".candidate") 
 
     .data(people); 
 

 
    var personGroups = person.enter() 
 
     .append("g") 
 
     .attr("class", "candidate"); 
 

 
    person 
 
     .enter().append("g") 
 
     .attr("class", "candidate"); 
 

 
    personGroups.append("path") 
 
     .attr("class", "line") 
 
     .attr("d", function(d) { return line(d.values); }) 
 
     .style("stroke", function(d) { return color(d.name); }); 
 

 
    var personUpdate = d3.transition(person); 
 

 
    personUpdate.select("path") 
 
     .transition() 
 
     .duration(1000) 
 
     .attr("d", function(d) { 
 
      return line(d.values); 
 
     }); 
 

 
    person 
 
     .append("text") 
 
     .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) 
 
     .attr("transform", function(d) { return "translate(" + x(d.value.Date) + "," + y(d.value.candidate) + ")"; }) 
 
     .attr("x", 3) 
 
     .attr("dy", ".35em") 
 
     .text(function(d) { return d.name; }); 
 

 
    person.selectAll("text").transition() 
 
     .attr("transform", function(d) { return "translate(" + x(d.value.Date) + "," + y(d.value.candidate) + ")"; }); 
 

 
    person.exit().remove();

答えて

0

あなたは一人一人にあなたがレンダリングするたびに新しいテキスト要素を追加している:ここでは

は(私はラベルの線を描き、追加)私のコードの関連する部分であります古いものを削除しないでください。おそらく、あなたが投稿したコードは、新しいデータでグラフを描画するたびに実行されるため、既存のものを更新するのではなく、毎回より多くのテキスト要素を使用することになります。あなたは "入力"選択に追加する必要があります。あなたはパス要素でこれを行いました。そのため、テキストをパスのようにする必要があります。あなたの例を私が変更したものを強調するコメントで更新しました。

var line = d3.svg.line() 
 
    .interpolate("basis") 
 
    .x(function(d) { return x(d.Date); }) 
 
    .y(function(d) { return y(d.candidate); }); 
 

 
var person = svg_multi.selectAll(".candidate") 
 
    // I added a key function here to make sure you always update the same 
 
    // line for every person. This ensures that when you re draw with different 
 
    // data, the line for Trump doesn't become the line for Sanders, for example. 
 
    .data(people, function(d) { return d.name}); 
 

 
var personGroups = person.enter() 
 
    .append("g") 
 
    .attr("class", "candidate"); 
 

 
// This isn't needed. The path and text get appended to the group above, 
 
// so this one just sits empty and clutters the DOM 
 
// person 
 
// .enter().append("g") 
 
// .attr("class", "candidate"); 
 

 
personGroups.append("path") 
 
    .attr("class", "line") 
 
    // You do this down below, so no need to duplicate it here 
 
    // .attr("d", function(d) { return line(d.values); }) 
 
    .style("stroke", function(d) { return color(d.name); }); 
 
    
 
// Append the text element to only new groups in the enter selection 
 
personGroups.append("text") 
 
    // Set any static attributes here that don't update on data 
 
    .attr("x", 3) 
 
    .attr("dy", ".35em"); 
 

 
var personUpdate = d3.transition(person); 
 

 
personUpdate.select("path") 
 
    .transition() 
 
    .duration(1000) 
 
    .attr("d", function(d) { 
 
    return line(d.values); 
 
    }); 
 

 
person.select("text") 
 
    // You don't have to do this datum call because the text element will have 
 
    // the same data as its parent, but it does make it easier to get to the last 
 
    // value in the list, so you can do it if you want 
 
    .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) 
 
    .attr("transform", function(d) { return "translate(" + x(d.value.Date) + "," + y(d.value.candidate) + ")"; }) 
 
    .text(function(d) { return d.name; }); 
 

 
// Remove this. You don't need it anymore since you are updating the text above 
 
// person.selectAll("text").transition() 
 
// .attr("transform", function(d) { return "translate(" + x(d.value.Date) + "," + y(d.value.candidate) + ")"; }); 
 

 
person.exit().remove();

は、あなたの質問への鍵は、本当にただ personGroups.append('text')ではなく person.append('text')をしていました。残りの部分は私が船外に出て、あなたのコードを改善して理解して維持しやすくする他の方法を指摘していました。

+0

ありがとうございました! – user3740848

関連する問題