私は人気のあるd3ライブラリのV3を使用しており、基本的に3つのトランジションが必要です。最初のトランジションは出口選択に適用され、2番目は更新選択に適用され、3番目は入力選択に適用されます。それらは、選択の1つが空の場合、それぞれの遷移がスキップされるようにチェーンする必要があります。つまり出口の選択がない場合、更新の選択はすぐに開始されます。これまでのところ、私はこのコードを思いついた(delay
関数を使用)。
_// DATA JOIN
var items = d3.select('#data').selectAll('.item');
items = items.data(data, function(d){
return d.Twitter_screenname;
});
// EXIT
items.exit().transition().duration(TRANSITION_DURATION).style('opacity', 0).remove();
// UPDATE
// Divs bewegen
items.transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 1)
.style('left', function(d, i) {
return positions[i].left + "px";
}).style('top', function(d, i) {
return positions[i].top + "px";
});
// ENTER
// Divs hinzufügen
var div = items.enter().append('div')
.attr('class', 'item')
.style('left', function(d, i) {
return positions[i].left + "px";
}).style('top', function(d, i) {
return positions[i].top + "px";
});
div.style('opacity', 0)
.transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 2)
.style('opacity', 1);
_
まず第一に、遷移を「スキップ」することはできません。第二に、delay
よりも良い方法があると思います。 http://bl.ocks.org/mbostock/3903818 を見てきましたが、何が起こっているのかよくわかりませんでした。
また、どういうわけか、items.exit().transition().duration(TRANSITION_DURATION).remove()
を書くだけではitems
は機能しません。おそらく、それらはSVG要素ではなくdiv
sであるためです。
承知しました。これが2つの方法です。
まず、明示的な delay を使用できます。次に、 selection.empty を使用して計算し、空の遷移をスキップします。 (これは、すでに持っているもののマイナーな変更にすぎません。)
var div = d3.select("body").selectAll("div")
.data(["enter", "update"], function(d) { return d || this.textContent; });
// 2. update
div.transition()
.duration(duration)
.delay(!div.exit().empty() * duration)
.style("background", "orange");
// 3. enter
div.enter().append("div")
.text(function(d) { return d; })
.style("opacity", 0)
.transition()
.duration(duration)
.delay((!div.exit().empty() + !div.enter().empty()) * duration)
.style("background", "green")
.style("opacity", 1);
// 1. exit
div.exit()
.style("background", "red")
.transition()
.duration(duration)
.style("opacity", 0)
.remove();
http://bl.ocks.org/mbostock/5779682
ここで注意が必要なのは、更新要素でトランジションを作成する必要があることですbefore入力要素でトランジションを作成します。これは、 enter.append 入力要素を更新選択にマージし、それらを別々に保ちたいためです。詳細については、 更新のみの移行の例 を参照してください。
または、 transition.transition から chain transitions 、および transition.each を使用して、これらの連鎖遷移を既存の選択に適用することもできます。 transition.eachのコンテキスト内で、selection.transitionは、新しい遷移を作成するのではなく、既存の遷移を継承します。
var div = d3.select("body").selectAll("div")
.data(["enter", "update"], function(d) { return d || this.textContent; });
// 1. exit
var exitTransition = d3.transition().duration(750).each(function() {
div.exit()
.style("background", "red")
.transition()
.style("opacity", 0)
.remove();
});
// 2. update
var updateTransition = exitTransition.transition().each(function() {
div.transition()
.style("background", "orange");
});
// 3. enter
var enterTransition = updateTransition.transition().each(function() {
div.enter().append("div")
.text(function(d) { return d; })
.style("opacity", 0)
.transition()
.style("background", "green")
.style("opacity", 1);
});
http://bl.ocks.org/mbostock/577969
後者はもう少し慣用的だと思いますが、transition.eachを使用して(デフォルトのパラメータで遷移を導出するのではなく)選択範囲に遷移を適用することは、広く知られた機能ではありません。