[D3.js] 애니메이션 효과

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

[D3.js] 애니메이션 효과


데이터를 웹페이지에 시각화 할 때 단순한 형태의 차트 이미지로 보여주면 뭔가 부족해 보일 수 있습니다. 데이터 시각화를 하고 시각화한 이미지가 실시간으로 움직이며 데이터가 살아 움직이는 효과를 보여 주면 좀 더 멋진 시각화 데이터가 되겠죠. 오늘은 간단한 애니메이션 효과로 이미지를 실시간으로 계속 움직이게 하는 표현을 실험하고자 합니다. 저도 기초부터 하나씩 잡아가는 단계라 깊게는 설명을 못드립니다.

1. SVG태그로 시각화 영역 설정


가로x세로 크기의 배경색은 blue로 지정하면 다음과 같습니다.

 //<svg width="300" height="300" style="background: blue"> 추가
  var canvas = d3.select("body").append("svg")
    .attr("width",300)
    .attr("height",300)
    .style("background-color","blue");

처음에 attr()함수에 "background-color"를 지정했는데 왜! 배경색이 안나오지 하고 삽질하고 찾아보니깐 style()함수로 지정해야 되더군요.

[결과]


위 결과 이미지를 보면 캔버스로 시각화 데이터가 그려질 영역이라고 보시면 됩니다.

2. 시각화 이미지 원 만들기


원이 그려 질 cx가 30, cy 150의 위치에 r=15인 원을 그리고 원의 색은 red로 지정하면 다음과 같습니다.

//<circle cx="30" cy="150"  r="15" fill="red> 추가
    var circle = canvas.append("circle") 
              .attr("cx",30)
              .attr("cy",150)
              .attr("r",15)
              .attr("fill","red");

위에 캔버스에서 특정 좌표(30,150) 위치에 원을 그립니다.

[결과]


3. 캔버스의 원을 움직이게 하기


 //<circle cx="30" cy="150"  r="15" fill="red> 추가
    var circle = canvas.append("circle")
              .attr("cx",30)
              .attr("cy",150)
              .attr("r",15)
              .attr("fill","red");
        circle.transition()   //시작전 1초 대기(delay)했다가 2초동안  현재위치에서 x축 300위치로 이동한뒤 원 제거
                .duration(2000)  
                .delay(1000)
              .attr("cx",300).remove();

circle을 이동하는데 duration(2초) 동안 이동합니다. 대기시간은 1초이고 cx가 300이 될때까지 이동을 2초동안 하게 됩니다. 즉, 초기 circle이 그려진 위치에서 2초동안 cx가 300인 위치까지 움직인다고 보면 되겠죠.
참가로 remove()함수는 제거 함수인데 2초동안 움직인 후 해당 원은 제거 합니다. 원을 한곳에 계속 쌓아 둘 필요는 없으니깐요.

4. d3.interval()함수를 실시간 처리


이전 시간에는 기존의 자바스크립트 언어에서 setTimeout()함수로 처리를 했지만 이번에는 d3.interval()함수를 통해서 한번 처리를 해볼까 합니다.

render(); //처음한번수행
d3.interval(render, 3000); //3초간격으로 render()함수 호출함

이렇게 표현하면 3초 간격으로 render()함수가 호출이 됩니다 어떤 의미 인지 아시겠지요. 오늘 배운 애니메이션 효과를 3초 간격으로 동작하도록 해볼까요.

5. 종합 코딩


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>codingman</title>
</head>
<body>

<script src="https://d3js.org/d3.v5.min.js"></script>
  
  <script>
 //<svg width="300" height="300" style="background: blue"> 추가
  var canvas = d3.select("body").append("svg") 
    .attr("width",300)
    .attr("height",300)
    .style("background-color","blue");    
    
  function render(){
     //<circle cx="30" cy="150"  r="15" fill="red> 추가
    var circle = canvas.append("circle") 
              .attr("cx",30)
              .attr("cy",150)
              .attr("r",15)
              .attr("fill","red");
        circle.transition()   //시작전 1초 대기(delay)했다가 2초동안  현재위치에서 x축 300위치로 이동한뒤 원 제거
                .duration(2000)  
                .delay(1000)
              .attr("cx",300).remove();
    }
    render(); //처음한번수행
    d3.interval(render, 3000); //3초간격으로 render()함수 호출함 
