D3.js - 데이터 시각화 라이브러리, 기본 사용법

D3.js - 데이터 시각화 라이브러리, 기본 사용법

D3란

Data Driven Document - 반복되는 앞 글자 D를 3개 따서, D3라 불리는 이 라이브러리는 첫 인상이 썩 순해보이지는 않습니다. D3를 공부하면서 초보자를 위해 정리된 글이 의외로 별로 없다는 생각이 들어서 제가 공부한 것들을 정리해봅니다.

chart.js와 같은 라이브러리는 상대적으로 사용이 쉬운데 비해 D3는 직접 작성해야하는 부분이 많아서 손품이 많이 드는 라이브러리이기도 합니다.

하지만 SVG를 사용하여 아주 유연한 화면 구현이 가능하기 때문에 데이터 시각화에 아주 강력한 모습을 보여줍니다.

💡
아래 내용부터는 HTML/CSS/JS에 대한 기본적인 이해가 필요합니다.

jQuery와 비슷한 node 접근방식

사람마다 DOM을 제어하는 방법이 다르겠지만, 저는 보통 반복적으로 처리해야할 부분은 아래와 같은 방식으로 처리합니다.

// 모든 p 태그를 찾아서 배열로
const nodes = [...document.querySelectorAll('p')];

// p태그의 폰트컬러를 모두 red로 변경
nodes.forEach(item => {
	item.style.setProperty('color','red',null);
}

jQuery라면 document.querySelectorAll 이라는 메서드 대신 $('p')로 간편하게 쓸 수 있겠죠. D3에도 비슷한 방식으로 노드에 접근할 수 있습니다.

import * as d3 from 'd3'

// 여러개의 node를 선택할때 - 모든 p태그를 red 컬러로
d3.selectAll('p').style('color', 'red')
                        
// 단일 node를 선택할때 - body 태그 백그라운드를 red 컬러로
d3.select('body').style('background-color', 'red')

동적 제어

D3는 데이터를 받아서 그려낼 때 동적인 데이터를 받아서 표현하기도 쉽습니다.

import * as d3 from 'd3'

// 스크린 사이즈
const screenWidth = [640,768,1024,1440]

// body 태그 안에 span 태그는 모두 screenWidth 값을 채워넣도록 초기화
let screen = d3.select('body').selectAll('span').data(screenWidth).text(data => data)

// 실제로 데이터를 삽입하기 위해서 enter() 메소드와 append() 메소드를 사용
// text 메소드에서 숫자에 px 단위를 붙여서 출력되도록 
screen.enter().append('span').text(width => `${width}px`)
screen.exit().remove()

라이프사이클

위의 예시와 같이 초기화 과정과 실제 데이터 삽입 과정이 나뉘어있음을 확인할 수 있는데, D3가 그래프를 그려내는 라이프 사이클을 보면 update , enter , exit로 이루어집니다.

// 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) { return d; });

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

위의 소스는 D3 공식문서에서 가져온 부분인데, .data() 메소드가 초기화와 update를 모두 담당하고 있다는 것을 알 수 있습니다. .enter() 메소드를 이용해서 실제 데이터를 적용하여 삽입하고, exit()remove() 메소드로 마무리한다는 것을 확인할 수 있습니다.


Exit & Remove

개인적으로는 exit와 remove가 왜 쓰이는지 어떻게 작동하는지 이해하는데 좀 어려움이 있었는데, 그냥 정적으로 화면에 뿌려지기만 하는 그래프라면 exit와 remove를 굳이 써주지 않아도 그래프가 그려지는데 별 무리가 없습니다.

추가적으로 인터랙션이 주어져 사용자의 클릭이나 데이터의 변화를 감지해서 그래프가 다시 그려질때 새롭게 데이터를 입히기 앞서, 잔여물처럼 남아있는 불필요한 데이터들을 지워주는 명령들이라고 이해하는 것이 가장 쉬운 것 같습니다. 알아서 데이터의 변화에 맞춰 불필요한 내용을 지워주는 편리한 메소드입니다.

잘 정리된 글이 있어서 저도 많은 도움을 얻었습니다.

[D3.js] 제거(remove()) 함수 — Steemit
[D3.js] 제거(remove()) 함수 오늘은 제거 함수에 대해서 알아보는 시간을 갖겠습니다. 별다른 내용은 없습니다. 구지 remove()함수를 1일 post에 할애할 정도의 내용을 갖고 있지… by codingman

Transition

D3에서는 Transition 기능도 제공해 간단한 애니메이션 구현이 가능합니다.

import * as d3 from 'd3'
// 트랜지션 - duration을 적용하지 않았을 경우 기본값은 250ms
d3.select("body").transition()
    .style("background-color", "black").style('color','white');

// duration : 애니메이션되는데 걸리는 시간, 
// delay: 얼마나 지연한 후에 애니메이션될지 설정 가능
// 단위는 ms로 500ms = 0.5초 기다린 후 1000ms = 1초 동안에 걸쳐 애니메이션 예시
d3.select("body").transition().delay(500).duration(1000)
    .style("background-color", "black").style('color','white');

css를 이용한 animation을 구현해보신 분들이라면 충분히 이해할 수 있을 만큼 직관적이고 쉬운 사용법입니다.

마무리

여기까지가 D3의 아주 기본적인 내용입니다. 여기에 이제 많은 데이터를 넣어서 실제로 그려보는 과정은 다음 포스팅에 다시 정리해보도록 하겠습니다.