D3.js data 사용법 - Enter, Update, Exit
기본 사용법
기본 사용법
dataset을 아래 같이 하면, <div>
요소에 데이터가 할당된다.
var dataset = [1, 2, 3, 4, 5, 6];
var div = d3.selectAll("div")
.data(dataset);
예를 들어, <div>
요소가 없는 상태에서, style
, text
를 지정하게 되면,
d3.selectAll("div")
.data(dataset)
.enter()
.append("div")
.style("color", "red")
.text(
function (d) {
return "this data is " + d;
}
);
아래와 같이 데이터 수의 <div>
요소가 생성된다.
기존 요소에 추가
아래와 같이 <div>
요소가 이미 2개 있다고 하자.
여기에 아래와 같이 새로운 요소를 추가하게 되면, 새로 생성된 요소가 업데이트된다.
d3.select("#view")
.selectAll("div")
.data(dataset)
.enter()
.append("div")
.style("color", "red")
.text(
function (d) {
return "this data is " + d
}
);
새로 생성된 부분을 enter 영역, 이미 있는 부분을 update 영역이라고 한다.
update 영역의 데이터 업데이트
이 update 영역의 style 적용하려면, 다음과 같이 하면된다.
d3.selectAll("div")
.data(dataset)
.style("color", "blue")
.text(
function (d) {
return "this data is " + d;
}
);
update 영역과 enter 영역의 스타일을 동시에 변경
update 영역과 enter 영역의 스타일을 동시에 변경하고 싶은 경우가 많을 거라고 생각되는데, 그러한 경우에는 다음과 같이 하면 일괄로 변경할 수 있다.
var div = d3.selectAll("div")
.data(dataset);
var divEnter = div.enter()
.append("div");
var divUpdate = divEnter.merge(div);
divUpdate.style("color", "blue")
.text(
function (d) {
return "this data is " + d
}
);
exit를 사용하여 여분의 요소 영역을 지정
반면에 이미 위와 같이 6개의 <div>
요소가 있고, 할당되는 데이터가 적은 경우에는 exit
를 사용하여 여분의 요소 영역을 지정할 수 있다.
dataset = ['A', 'B'];
var div = d3.selectAll("div")
.data(dataset)
.style("color", "red")
.text(function(d){return "this data is " + d;});
div.exit()
.style("color", "green");
exit 영역의 데이터 지우기
exit 영역의 데이터는 지우는 것이 대부분이므로 아래와 같이 지우며 된다.
div.exit().remove();
Enter selection, Exit selection
D3의 가장 중요한 개념인 Update, Enter, Exit에 대해서는 알아보자.
Enter selection
먼저, 다음의 HTML 로 enter selection에 대해 설명하겠다.
<div class="fruitlist">
<div class="fruit">Apple</div>
<div class="fruit">Banana</div>
<div class="fruit">Cherry</div>
</div>
data()
로 data
를 할당한 후에, DOM 요소보다 data
의 수가 많을 때, data
의 수가 많은 부분을 enter selection 이라고 부른다.
enter()
로 enter selection에 요소를 추가할 수 있다. append()
로 데이터를 추가하려면 selection.selectAll()
메소드를 사용하여 부모 요소로부터 선택해야 한다.
d3.select(".fruitlist")
.selectAll(".fruit")
.data([1, 2, 3, 4, 5])
.enter()
.append("div")
.text(d => `Extra fruit number ${d}`)
Exit selection
다음으로 다음 HTML에서 Exit selection
에 대해 알아본다.
<div>
<div class="lunch">Burger</div>
<div class="lunch">Hotdog</div>
<div class="lunch">Curry</div>
<div class="lunch">Pasta</div>
<div class="lunch">Pizza</div>
</div>
DOM 요소보다 data
수가 적을 때 data
수가 적은 부분을 exit selection 이라고 부른다. exit()
으로 exit selection을 삭제할 수 있다.
d3.selectAll(".lunch")
.data([1, 2, 3])
.exit()
.remove()
Update, Enter, Exit를 사용하여 필요한 경우에만 DOM을 업데이트
D3 튜토리얼을 보다 보면, 존재하지 않는 요소를 selectAll()
하고 나서, enter()
를 실행하고 append()
하는 패턴이 갑자기 나와서 당황하게 된다.
존재하지 않는 요소를 selectAll()
를 하는 이유는 데이터 갱신시에 전회의 DOM 요소를 다시 이용하기 때문이다. 즉, 처음에는 존재하지 않는 요소를 selectAll()
하게 되지만, 두번째에는 존재하게 되는 것이다.
이 패턴을 사용해 보도록 하자.
이 예제에스는 div
요소가 처음에는 비어 있다.
<style>
.chart div {
background-color: powderblue;
text-align: right;
margin: 1px;
transition: width 0.5s ease-in-out;
animation: fade-in 0.5s ease 0s 1 normal;
}
@keyframes fade-in {
0% { opacity: 0 }
100% {opacity: 1 }
}
</style>
<div class="chart"/>
데이터의 갱신을 알기 쉽도록 간단한 애니메이션을 붙이고 있다. 다음 코드로 무작위로 데이터를 업데이트한다.
function barchart(data) {
const chart = d3.select(".chart")
.selectAll("div")
.data(data)
.style("width", function(d) { return d + "px"; })
.text( d => d);
chart.enter()
.append("div")
.style("width", function(d) { return d + "px"; })
.text( d => d)
chart.exit().remove();
}
function updatebar() {
ndata = Math.floor(Math.random() * 5) + 5; // [5, 10)
data = d3.range(0, ndata).map(() => Math.floor(Math.random() * 300));
barchart(data);
}
setInterval(updatebar, 1000);