</script>
</body>
</html>

[결과]


단순하게 원 하나를 수평으로 이동시키는 실험이였습니다. 하지만 이 한동작의 원리만 제대로 이해하셔도 많은곳에 사용할 수 있습니다. 가령 막대형 차트에 적용 한다고 상상해 보세요. 각 막대기가 데이터 길이만큼 애니메이션 효과로 움직이면서 막대가 그려지겠죠. 한번 머리속에서 그려 보세요.

마무리


오늘은 d3.js에서 제공하는 실시간 동작 명령 interval함수에 대해서 살펴 보았습니다. 그리고 실시간 처리를 할 때 CSS의 부분인 애니메이션 효과를 D3.js함수를 이용하여 간단히 움직이는 동작을 코딩했습니다. 이런 동작 원리를 이해하시면 차트가 처음 열릴 때 움직이는 차트를 한번쯤은 보셨을 꺼에요. 그와 같이 애니메이션 효과를 부여하면 좀 더 멋진 데이터 시각화를 할 수 있습니다.

맛보기로 간단히 원을 수평으로 움직이게 실험했는데 여러분들 수직으로 한번 움직이게 해보세요. 원이 그려지는 초기 위치를 수정하고 cy값으로 변경하시면 되겠죠. 그리고 duration()함수의 시간값을 수정하여 빠르게 또는 느리게 움직이게 해보세요. 또는 interval()함수내 시간값을 수정하여 빠르게 또는 느리게 움직임을 만들어 보세요. 다양한 움직임을 만들어 낼 수 있을 거에요.

댓글()

