d3を学ぶ上で一番難しいのはenter、update、exitの関係でしょう。この中で、updateは特に明示するわけではないのも混乱の元です。
このページでは、復習も兼ねてそれぞれの役割を確認してみます。
まずは、datasetの要素数に合わせてdivとテキストを作成するサンプルから始めます。
enterとupdate
すでに、追加と削除ボタンが付いているのでこれを利用して、まずは新しくdatasetの要素数を増やしてみます。
//クリックするとdatasetを更新して要素数を7にする////////////////////
d3.select(".add")
.on("click", function() {
//datasetの新しい値
dataset = [ 5, 10, 15, 20, 25, 30, 35 ];
var divs = body.selectAll("div") //divのDOM要素が7になるように選択し直す。
.data(dataset); //データの要素数をカウントし抽出。updateセレクションに入る
//enterセレクション。DOM要素がデータの要素数より少ない場合は新しく空のDOM要素を作る。
divs.enter()
.append("div") //新しく作ったDOM要素にdivを追加。
.text(function(d){ //divの中にテキストを追加。
return "新しい数値は" + d + "になります";
})
.style("color", "blue"); //全てのp要素に適用
});
このコードのポイントは、.data(dataset)以降です。
まず、データの要素数をカウントし抽出します。
.data(dataset)
次に、.enter()で、DOM要素がデータの要素数より少ない場合は新しく空のDOM要素を作ります。
.enter()
新しく作ったDOM要素にdivを追加します。
.append("div")
新しく作ったdivにテキストを追加します。
.text(function(d){ //の中にテキストを追加。
return "新しい数値は" + d + "になります";
})
最後に、新しく作ったdivの色(テキストの色)を赤にします。
.style("color", "blue"); //全てのp要素に適用
「追加」をクリックしてみると、新しく追加された要素だけが青になります。これは、enter()によって行われる更新は、新しいdiv要素にのみ適用されるからです。

全て更新したい場合はどうすればいいでしょうか。答えは簡単で、もう一度全てのdivを選択し直して、更新します。ここではupdateというコードは出てきませんが、実際にはupdate()を実行しています。
var divs = body.selectAll("div") //divのDOM要素が7になるように選択し直す。
.data(dataset) //データの要素数をカウントし抽出。updateセレクションに入る
//enterセレクション。DOM要素がデータの要素数より少ない場合は新しく空のDOM要素を作る。
divs.enter()
.append("div") //新しく作ったDOM要素にdivを追加。
.text(function(d){ //divの中にテキストを追加。
return "新しい数値は" + d + "になります";
})
.style("color", "blue"); //全てのp要素に適用
//update
divs.style("color", "blue");
全て青に変更できました。
merge(結合)
実は、新しく増えたdivと既存のdivの更新はもっと短いコードで同時に行うことができます。merge()(結合という意味の英語)を使います。
var divs = body.selectAll("div") //divのDOM要素が7になるように選択し直す。
.data(dataset) //データの要素数をカウントし抽出。updateセレクションに入る
//enterセレクション。DOM要素がデータの要素数より少ない場合は新しく空のDOM要素を作る。
divs.enter()
.append("div") //新しく作ったDOM要素にdivを追加。
.text(function(d){ //divの中にテキストを追加。
return "新しい数値は" + d + "になります";
})
.merge(divs) //既存のdiv要素も一緒に選択する
.style("color", "blue"); //全てのp要素に適用
同じ結果になります。
exit
次に、datasetの要素が減った時の動作をexit()で操作してみましょう。以下のコードを追加します。
//クリックするとdatasetを更新して要素数を4にする////////////////////
d3.select(".remove")
.on("click", function() {
//datasetの新しい値
dataset = [ 5, 10, 15, 20 ];
body.selectAll("div")
.data(dataset) //データの要素数をカウントし抽出
.exit()
.style("color", "red"); //exit()のp要素に適用
});
ここでは、datasetの要素が4個に減っているので、「追加」によって増えた7個から3個減っています。exitによって、データがなくなってしまったdiv要素を選択し、style()で赤に変更しています。
一般的には余分なdiv要素は削除するので、remove()しましょう。
body.selectAll("div")
.data(dataset) //データの要素数をカウントし抽出
.exit()
//.style("color", "red"); //exit()のp要素に適用
.remove();
まとめ
よって、enter, update, exitの関係は以下になります。
enter : データセットに追加され、まだDOM要素になっていないもの
update : すでにDOM要素になっている既存のデータ
exit : DOM要素として描画されていて、データセットから削除されたもの
この関係性を忘れないようにしましょう。




