시각화 문서 D3.js를 도전해보자

D3.js/D3.js|2019. 10. 14. 09:00

시각화 문서 D3.js를 도전해보자


오늘은 D3.js에 대해 간단히 소개할까 합니다. D3(Data-Driven Documents)는 한마디로 표현하자면 데이터를 시각화하는 문서로 실시간성을 갖고 수치를 그림 챠트와 같은 형태로 쉽게 표현할 수 있다는 점이 큰 장점을 지니고 있습니다. 제가 오래전에 잠깐 기초를 독학으로 공부한 적이 있는데 이제 기억도 가물 거리네요. 이제는 쓰는 방법도 기억이 안나네요. 어렴 픗한 기억으로 한자락을 가지고 포스팅을 해볼까 합니다. 혹시 Steem API를 이용해 데이터를 시각화로 보여주는 사이트를 보신적 있을꺼에요. 그 사이트와 같은 형태로 steem 데이터를 시각적으로 표현해주는데 특화된 API라고 생각하시면 됩니다. 혹시 데이터 시각화에 관심 있으신 분들이 있다면 D3.js를 공부를 해보라고 추천 드리고 싶네요.

하지만 전 공부하다가 포기했습니다. 실전에 써먹을 곳이 저에게 없었고 미리 공부해 놓더라도 사실 버전이 달라지면 약간 혼동과 충돌이 일어나기 때문에 일관성이 약간 부족하다는 점이 단점이여서 시간을 투자하기가 애매해서 포기 했네요. 열심히 현재 버전을 공부했는데 나중 새로운 버전이 나오고 새로운 버전으로 공부한 사람이 과거 버전으로 공부한 사람과 같이 협동해서 작업 할 때 버전 별 충돌 부분이 생기면 참 애매해지는 경우가 생기지 않을까 썩먹을 날이 오면은 제대로 공부를 해보고 싶은 라이브러리라고 생각만 하고 포기했네요.

1. D3.js 설치





해당 첫페이지에서 d3.zip라고 라이브러리를 다운 받을 수 있습니다. 그리고 script 링크 주소 선언을 통해 설치없이 사용이 가능합니다.

2. D3.js 문법


주로 사용되는 기본 함수

  • d3.select - 현재 문서에서 특정 태그 하나를 선택
  • d3.selectAll - 현재 문서에서 특정 태그 전체를 선택
  • selection.attr - 선택된 태그의 속성값 지정
  • selection.data - 참조 연결할 데이터 가져옴(선택된 태그에 데이터 매칭)
  • selection.enter - 데이터 갯수만큼 태그가 부족할시에 플레이스홀더를 반환
  • selection.append - 새로운 태그를 추가
  • selection.exit - 종료(더 이상 필요없는 태그는 반환)
  • selection.remove - 현재 문서에서 선택된 태그를 제거



위 문법 문장의 표현은 홈페이지 가시면 나온 예제인데요 대충 저렇게 세부분의 영역으로 나눠서 생각해 볼 수 있습니다.

d3.select(사용될영역태그).selectAll(선택태그) => d3이 사용될 영역위치를 선택하고 선택된 영역안에 특정 선택태그들을 모두 선택한다는 명령입니다.

data()함수는 선택태그에 사용될 데이터인데 태그와 1:1 매칭된다고 생각하시면 더 쉬울꺼에요.

text()함수내에서 콜백함수를 사용했는데 콜백함수는 d값인데 이것은 data에서 순차적으로 가져온 값(forEach)이고 리턴하니깐 이렇게 되겠죠. text("4")로 표현이 됩니다. 그럼 선택된 태그로 4값을 출력하라는 명령이 됩니다. print 출력함수라고 생각하시면 됩니다. 여기서 'body"안에 선택된 'p'태그들이 이미 데이터 값을 가지고 있으면 어떻게 될까요. 바로 지워지고 새로운 값으로 갱신됩니다. 업데이트가 되는 것이죠. 그렇지만 중요한 것은 'p'태그가 선택된것이 3개라면 선택된 3개 태그의 값만 갱신됩니다. 즉, 이말은 "4, 8, 15"까지의 data 값만 'p'태그에서 갱신이 되고 끝난다는 것이죠. 업데이트만 된다고 생각하시면 됩니다. 나머지 "16, 23, 42"은 쓸 수 없습니다.

그래서 나온것이 다음 문장 //Enter라고 나와 있는데 이 문장 대신에 추가라고 생각하시면 됩니다.

enter().append("p") 하면 실행하는데 더이상 선택 태그가 없으면 "p"태그를 새로 생성하라는 명령으로 이해하시면 됩니다.
그리고 나서 .text()함수를 통해서 나머지 "16, 23, 42"가 'p'태그에 출력 됩니다.

