この記事は、D3.js のデータ結合まわりのメソッド (data
/enter
/exit
/join
) の基本を理解していることを前提としています。
D3.js でデータ配列の内容をプロットするとき、各要素の値を元にその要素を表示するか表示しないかを制御したいことがあります。
このようなケースでは、D3.js の仕組みで処理しようと考えがちですが、単純にデータ配列の要素をフィルタしてから、selection.data()
でデータ結合してやれば OK です。
次の例では、データ配列 (data
) の enabled
プロパティを見て、描画要素の表示/非表示を制御しています。
とはいっても、データ配列の要素を filter()
メソッドで先にフィルタしているだけです。
次の例では、この方法がうまく動作することを示すために、1 秒ごとにデータ配列の enable
フラグをランダムに入れ替えています。
enabled=true
になったデータはアニメーションしながら表示され、enabled=false
になったデータはアニメーションしながら非表示になります。
const data = [
{ pos: 1, color: "#f00", enabled: true },
{ pos: 2, color: "#0f0", enabled: true },
{ pos: 3, color: "#00f", enabled: true },
]
// enabled プロパティの true/false をランダムにセットする
function updateData() {
data.forEach((d) => {
d.enabled = Math.random() < 0.5;
})
}
function render(filteredData) {
d3.select("#svg-wwhf")
.selectAll("circle")
.data(filteredData, (d) => d.pos)
.join(
(enter) => enter.append("circle")
.attr("cx", (d) => d.pos * 30)
.attr("cy", 20)
.attr("fill", (d) => d.color)
.transition()
.duration(500)
.attr("r", 10),
(update) => update,
(exit) => exit.transition()
.duration(500)
.attr("r", 0)
.remove()
)
}
setInterval(() => {
updateData()
const filteredData = data.filter((d) => d.enabled)
render(filteredData)
}, 1000)