2016-07-16 10 views
0

既存のd3棒グラフに新しいバーを追加してリアルタイムグラフにしたいと考えています。カスタムバー幅のリアルタイムd3棒グラフ

バーが更新されているのが見えますが、バーが再調整したときにラベルがアラインメントしていません。

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

var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width], .1); 

var y = d3.scale.linear() 
    .range([height, 0]); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .ticks(10, "%"); 

var svg = d3.select("body").append("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.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 

svg.append("g") 
    .attr("class", "y axis") 
    .append("text") // just for the title (ticks are automatic) 
    .attr("transform", "rotate(-90)") // rotate the text! 
    .attr("y", 6) 
    .attr("dy", ".71em") 
    .style("text-anchor", "end") 
    .text("Frequency"); 

function draw(data) { 
    x.domain(data.map(function(d) { 
    return d.letter; 
    })); 
    y.domain([0, d3.max(data, function(d) { 
    return d.frequency; 
    })]); 
var labels = svg 
    .selectAll(".bartext") 
    .data(data, function(d) { 
     return d.letter; 
    }); 
labels 
.exit() 
.remove(); 

labels 
    .enter() 
    .append("text") 
    .attr("class", "bartext") 
    .attr("text-anchor", "middle") 
    .attr("fill", "black") 
    .attr("x", function(d, i) { 
    return x(d.letter) + 7.5; 
    }) 
    .attr("y", function(d, i) { 
    return height + 15; 
    }) 
    .text(function(d, i) { 
    return d.letter; 
    }); 
    svg.select(".y.axis").transition().duration(300).call(yAxis) 

    var bars = svg.selectAll(".bar").data(data, function(d) { 
     return d.letter; 
    }) 
    bars.exit() 
    .transition() 
    .duration(300) 
    .remove(); 

    bars.enter().append("rect") 
    .attr("class", "bar"); 

    bars.transition().duration(300).attr("x", function(d) { 
     return x(d.letter); 
    }) 
    .attr("width", 15) 
    .attr("y", function(d) { 
     return y(d.frequency); 
    }) 
    .attr("height", function(d) { 
     return height - y(d.frequency); 
    }); 
} 
var data1 = [{ 
    "letter": 'A', 
    "frequency": .00167 
}]; 

var data2 = [{ 
    "letter": 'A', 
    "frequency": .01167 
},{ 
    "letter": 'I', 
    "frequency": .01477 
}]; 

draw(data1); 

setTimeout(function() { 
    draw(data2); 
}, 2000); 

https://jsfiddle.net/foh7cgst/

答えて

2

ここselection.enter() documentationの関連部分です:。

VAR update_sel = svg.selectAll( "円")は、データ(データ)

update_sel.attr(/*古い要素のみを操作する* /)

update_sel.enter()。append( "circle")。attr(/ * opera TEの新しい要素に のみ* /)

update_sel.attr(/ *古いものと新しい要素を操作* /)

update_sel.exit()。/)(削除*を入力し、更新終了を完了パターン */

表示されているように、入力選択に追加すると、後続の操作は追加された新しい要素のみを対象とします。

新しい要素と古い要素の両方を対象にする場合は、ノードを入力した後で更新選択を操作する必要があります。

そうで、draw関数内で、あなたの例のコードを使用して、この:この代わりの

labels.enter().append("text") 
    .attr("class", "bartext") 
    .attr("text-anchor", "middle") 
    .attr("fill", "black") 
    .attr("y", height + 15); 

labels 
    .attr("x", function(d) { 
    return x(d.letter) + 7.5; 
    }) 
    .text(function(d) { 
    return d.letter; 
    }); 
+0

オハイオ州私の悪いものはここで問題を理解しています。 –

+0

バーロジックはラベルロジックとは異なります。最初に 'bars()'に 'enter()。append()'を、**その後は 'old'と' new'の両方の 'bars'をトランジションして配置します。 – Ashitaka

+1

Btwは、この動作が完全にはっきりしないため、新しいD3バージョンで変更されました。詳細については、Mike Bostockが最近この記事に関する素晴らしい記事を書いています。https://medium.com/@mbostock/what-makes-software-good-943557f8a488#708a – Ashitaka

1

labels 
    .enter() 
    .append("text") 
    .attr("class", "bartext") 
    .attr("text-anchor", "middle") 
    .attr("fill", "black") 
    .attr("x", function(d, i) { 
    return x(d.letter) + 7.5; 
    }) 
    .attr("y", function(d, i) { 
    return height + 15; 
    }) 
    .text(function(d, i) { 
    return d.letter; 
    }); 

labels.enter().append("text") 
    .attr("class", "bartext") 
    .attr("text-anchor", "middle") 
    .attr("fill", "black") 
    .attr("x", function(d, i) { 
    return x(d.letter) + 7.5; 
    }) 
    .attr("y", function(d, i) { 
    return height + 15; 
    }) 
    .text(function(d, i) { 
    return d.letter; 
    }); 

は、このように変更する必要がありますこれを行う:

labels 
    .enter() 
    .append("text") 
    .attr("class", "bartext"); 
    //update all the bar text. 
    svg 
    .selectAll(".bartext").attr("text-anchor", "middle") 
    .transition().duration(300) 
    .attr("fill", "black") 
    .attr("x", function(d, i) { 
     return x(d.letter) + 7.5; 
    }) 
    .attr("y", function(d, i) { 
     return height + 15; 
    }) 
    .text(function(d, i) { 
     return d.letter; 
    }); 

最初のケースでは、属性が新しいデータに対してのみ更新され、更新されたデータはDOMに更新されないため、機能しませんでした。

作業コードhere

+1

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

関連する問題