글보다 애래 그림을 보시는게 이해가 더 빠르겠지요.


갱신부분은 'p'태그가 3개뿐이고 해당 "p"태그의 값만 "1,2,3"이 data값에서 순서대로 3개 "4,8,15"로 갱신이 되고 거기서 끝나게 됩니다. 하지만 부족한 부분은 다음 append() 명령으로 나머지 데이터 갯수만큼 추가하게 됩니다. 위에서 data()는 선택된 'p'태그랑 1:1 매칭이라고 했죠. 그래서 나머지 데이터도 1:1 매칭하기 위해서 나머지 갯수만큼 'p'태그가 늘어나는 것이죠.

마지막 exit()함수는 끝내는 문장인데 remove()함수로 나마지 태그를 제거하라는 명령입니다. 이런 경우도 있겠죠. 'p'태그가 10개가 있는데 데이터가 6개라면 어떻게 될까요. 6개의 태그에 데이터를 출력했는데 나미저 4개의 'p'태그에도 데이터가 있으면 충돌나서 혼동이 발생하겠죠. 그래서 해당 데이터 만큼 수행 한 뒤에 나머지 태그가 남아있으면 그 태그는 지우라는 명령으로 이해하시면 됩니다. 즉, 10개의 'p'태그가 기존에 있지만 데이터 6개를 갱신 한뒤에 나머지 4개 태그는 문서상에서 지워버려라는 의미로 해석하시면 됩니다.

다르게 표현할 수도 있습니다. 해당 위치에 값만 갱신이 필요한 경우는 remove()함만 없애 주면 됩니다. 남은 태그는 그냥 두라는 의미로 종료가 되겠죠.

3. D3.js 예제로 느끼자.


<!doctype html>
<html>
<head>
  <title>D3</title>
  <script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
  <div id="aaa"><p>aaa</p></div>
  <div id="bbb"><p>bbb</p></div>
  <div id="ccc"><p>ccc</p></div>
  
  <script>
  var data =[1,2,3,4,5];
  function render(data){
    var p = d3.select("#bbb").selectAll("p").data(data)
           .text(function(d){return d;})
        p.enter().append("p")
           .text(function(d){return d;})
        p.exit().remove();
  }  
  
  render(data);    
  </script>
  
</body>
</html>

select()함수는 태그를 선택한다고 했는데 여기서 "#bbb"로 id를 선택할 수 있습니다. 'body' 태그 안에 'div' 태그 중 세개의 id가 있습니다. 여기서 두번째 'bbb' id 영역을 선택한다고 생각하시면 됩니다. 그리고 그 영역에서 사용되는 태그가 "p"태그입니다. 그런데 "p" 태그는 1개뿐입니다. data 값을 text()로 출력하게 되면 우선 첫번째 "bbb"가 출력된 값이 '1' 업데이트 됩니다. 그리고 더 이상 태그가 없으니깐 다음 문장에서 append("p")로 태그를 추가하게 됩니다. 그리고 나서 나머지 새로 생성된 "p"태그에 "2,3,4,5" 값이 출력되는 것이죠. 그러면 그 결과가 어떻게 나타날까요.

결과

위 그림처럼 "bbb" 위치에 값은 '1'로 갱신이 되고 추가로 나머지 4개의 데이터 값이 출력이 됩니다. 대충 어떤 느낌의 구조인지 아시겠지요.

이런식으로 D3.js은 웹페이지들은 실시간으로 수정과 삭제 그리고 시각화를 할 수 있습니다. 자바스크립트로 표현 하려고 하면 불필요하게 많은 코딩량을 추가해야 합니다. 하지만 이런 기본 문법에서 몇가지만 추가하면 다양한 표현이 가능 해집니다. 자주 사용되는 함수들을 깔끔하게 정리해서 만들어 놓은 라이브러리죠.

재밌는 것은 모든 표현을 D3.js로 할 수도 있지만 다른 css, javascript 표현을 같이 사용할 수 있습니다. 어떤 분들은 css와 javascript로 많이 하신분들은 일부분만 D3.js를 이용하시는 분들도 있고 어떤 분들은 아예 D3.js로 하신분들은 css, javascript에서 사용되는 표현을 잘 모르니깐 모든 표현을 D3.js 문법에 맞게 표현하시기도 합니다. 어떻게 표현하는 것이 좋다고 할 수 없고 그냥 자신이 편한 코딩으로 하시는게 가장 좋겠죠.

4. D3.js 오픈 예제 소스



보시는 것처럼 예제들이 있는데 다양한 D3.js 시각화 예제들이 오픈소스로 공개되어 있습니다. 믈론 라이센스를 잘 확인하시고 쓰셔야 합니다. 하지만 학습용으로는 이만한 예제는 없습니다. 소스까지 다 공개되어 있으니깐요.

