[D3.js] 막대형 차트로 보는 D3.js

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

[D3.js] 막대형 차트로 보는 D3.js



오늘은 막대형 차트를 간단히 하나를 막들어 보았는데 D3.js에서 튜토리얼로 아주 좋은 예제가 있어서 D3.js 튜토리얼로 나온 예제로 이야기를 풀어 나갈까 합니다. D3.js를 배우면 좋은 점으로 설명하기 가장 좋은 예제일 것 같습니다.


위 링크로 가시면 튜토리얼에 Let’s Make a Bar Chart 예제가 있습니다. D3.js를 처음 시작하면 이 막대형 차트 시각화부터 시작합니다. 저도 비슷하게 다른 막대형 차트 표현을 했는데 위 출처의 예제가 너무 완벽해서 이걸로 소개하는게 좋을 것 같아서 제 코딩은 잠시 접어 둡니다.


1. HTML 막대형 차트


출처 : November 5, 2013Mike Bostock - Let’s Make a Bar Chart



위 막대형 차트가 출처 "Let’s Make a Bar Chart" 코딩 소스를 기반으로 살펴보면 막대형 챠트 이미지가 HTML로 만든다면 이렇게 코딩이 됩니다.

[ "Let’s Make a Bar Chart" 코딩 소스]

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>codingman</title>    
    <style>
    .chart div {
      font: 10px sans-serif;
      background-color: steelblue;
      text-align: right;
      padding: 3px;
      margin: 1px;
      color: white;
    }
    </style>
  </head>
  <body>
    <div class="chart">
    <div style="width: 100px;">10</div>
      <div style="width: 200px;">20</div>
      <div style="width: 300px;">30</div>
      <div style="width: 400px;">40</div>
      <div style="width: 500px;">50</div>    
    </div>
  </body>
</html>

기존의 HTML에서는 div 태그를 일일히 코딩해야 합니다. 이 표현을 자바스크립트로는 for문으로 해서 div태그를 5번 반복하여 출력하면 됩니다. 그렇게 코딩을 하면 좀 지졉분하게 코딩되고 복잡해 보일 수 있는데 이런 코딩을 아주 쉽고 간단하게 표현할 수 있는게 D3.js API입니다.

2. D3.js 막대형 차트



위 표현을 D3.js를 이용하여 표현 하면 다음과 같습니다. 위 CSS 부분은 그대로 두고 다음 body 태그 안에 div태그 부분만 수정하면 됩니다.

  <body>
    <div class="chart">
      데이터 출력되는 부분;
    </div>
  </body>

위 코딩에서 데이터 출력되는 부분으로 막대형 차트에서 데이터 막대가 그려지는 부분입니다. 이 부분을 D3.js를 이용하여 표현하면 다음과 같습니다.

  <body>
    <div class="chart"></div>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script>
      var data = [10, 20, 30, 40, 50];

      d3.select(".chart").selectAll("div").data(data)
        .enter().append("div")
        .style("width", function(d) { return d*10 + "px"; })
        .text(function(d) { return d; });
    </script>    
  </body>

하나씩 살펴보면,

d3.select(".chart").selectAll("div").data(data)

select()함수로 클래스명이 "chart"를 가리키고 그 가리킨 위치에 selectAll()함수로 모든 div를 선택하게 됩니다. div태그가 있던 없던 우선 선택된 영역의 div들을 선택한다고 보시면 됩니다. data()함수는 시각화 data인자로 넣습니다. 갱신이 아닌 추가이기 때문에 갱신영역의 코딩은 현재 필요 없습니다. 추가 이기 때문에 추가영역에 데이터를 막대이미지로 출력하면 됩니다

div 태그 추가

.enter().append("div")

수평 막대이미지를 만들기 때문에 스타일에서 width의 값을 데이터 값에 맞게 지정하면 됩니다. 아래 d값은 순차적으로 배열 data 변수의 값을 반환하여 스타일을 지정합니다.

.style("width", function(d) { return d*10 + "px"; })