[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

댓글()

[D3.js] Data 실시간 처리

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

[D3.js] Data 실시간 처리


시각화 데이터를 웹페이지에 열때 기본적으로 처음 한번만 해당 데이터를 읽어와 화면에 챠트와 같은 이미지로 출력을 하게 됩니다. 한번만 html문서로 출력을 한다면 뭔가 부족해 보일 수 있습니다. 대개 html 문서 상의 데이터들은 실시간 데이터를 다루는 경우가 많습니다. D3.js에서 이러한 데이터를 실시간 처리를 하는 코딩이 필요합니다. 그래서 오늘의 내용은 D3.js 상의 데이터를 일정시간 시간단위로 데이터를 갱신하는 실험을 해보겠습니다.

1. 기본 소스


지난 시간의 p태그에 data 값을 출력하는 예제를 통해 실시간 처리를 해보도록 하죠.

<body>
  <p>1</p>
  <p>1/p>
  <p>1</p>
<script src="https://d3js.org/d3.v5.min.js"></script>
  
<script>
    var data = [1,2,3,4,5];
    
    //갱신
    var p = d3.select("body").selectAll("p").data(data)
           .text(function(d){return d;})
    //추가
        p.enter().append("p")
           .text(function(d){return d;})
    //종료
        p.exit().remove();
</script> 
  
</body>

[결과]

1
2
3
4
5

위와같이 html 문서가 열릴 때 처음 한번만 data 값들을 순차적으로 p태그에 출력하게 됩니다. 여기서 html 상의 데이터들이 출력한 상태에서 일정 시간 단위로 새로운 데이터로 갱신 시키는 코딩을 간단히 표현해 보겠습니다.

2. setTimeout() 함수를 통한 갱신


setTimeout(function(){호출함수(data);},1000);

다른 방법도 있지만 간단히 의미 전달로 setTimeout 함수를 사용해 보고자 합니다. setTimeout함수는 호출함수를 1초(1000) 후 호출하게 됩니다. 즉, 호출함수에 인자값을 새로운 data로 하여 호출함수를 수행하게 하면 일정 시간단위로 데이터 갱신 할 수 있게 됩니다.

위 기본소스를 간단히 수정해 볼까요.

기본 text()출력을 수행하는데 전체 코딩 부분을 render()함수로 묶어서 처리하도록 하겠습니다.

var data = [1,2,3,4,5];
function render(data){
  출력문;
  setTimeout(function(){render([k,12,13]);},1000);   
}

render함수가 1초(1000) 단위로 호출되게 됩니다. 동작은 render함수가 호출되면 내부동작을 수행하고 마지막 SetTimeout 함수를 통해 다시 render함수가 새로운 data값으로 재호출 됩니다. 재호출 되는 시간을 1초로 하였는데 이 표현을 통해 반복 수행을 하게 되면 1초 단위로 호출되어 데이터 값이 갱신을 하게 되더군요. 정확한 표현은 아니고 생각나는데로 표현한 것입니다.

[소스]

<body>

<script src="https://d3js.org/d3.v5.min.js"></script>
  
<script>
    var data=[1,2,3,4,5];
    var k = 1;
    function render(data){
      var p = d3.select("body").selectAll("p").data(data)
           .text(function(d){return d;})
         p.enter().append("p")
           .text(function(d){return d;});
         p.exit().remove();
      k++;
      setTimeout(function(){render([k,12,13]);},100);      
  } 
  render(data);   
   
</script>
</body>

위 소스는 0.1초 단위로 갱신이 되는데 결과 영상을 짧게 보기 위해서 갱신 시간으로 아주 짧게 만들었네요. 결과는 아래 움짤로 재편집 했습니다.

[결과]


처음 데이터 1,2,3,4,5값이 p태그에 text()함수를 통해 출력이 됩니다. 그다음 새로운 데이터 값 3개가 들어오고 기존에 5개의 p태그에서 3개의 p태그 값이 갱신되어 집니다. 여기서 나머지 2개의 값은 remove()함수를 통해 제거가 됩니다.

참고로, k변수를 새로 만들어서 k++로 표현하였는데 k값은 실시간으로 갱신되는 데이터 값을 보기 위한 표현으로 의미를 둘 필요는 없는 변수입니다. 결과를 실시간 갱신이 이루어지는지 보기 위해서 표현한 부분입니다.

마무리


위 setTimeout()함수외에도 다른 표현 방법으로 타이머함수도 있으며 몇가지 다르게 표현하는 방법들이 있었는데 간단히 실시간 데이터 갱신을 하게 된다면 이런 느낌으로 코딩을 하고 그 결과를 간단히 보기 위한 표현으로 보시면 되겠습니다.

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

[D3.js] 애니메이션 효과  (0) 2019.10.21
[D3.js] 막대형 차트로 보는 D3.js  (0) 2019.10.18
D3.js 기본 틀  (0) 2019.10.16
D3.js 버전5로 공부 시작  (0) 2019.10.15
시각화 문서 D3.js를 도전해보자  (0) 2019.10.14

댓글()

D3.js 기본 틀

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

D3.js 기본 틀



오래전 D3.js v4로 잠깐 기초를 독학했는데 이번에 v5로 기본틀을 다시 정리를 해보려고 하네요. 예전 post에서 "사각화 문서 D3.js를 도전해보자"에서 잠시 다루었는데 이번 post는 기본 틀 부터 해서 순차적으로 내용을 정리하여 간단히 post를 해볼까 합니다.

기본 틀


예제를 통해 간단히 살펴보겠습니다.

    var data = [1,2,3,4,5];
    
    //갱신
    var p = d3.select("body").selectAll("p").data(data)
           .text(function(d){return d;})
    //추가
        p.enter().append("p")
           .text(function(d){return d;})
    //종료
        p.exit().remove();

위 소스에서 보듯이 딱 3개의 구조로 이루어졌습니다.

  • 갱신 : body라는 태그를 선택하고 그 위치에 있는 모든 p태그를 선택하라 그리고 data값을 text()함수를 통해 순서대로 출력한다.
  • 추가 : 만약 선택된 태그가 3개이고 data가 5개인 경우 나머지 2개의 data는 갱신을 못시키기 때문에 추가부분에서 p태그를 append()함수로 추가하여 text()함수로 해당 새로운 p태그에 값을 text형태로 출력한다.
  • 종료 : exit()종료하는데 remove()함수로 인해 만약 p태그가 7개이고 data 5개 일 때 나머지 2개는 제거 됩니다.

여기서, 태그는 body, p 태그로 실험했지만 다른 태그로 접근해서 실험을 하셔도 됩니다. 또, 디테일 접근으로 html문서의 태그 id, class로도 접근을 할 수 있습니다.

예제) p태그가 3개일 때

