시각화 과제를 진행하며 AMChart 같은 솔루션을 이용하지 않고 D3를 이용하여 직접 개발하며 공부한 것을 정리해보았다.

D3.js 라이브러리를 적극적으로 활용해보기 위해 기본부터 정리하는 문서 (D3의 tutorials목차를 따라가며 정리함.)

D3란?

  • 임의의 데이터를 DOM에 bind하고 document(html)를 data-driven하게 변환할 수 있도록 하는 라이브러리
  • DOM을 셀렉트하여 데이터에 맞게 변형시키거나 SVG 태그를 이용해 interactive한 차트를 그릴수도 있음.

필수 개념 정리

Selections

W3C의 DOM API를 이용하여 DOM을 핸들링하는 것은 귀찮고 반복적인 일이다. 이러한 수고를 덜기 위해, D3에서는 selection 이라는 임의의 노드의 집합을 제공함으로써 선언적인 접근이 가능하도록 하였다.

Plain JS vs D3 selection

// plain js
var paragraphs = document.getElementsByTagName("p");
for (var i = 0; i < paragraphs.length; i++) {
  var paragraph = paragraphs.item(i);
  paragraph.style.setProperty("color", "blue", null);
}

// d3 selections
d3.selectAll("p").style("color", "blue");

Dynamic Properties

D3의 selection을 이용한 DOM 핸들링이 jQuery와 같은 다른 프레임워크와 유사하다고 느낄 수 있다. 그러나 D3에서는 style, attribute 와 같은 속성들은 단순한 상수가 아닌 data의 함수로 정의될 수 있다.

ex)

d3.selectAll("p").style("color", function(d,i){
    return i % 2 ? "#fff" : "#eee";
})

data가 bound된 뒤에 속성을 계산하여 정의할 수도 있다.

ex)

d3.selectAll("p")
    .data([4,5,7,16,24,46])
    .style("color", function(d,i){
    return i % 2 ? "#fff" : "#eee";
})

데이터가 한 번 bound되면 data메소드를 생략할 수 있다. 이를 이용하여, bind를 다시하지 않고도 속성값을 다시 계산할 수 있다.

Enter and Exit

D3의 enterexit selection을 이용한다면 입력되는 데이터에 대한 새로운 노드를 만들거나, 삭제될 데이터에 해당하는 노드를 지울수도 있다.

데이터를 selection에 bound할 때 데이터 배열의 각 요소는 selection에서 대응되는 노드에 bound된다. 만약 데이터의 숫자보다 selection 안의 노드의 갯수가 더 적다면, 남는 데이터들은 enter selection을 이룬다. 이 enter selection을 이용하여, 필요한 갯수만큼 새로운 노드를 만들 수 있다.

ex)

d3.select("body")
    .selectAll("p")
    .data([4,8,15,16,23,42])
    .enter().append("p")
    .text(function(d) { return "I 'm number " + d + "!"; });

기본적으로 노드를 업데이트하는 부분은 data 메소드의 영역이다. 만약, enterexit이 있다는걸 까먹는다면, 추가되거나 삭제된 데이터에 대해서는 대응이 불가능하다. 그렇기 때문에 update, add, remove 로 데이터를 initializing하는 공용 패턴을 기억하는 것이 좋다.

// update
var p = d3.select("body")
        .selectAll("p")
        .data([4,8,15,16,23,42])
        .text(function(d) { return d; });

// enter
p.enter().append("p")
    .text(function(d) { reutnr d; });

// exit
p.exit().remove();

Transformation, not Representation

D3는 새로운 시각적 표현을 도입하지 않는다. Processing이나 Protovis와는 달리, HTML, SVG, CSS와 같은 웹 표준 그래픽 마크업을 통해 표현한다.

Transitions

변환에 대한 D3의 초점은 자연스러운 전환이다. Transitions는 스타일과 속성을 천천히 간섭하여 변환한다. “elastic”, “cubic-in-out”, “linear”과 같은 함수를 통해 조절할 수 있다.

// basic transition
d3.select("body").transition()
    .style("background-color", "black");