위 표현이 data가 10이면 막대 길이를 d*10으로 하면 100이 되고 스타일은 아래와 같이 추가 되었다고 생각하시면 됩니다.

<style>
  .chart div {
    width: 100px;
  }
</style>

5개의 데이터 이기 때문에 이 과정을 5번 수행되고 5개의 막대이미지가 그려집니다.

막대 이미지 안에 data를 텍스트 형태로 출력하기 때문에 텍스트 출력은 CSS에서 오른쪽 정렬 글자색 White로 표현되도록 설정되어 있고 D3.js에서는 텍스트만 뿌려주면 됩니다. 그 표현은 아래와 같이 코딩하면 됩니다.

.text(function(d) { return d; });

d는 배열 data 변수의 값을 순차적으로 출력됩니다.

결론은

.style("width", function(d) { return d*10 + "px"; })
.text(function(d) { return d; });

막대이미지를 데이터 d만큼 그리고 그 안에 데이터 d값을 출력한다는 의미입니다.

3. D3.js 막대형 챠트를 갱신 및 추가 한다면


<script>
  var data = [10, 20, 30, 40, 50];

  d3.select(".chart").selectAll("div").data(data)
     .enter().append("div")
     .style("width", function(d) { return d*10 + "px"; })
     .text(function(d) { return d; });
</script>    

위 코딩에서 어떻게 해야 할까요.

  var data = [10, 20, 30, 40, 50];

  var div = d3.select(".chart").selectAll("div").data(data)
     .style("width", function(d) { return d*10 + "px"; })
     .text(function(d) { return d; })
  div.enter().append("div")
     .style("width", function(d) { return d*10 + "px"; })
     .text(function(d) { return d; })
  div.exit().remove();

한번 테스트 해 볼까요.

<script>
  var data = [10, 20, 30, 40, 50];
  function render(data){
    var div = d3.select(".chart").selectAll("div").data(data)
          .style("width", function(d) { return d*10 + "px"; })
          .text(function(d) { return d; })
        div.enter().append("div")
          .style("width", function(d) { return d*10 + "px"; })
          .text(function(d) { return d; })
        div.exit().remove();
  }
  render(data);

  setTimeout(function(){render([20,10,33]);},1000);      
  setTimeout(function(){render([50,40,30,20,10]);},2000);      
</script>   

[결과]


마무리


D3.js로 코딩을 할 때는 위와 같이 순수 시각화 하는 데이터 영역만 간단하게 표현하기도 하고 CSS의 부분을 D3.js 함수로 이용하여 새로 갱신하거나 추가할 수 있습니다. 아예 처음부터 D3.js 함수로 표현해도 되지만 이렇게 하면 코딩이 길어지고 보기 불편합니다. 고정되는 CSS코딩 부분은 CSS 영역에서 처리하고 D3.js에서는 막대차트에서 막대이미지에 직접적으로 변경이 이루어지는 스타일부분만 코딩해주면 왠만한 차트 표현을 한페이지 코딩으로 고퀄리티 코딩을 할 수 있습니다.

어떻게 코딩할지는 여러분들의 몫이지만 여러분들이 한번 잘 생각해보시고 코딩 스타일을 잡아가시기 바랍니다. 오늘 살펴 본 막대형 차트는 CSS부분을 어느정도 기본 개념이 탑재 된 상태에서 봐야 하는 부분입니다. 혹시 CSS부분이 이해가 안되신다면 CSS 부분은 이곳 https://www.w3schools.com/css/ 사이트에 가셔서 한번 읽어 오셔서 보셨으면 합니다.

오늘 핵심 코딩은 딱 두줄입니다.

.style("width", function(d) { return d*10 + "px"; })
.text(function(d) { return d; })

수평 막대이미지를 길이를 지정하고 안에 텍스트 값을 출력하는 명령이 핵심입니다. 나머지 코딩은 D3.js 기본틀을 기준입니다. 기본틀의 의미만 이해하시면 딱 위 두줄로 CSS 스타일과 잘 접목하여 막대형 차트를 그릴 수 있게 됩니다.

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

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

댓글()