D3の新機能。ここに示されている単純な棒グラフの例を変更しようとしています。データを更新しようとしていますが、基本的なものが欠けています。私は、Mike がオブジェクトの恒常性について語っているこちらをフォローしようとしています。具体的には、コードで次のことを達成しようとしています。
Key functions can be useful for improving performance independent of transitions. For example, if you filter a large table, you can use a key function to reduce the number of DOM modifications: reorder DOM elements in the update selection rather than regenerating them. We used this technique at Square to improve the performance of merchant analytics, and it’s one of the reasons that D3 is faster than most template frameworks.
(私の場合、キー関数は単純に「.data(data)」です (この投稿によると、これで問題ありません)
以下のコードは機能しますが、パフォーマンスに最も適しているとは思えません。たとえば、頻度「70」は両方のデータセットにありますが、データを「削除」することで、事実上再描画しています。(最初にデータを「削除」しないと、古いグラフが更新されたデータを取得するのではなく、別のグラフが描画されます)。以下のコードを変更してキー関数に準拠し、両方のデータセットに存在するデータが再描画されないようにするにはどうすればよいですか?
棒グラフの私のコード:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<button id="change" name="change">Update</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
$(document).ready(function () {
var old_data = [{"letter": "A","frequency": "50"},
{"letter": "B","frequency": "60"},
{"letter": "C","frequency": "70"}, // this also appears in new_data
{"letter": "D","frequency": "80"},
];
draw_chart(old_data);
$("#change").click(function(){
var new_data = [{"letter": "A","frequency": "10"},
{"letter": "B","frequency": "20"},
{"letter": "C","frequency": "70"}, // this appears in old_data
{"letter": "D","frequency": "30"},
];
var bar = d3.select('body').selectAll('svg').remove();// delete this line and you'll get multiple charts rather than just updating the data in the original chart
draw_chart(new_data);
});
});
</script>
<script>
function draw_chart(data){
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");
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 + ")");
data.forEach(function(d) {
d.frequency = +d.frequency;
});
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", height)
.attr("height","0")
.transition()
.delay(function(d, i) { return i*300 })
.duration(1000)
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); });
}
</script>