5. D3.js API Reference



D3.js 메인창에서 문서 항목를 클릭하시면 이 창이 뜨는데 한국어를 지원합니다.


여기서 API Reference를 선택하시면 됩니다.


이렇게 함수에 대한 의미가 잘 소개 되어 있는데 샘풀 예제가 없어서 처음 하시는 분들은 익숙치 않을꺼에요. 그럴때에는 구글 검색을 하시면 됩니다.
참고로 D3.js를 바로 하시기 전에 아래 링크 걸린 사이트에서 HTML과 그 안에 SVG를 집중적으로 공부하시고 CSS도 어느정도 습득하시고 하면 더 빠르게 배울 수 있습니다.

대부분 시각화하면 그림 형태로 출력하는 경우가 많습니다. 시각화 문서를 하는 이유가 그림 형태로 표현하기 위해서이죠. 바로 D3.js로 표현하는 걸로 들어가기 전에 HTML로 SVG에 대한 속성이나 표현을 잠깐 읽으시고 들어가시면 D3.js가 좀 더 쉽게 다가올꺼에요.

- HTML, CSS. JavaScript 참고 사이트 : https://www.w3schools.com/

- 유튜브 : Introduction to D3 - 강사: Curran Kelleher

제가 처음에 D3.js를 공부하면서 배울때 유튜브 검색에서 찾아낸 강의 내용입니다. 이분 링크사이트 가시면 소스가 파트별 공개되어 있습니다.
참고로 v3 버전용 강의입니다. 전 v4로 연습했는데 이게 서로 매칭해서 함수 찾는데 시간 무자게 잡아 먹었어요. 따라 하실때 v3로 그냥 하시는 걸 추천 드려요. v5으로 최근걸로 하시면 답답 하실꺼에요. "왜! 안돼!" 에러난 위치를 보고 함수명이 잘못되었고 그 함수명이 어떻게 바뀌었는지 일일히 찾아서 표현을 바꿔야 하기 때문에 시간이 엄청 소요 됩니다. 강의 들으면서 수시로 레퍼런스를 찾아가서 해당 함수를 찾으셔야 합니다.
그냥 속편하게 v3로 따라서 연습을 끝내고 나서 익숙해지면 그제서 v5로 연습하시고 변경된 부분만 바꾸시면 될꺼에요.
암튼 이분 강의 내용은 기본적인 웹 내용을 먼저 설명해주고 D3.js을 들어가니깐 전부 다 가르쳐 준다고 생각하시면 됩니다.
한방에 다 해결되는 것이죠. 따로 공부할 필요 없이 이분 것 한시간 30분가량 되는 내용인데 꼭 보시라고 추천 드려요. 제가 쉽게 d3.js를 이해하는데 가장 큰 도움을 준 유튜브 강좌였던 것 같습니다.

마무리


D3.js는 시각화 라이브러리로 아주 강력합니다. 단순히 위에서 소개한 내용은 기초입니다. 시각화에 사용되는 함수들이 꽤 잘 정리되어 있고 함수로 많이 만들어 놓았기 때문에 어려움 자바스크립트 표현들을 쉽게 접근할 수 있습니다. 혹시 프로그램을 처음 입문하시는 분들이라면 D3.js를 공부해보시는 추천드립니다.

어제 D3.js에서 json 읽는 법을 거론하면서 포스팅으로 D3.js를 소개하면 좋을 것 같아서 이렇게 소개하게 되었네요. 물론 웹 프로그램을 좀 하시는 분들은 다들 D3.js를 어느정도 알거나 접해보셨을 꺼에요.

이제 입문하시는 분들이라면 한번 공부해보시는 것도 나쁘지 않을 것 같아서 이렇게 소개합니다. 그리고 Steem API로 읽은 데이터를 D3.js로 이용하시면 재밌는 것들을 아마 많이 만드실 수 있을거에요. Steem API와 연동한다면 활용범위는 엄청 넓어진다고 생각 되네요.

시각화 전용 API이깐요. 화려한 그래픽으로 표현하고 싶은데 표현력이 부족하시다면 여기서 제공하는 함수로 한번 도전해 보세요.


'D3.js > D3.js' 카테고리의 다른 글

[D3.js] 애니메이션 효과  (0) 2019.10.21
[D3.js] 막대형 차트로 보는 D3.js  (0) 2019.10.18
[D3.js] Data 실시간 처리  (0) 2019.10.17
D3.js 기본 틀  (0) 2019.10.16
D3.js 버전5로 공부 시작  (0) 2019.10.15

댓글()