D3.js를 찍어 먹어보자!

sun202x·2022년 9월 29일
0

D3.js

목록 보기
1/4
post-thumbnail

이직을 시작하며 프론트엔드 기술을 찾아보며 공부하다가 데이터 시각화라는 분야에 매력을 느끼게 됐다. 복잡하고 현란한 시각화 자료들을 보면서 마치 프론트엔드의 정점으로 느껴져 더욱 흥미가 갔다.

리서치를 해보면서 몇가지 데이터 시각화 라이브러리들을 찾아보았다. 그 중에서 브라우저 환경에 가장 특화된 D3.js를 선택하게 되었다. plotly.js, three.js, tableau 등 몇가지 라이브러리들이 존재하긴 하지만 다른 언어(python, R 등)들의 파생된 라이브러리 이거나 상황에 맞지 않다는 생각이 들어서 D3.js를 선택하게 되었다.

📝 plotly.js, tableau는 데이터로 인한 DOM 조작보다 차트 작성에 특화되어있고, three.js는 3d 표현에 더 적합한 라이브러리이다.

📝 D3.js의 핵심은 데이터 시각화 보다 데이터 중심의 DOM 조작이라고 한다.

D3.js(Data-Driven Document)란?

📝 D3.js is a JavaScript library for manipulating documents based on data.

D3.js는 데이터를 기반으로 문서를 조작하기 위한 Javascript 라이브러리이다. 공식사이트에 접속해보면 굉장히 다채롭게 구현된 시각화 자료들을 만날 수 있다.

D3.js는 HTML, SVG, CSS를 통해 다양한 시각화 자료들을 만들 수 있다. 또한 DOM 조작으로 인한 데이터 중심 접근 방식을 제공하기 때문에 특정 Framework(react, vue, angular 등)에 종속적이지 않아 이식성이 높다는 장점이 있다.

D3.js 설치

<script src="https://d3js.org/d3.v7.min.js"></script>

cdn 방식으로 사용하려면 위 코드를 html 코드에 삽입하면 된다. 물론 package manager를 통해 설치할 수도 있다.

# npm 사용
npm i d3

# yarn 사용
yarn add d3

d3.js를 사용하기 위해서는 반드시 문자 인코딩을 설정해 주어야 하는데, 그 이유는 d3.js 내에서는 π와 같은 특정 기호에서 utf-8 형식을 사용하기 때문이다. 따라서 인코딩 설정이 없다면 d3.js 라이브러리를 사용할 수 없다.

<meta charset="utf-8">

D3.js 샘플코드 작성

차트중에 제일 만만한 막대 차트를 만들어 보기로 했다. 우선 막대차트가 될 데이터들을 정의해보자.

const data = [4, 8, 12, 23, 26, 45];

위 데이터를 보여줄 화면을 만들건데 우선 HTML로 작업해보자.

📝 해당 게시글에서는 기본적으로 frontend 개발 경험이 어느정도 있다고 가정하고 작성되었기 때문에 최대한 즉시 사용하여 화면을 확인하기 위한 코드들로 작성되었다. 더 자세한 튜토리얼을 확인하고 싶다면 참조로 걸어둔 막대차트 tutorials 를 참조하길 바란다.

HTML

D3.js는 jQuery처럼 chaining method를 통해 DOM selector, creator를 제공한다. 각 메서드들은 현재 선택된 요소를 반환하게 된다. jQuery에 익숙한 개발자라면 어렵지 않게 작성할 수 있을 것이라고 생각한다. API의 자세한 내용을 알고 싶다면 Github 문서를 참조하면 된다.

d3.select('body')
  .append('div')
  .html('Hello world!');

위와 같이 작성된 코드를 실행하면 아래와 같이 화면이 나오는 것을 확인할 수 있다.
sample1

D3.js를 통해 DOM element를 생성하고 조작하는 방법에 대해 알았으니, 이제 막대 그래프를 만들어 보자.

// 빈 차트 컨테이너를 생성하고 스타일을 설정한다.
const div = d3.select('body')
  .append('div')
  .style("font", "10px sans-serif")
  .style("text-align", "right")
  .style("color", "white");

// 막대 차트를 위한 초기 셀렉터를 설정한다.
div.selectAll("div")
  // 데이터를 해당 셀렉터에 바인딩한다.
  .data(data)
  // 바인딩된 데이터에 따라 입력될 막대 요소를 지정한다.
  .join("div")
  // 각 막대의 스타일을 정의한다.
  .style("background", "steelblue")
  .style("padding", "3px")
  .style("margin", "1px")
  .style("width", d => `${d * 10}px`)
  // 각 막대 안에 들어갈 text를 설정한다.
  .text(d => d);

위 코드를 실행하면 아래와 같은 화면을 확인할 수 있다.

위 코드의 문제점은 아무래도 막대 요소의 너비 값을 하드코딩 해놨기 때문에 데이터에 따라 너비를 의도했던 대로 보여줄 수 없다는 단점이 있다. 해당 문제를 해결하기 위해 d3.js는 scale을 설정할 수 있도록 몇가지 api를 제공해준다. 해당 예제에서는 scaleLinear를 사용하여 scale을 설정해 볼 수 있다.

const x = d3.scaleLinear()
  // 데이터 영역을 설정한다.
  // 해당 예제에서는 0~45가 되겠다.
  .domain([0, d3.max(data)])
  // 시각적 표현의 변수 범위를 지정한다.
  // 위치, 너비 등을 설정하기 위해 쓰일 변수 범위이다.
  .range([0, 420])

반환된 함수는 변수 x에 설정되고, 해당 scale 함수를 통해 전달되어진 데이터의 시각적 변수 값을 반환받게 된다.

scale 함수를 생성했으니 예제를 변경해보자.

const div = d3.select('body')
  .append('div')
  .style("font", "10px sans-serif")
  .style("text-align", "right")
  .style("color", "white");

div.selectAll("div")
  .data(data)
  .join("div")
  .style("background", "steelblue")
  .style("padding", "3px")
  .style("margin", "1px")
  // 위에서 생성한 scale 함수를 너비 설정에 사용한다.
  .style("width", d => `${x(d)}px`)
  .text(d => d);

이런 식으로 간단한 막대 차트를 d3.js를 사용하여 만들어 보았다. 간단한 예제지만 d3.js의 사용 방식을 조금은 알 수 있지 않았나 싶다. 아무래도 DOM을 조작하다 보니 HTML로 작성하는 것은 성능에 문제가 있지 않을까 싶은데 그 부분은 SVG를 활용한 예제들을 통해 확인해 보도록 하겠다.

Reference

D3.js
D3.js tutorials
막대차트 tutorials

profile
긍정적으로 살고 싶은 개발자

0개의 댓글