<body>
  <p>a</p>
  <p>b/p>
  <p>c</p>
<script src="https://d3js.org/d3.v5.min.js"></script>
  
<script>
    var data = [1,2,3,4,5];
    
    //갱신
    var p = d3.select("body").selectAll("p").data(data)
           .text(function(d){return d;})
    //추가
        p.enter().append("p")
           .text(function(d){return d;})
    //종료
        p.exit().remove();
</script> 
  
</body>

[결과] 기존 p태그에 1,2,3으로 갱신이 되고 새롭게 p태그 2개가 추가되어 총 5개의 값을 출력했네요.

1
2
3
4
5

**예제) p태그가 7개일 때 **

<body>
  <p>a</p>
  <p>b/p>
  <p>c</p>
  <p>d</p>
  <p>e</p>
  <p>f</p>
  <p>g</p>

<script src="https://d3js.org/d3.v5.min.js"></script>
  
<script>
    var data = [1,2,3,4,5];
    
    //갱신
    var p = d3.select("body").selectAll("p").data(data)
           .text(function(d){return d;})
    //추가
        p.enter().append("p")
           .text(function(d){return d;})
    //종료
        p.exit().remove();
</script>
  
  
</body>

[결과] : 데이터는 5개이고 그러면 선택된 p태그 7개에서 5개는 갱신이 되고 나머지 2개는 exit()종료하는데 나머지 remove()함수로 제거 되게 됩니다.

1
2
3
4
5

그리고, exit() 종료함수만 있고 remove()함수를 제거하면 아래와 같이 출력됩니다.

1
2
3
4
5
f
g

remove()함수에 대한 의미를 잘 이해하시면 됩니다.

정리


초반에 태그 위치 선택은 select(), 태그 범위 선택은 selectAll(), 선택 태그 범위의 출력 할 데이터은 data()함수로 사용합니다.
enter(), append() 아직 데이터가 남아 있을 때 나머지를 해당 태그를 추구할 때 사용하는 함수입니다.
오늘 post에서는 text()함수가 있는데 갱신과 추가 부분에 text() 함수가 표현 되었는데 갱신부분의 기존의 p태그와 추가부분의 새로운 p태그에 data값을 출력하는데 text()함수로 텍스트 형태로 출력시키는 문장입니다. 이 부분을 다른 형태로 하면 해당 행터로 값을 출력합니다. 기본 테스트 이기 때문에 text()함수를 사용한 것이고 원하는 형태로 출력하고자 할 때 이 부분을 잘 활용하여 응용하시면 됩니다.
마지막 종료부분은 exit()함수는 종료이고 remove()은 나머지 부분을 제거하는 함수입니다. remove()함수만 주의하면 기초적인 부분에서는 어려움이 없는 것 같아요.

코딩을 할 때 저 세부분의 영역으로 나눠서 코딩을 하면 됩니다. 기존의 태그에서 갱신이나 추가하고 싶을 때 해당 영역 위치에 원하는 동작 명령 코딩을 삽입만 하면 됩니다.
그리고 , 아래 변수 p로 선언하고 d3코딩을 저장했는데, p변수로 해당 명령 코딩을 접근하기 쉽게 하기 위해서 입니다. 여기서 d3로 동작시키고자 하는 해당 태그명을 변수명으로 하시면 나중에 변수명만 보면 어떤 태그에서 특정 동작이 이루어지는지 쉽게 구별할 수 있습니다. 변수명으로 의미를 잘 전달 할 수 있는 이름으로 지어주는게 좋습니다.

var p = d3.select("body").selectAll("p").data(data)
           .text(function(d){return d;})

위 코딩을 보면 p라는 변수명만 보면 p태그에서 뭔가의 동작을 수행했겠구나 하고 쉽게 식별이 됩니다. 나중에 여러 태그을 복합적으로 사용할 때 아주 좋습니다. 태그간 d3표현을 할 때 한쪽 태그에서 다른쪽 태그의 d3 동작을 가져올 때 해당 변수명으로 가져와서 접근하면 코딩 구별하는데 쉽고 코딩도 깔끔해집니다. 이부분은 자주 사용되는 표현이라 나중에 post에 담아보겠습니다.

'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 버전5로 공부 시작  (0) 2019.10.15
시각화 문서 D3.js를 도전해보자  (0) 2019.10.14

댓글()

D3.js 버전5로 공부 시작

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

D3.js 버전5로 공부 시작



새벽형 인간이 되기로 한 시점에서 아침의 시간이 많이 남아서 따로 공부할 것을 찾다가 D3.js를 한번 제대로 공부해보고자 예전 기초 지식과 현재 새롭게 공부하는 내용을 토대로 정리하는 자료로 post를 작성해 볼까 합니다. 사실 아두이노 실험을 현재 사정 상 못해서 D3.js로 넘어왔네요. ^^

1. D3.js 시작 전 사전 학습


D3.js를 바로 시작하는 것도 좋지만 사전 학습으로 미리 공부해 놓으면 배우기가 무지 쉽습니다. D3.js은 기본적으로 자바스크립트 문법을 취하고 있으며 D3.js의 데이터 시각화 문서의 쓰이는 기본 베이스 형식이 HTML의 SVG, CSS의 표현 기능을 간단히 D3.js화 하여 표현합니다. 그래서 자바스크립트, SVG, CSS를 미리 학습해 놓으면 D3.js의 API 함수를 쉽게 이해하고 사용 할 수 있습니다.



위 참고 post를 한번 읽고 오시면 되겠습니다.


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


사전 학습은 w3chools 사이트에 가셔서 기본 문법을 배워 오시면 좋습니다.

2. D3.js의 장점


데이터 시각화 문서를 D3.js API 함수를 이용하여 간단히 표현 할 수 있습니다. 데이터를 챠트와 같은 그림으로 표현 할 때 자주 사용되는 기본 표현들을 함수 단위로 제공해 주고 있습니다. 말로만 좋다고 하는 것 보다 기본 예시를 들어 설명하는게 좋겠죠.

이 예제는 https://d3js.org/ 의 첫 페이지 예제입니다. 보면 극단적으로 비교한 예제인데 꼭 이런 코딩을 이렇게 간단히 표현 할 수 있다는 느낌을 전달한 예제이니깐 절대적 표현 비교로 보시면 안됩니다.

<body>
  <p> hellow World!</p>

<script>
var paragraphs = document.getElementsByTagName("p");
for (var i = 0; i < paragraphs.length; i++) {
  var paragraph = paragraphs.item(i);
  paragraph.style.setProperty("color", "white", null);
}
</script>
</body>

위 예제는 복잡한 표현인데 p태그의 컬러를 white로 지정하는 문장입니다. p태그의 문장이 white로 출력하면 배경색을 white계열에 가까워서 색이 뚜렷하게 안나오네요. 그래서 배경은 black으로 지정 한 후에 출력 결과가 아래와 같습니다.


위 코딩은 D3.js와 극단적으로 차이를 보이기 위한 예시로 보이네요. 꼭 위 처럼 코딩하지는 않습니다. 그냥 극단적 예시로 보면 될 듯 하네요.

d3js.org 홈페이지의 위 코딩 예시는 D3.js로 표현하면 아래와 같이 간단히 표현 할 수 있다고 장점을 소개 합니다.

d3.selectAll("p").style("color", "white");  

한줄로 위 4줄의 긴 코딩을 간단히 selectAll(), style()함수로 표현을 하게 됩니다. 배경도 이 방법으로 같이 표현이 가능합니다.

그러면, 아래와 같이 "Hellow World!"라는 문장을 black에서 white 글자색으로 출력을 아래와 같이 코딩을 하게 됩니다.

<body>
<p> hellow World!</p>
<script src="https://d3js.org/d3.v5.min.js"></script>

<script>
d3.selectAll("p").style("color", "white");  
d3.select("body").style("background-color", "black"); 
</script>
</body>    

이런식으로 극단적 비교하는 예시를 올라와 있네요. 극단적 표현이지만 딱 한줄로 복잡한 여러줄의 코딩을 D3.js로 줄여서 표현이 가능합니다. D3.js은 쉽게 말해서 데이터 시각화 표현들에서 자주 사용되는 표현들을 함수로 미리 만들어 놓고 제공해주는 API라고 생각하시면 될 듯 싶네요.

방금 간단히 D3.js 공식 홈페이지에 나온 예제 일부분을 가져 와서 보여 드렸습니다. 위 예제어서 추가로 D3.js 표현들이 있는데 생략을 했습니다. 가셔서 나머지 부분들을 읽어 보시기 바랍니다.

3. D3.js 공부하기 어려운 점


D3.js를 통한 코딩은 꽤! 단순한 형태로 코딩을 하게 됩니다. 이미 만들어 놓은 API를 이용하기 때문에 API에서 제공되는 함수만 이용해도 고퀄리티 표현을 쉽게 할 수 있습니다. 하지만 D3.js를 공부하는 것에도 어려운 점이 있네요. 그것은 버전 별 충돌입니다. 해당 함수는 해당 버전에서만 허용되는 경우들이 있습니다. 그래서, 여러분들이 사용하는 버전의 함수들이 다른 버전으로 바꿀 때 정상적으로 작동하지 않는 경우가 발생합니다. 그러면 공동 작업하는 모든 사람들이 공유된 하나의 버전으로만 코딩을 해야한 다는 점이 불편합니다. 새로운 사람이 새로운 버전으로 참여 할 경우 이전 버전 사용자들과의 소통이 약간 불편할 수 있겠죠.

그리고 또 한가지는 새로운 버전보다 구버전의 예제들이 많습니다. 당연한 이야기 이지만 D3.js에서 처음 공부하는 사람들은 자연스럽게 최신 버전 API를 사용하게 됩니다. 그런데 공부하는 사람들은 참고하는 예시들은 구버전에서 사용한 예시들이 많기 때문에 그대로 따라할 때 가끔 버전 문제로 정상적으로 작동하지 않아 해당 표현을 최선 버전 표현으로 바꾸기 위해 이중 공부를 해야 합니다. 구버전 표현을 이해해야하고 그 표현을 신버전으로 표현 할 수 있는 능력이 필요합니다. 처음 배우는 사람에게는 이 또한 큰 장벽이 될 수 있습니다.

4. D3.js 배워야 하는 이유


요즘 웹사이트를 돌아 보시면 데이터 시각화 문서들은 거의 대부분 실시간 시각화 문서들이 주류를 이루고 있습니다. 과거 단순하게 챠트로 처음 페이지가 열릴 때 한번만 출력하는 고정된 문서의 형태를 취했다면 요즘은 고정된 데이터 시각화 표현에 그치지 않고 실시간 갱신으로 통한 보다 생동감 있는 시각화 문서를 만들어 보여주고 있는 이 시기에 시대의 흐름에 맞게 지식을 습득해야 겠죠. D3.js은 이런 데이터 시각화 문서에 특화된 API 함수들을 제공하고 있습니다. 이걸 사용하면 초보분들도 충분히 독학으로 데이터 시각화 문서를 만들 수 있기 때문에 배워 두시면 좋습니다. 현재 써먹는 일이 없더라도 알아두시면 나중에 도움이 되실 꺼에요.

마무리


이번에 한번 새벽 3시에 기상이고 아침 시간적 여유가 있을 때 D3.js를 제대로 공부해 볼까 합니다. 아직 과거 기초지식만 있는 상태라도 챠트 표현이 초보 수준이지만 잘 정리해서 제대로 된 결과물을 만들어 볼려고 도전해 보네요. 중간에 일정이 바뀔 수 있지만 현재는 시간 여유가 생겨서 post 형식으로 정리를 해놓으려고 합니다.

'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를 도전해보자  (0) 2019.10.14

댓글()

시각화 문서 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

댓글()