Steem.js 보팅카운트 d3.js 시각화 입문용

in #kr-dev6 years ago

Steem.js 보팅카운트 d3.js 시각화 입문용



주말이라서 Steem.js 보팅카운트 예제를 하나 가지고 이것을 한번 챠트 형식으로 시각화 하는 예제를 post로 쓰면 괜찮을 것 같아서 토요일 오후에 잠깐 고민에 빠지다가 보팅 카운트 정보를 d3.js로 원형 챠트로 시각화 입문 예제를 간단히 만들어 보았습니다. 오늘 사용할 d3.js 통해 쉽게 시각화가 가능하기 때문에 한번 코딩을 살펴보시고 d3.js에 입문을 해보셨으면 하는 마음으로 이 글을 적습니다.

우선 시각화 문서 D3.js를 도전해보자 post를 읽고 오신 후 아래 과정을 읽어 보시기 바랍니다.

1. Pie Chart 이론


(function pie(){
    var width = 500, height = 500;
    var colorData=[];    
    var data = [1, 2, 3, 4, 5];
    var pie = d3.pie();

    var pieData = pie(data);
    console.log(pieData );
    
   for(var i in data){
   //  colorData[i]="#" + Math.floor(Math.random()*0xffffff).toString(16);
     colorData[i]="#" + Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16);     
   }
    var svg = d3.select('#svg')
                .attr('width', width)
                .attr('height', height)
                .style("background-color","#f0f0f0");    
    var arc = d3.arc().innerRadius(100).outerRadius(200);


    var g = svg.append('g').attr('transform', 'translate(250,250)');
        g.selectAll('path.slice')
           .data(pieData)
           .enter()
           .append('path')
           .classed('slice', true)
           .attr('d', arc)
           .attr('fill', function(d,i){ return colorData[i]; });

    })();

간단히 살펴보도록 합시다.

1) 데이터

먼저, Pie Chart를 그리기 위해서는 우선 시각화 할 데이터가 있어야 겠죠.

var data = [1,2,3,4,5];

대충 이런 데이터가 있다고 칩시다.

Pie Chart 데이터 영역의 Color를 랜덤색으로 만들면 좀 더 시각적으로 보기 좋겠죠. d3.js에 다양함 color함수들을 제공합니다. 그냥 랜덤함수를 이용하여 표현하겠습니다.

2) 데이터 Color 만들기



for(var i in data){
   //  colorData[i]="#" + Math.floor(Math.random()*0xffffff).toString(16);
     colorData[i]="#" + Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16);     
}

그냥 random()함수로 해도 됩니다. jdarling저자의 마지막 한줄 문장이 맘에 들어서 사용해 보았습니다. 이렇게 해도 색은 맘에 들지 않지만 그대로 활용 했네요. jdarling님이 표현한 randomColor 함수를 사용해 보시는 것도 괜찮을 듯 싶네요. 해당 소스는 사실 제것이 아니기 때문에 링크만 걸어놓겠습니다.

colorData[i]="#" + Math.floor(Math.random()*0xffffff).toString(16);
colorData[i]="#" + Math.round(Math.random()*0xffffff).toString(16);

이렇게 통으로 표현해도 되고,

colorData[i]="#" + Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16);     

이렇게 R,G,B별로 색상을 난수로 만드셔도 됩니다 코드의 설명은 floor, round은 소숫점 이하를 버리는 함수입니다. random()은 0~1사이의 난수값을 만들어 냅니다.

Math.random()*100 => 0~99까자의 난수를 만들어 냅니다.

16진수 색상값은 0x000000~0xffffff 범위니 Math.random()*0xffffff 로 해서 전체 색상값에서 난수를 색상값을 구하게 됩니다.
Math.random()*255 => R, G, B 각각의 색상 0x00~0xff or 0~255로 표현됨

toString(16) 함수는 16진수변환 함수입니다. 예로, toString(2)이면 2진수변환이겠죠.

3) pieData 만들기

var pie = d3.pie();
var pieData = pie(data);

pie 변수는 d3.pie()함수를 가리킵니다. 여기서, pie(data)하면 1,2,3,4,5의 값이 d3.pie()에 대입되겠죠.
반환되어 나오는 값은 아래와 같이 data, endAngle, padAngle, startAngle, value 요소 값들이 5개가 pieData로 저장됩니다. 이 값을 통해서 실제 Pie 챠트를 그리게 됩니다. 데이터 값을 넣으면 알아서 비율에 맞춰서 값이 계산되어 나오기 때문에 참 편하게 코딩 할 수 있습니다. 5개의 pie 영역을 자동으로 계산되기 때문에 이 영역만큼 Pie 챠트를 그리면 됩니다.

[[object Object] {
  data: 1,
  endAngle: 6.283185307179586,
  index: 4,
  padAngle: 0,
  startAngle: 5.8643062867009474,
  value: 1
},

...

[object Object] {
  data: 5,
  endAngle: 2.0943951023931953,
  index: 0,
  padAngle: 0,
  startAngle: 0,
  value: 5
}]

4) SVG 영역 만들기

var svg = d3.select('#svg')
                .attr('width', 500)
                .attr('height', 500)

챠트를 그릴 영역을 만들어야 합니다. select()함수는 id가 svg인 태그를 선택하는 문장입니다. 그리고 attr()함수로 해당 태그의 요소를 값을 지정할 수 있는데 width과 height의 값을 각각 500으로 하면 그리기 svg 태그 켄버스를 500x500으로 영역을 지정한다고 생각하시면 됩니다.

5) 원영 챠트 영역 만들기

원형 챠트를 그리기 위해서는 arc()함수을 사용하는데 내부반지름 innerRadius()이고 외부반지름은 outerRadius()함수 입니다.

var arc = d3.arc().innerRadius(100).outerRadius(200);

arc변수에 내부원에서 외부원의 영역의 값을 저장해 놓습니다. arc 변수에 들어 있는 값은

console.log(arc); =>

function t(){var t,s,f=+n.apply(this,arguments),l=+e.apply(this,arguments),h=o.apply(this,arguments)-i_,p=u.apply(this,arguments)-i_,d=Zg(p-h),v=p>h;if(c||(c=t=ee()),le_)if(d>o_-e_)c.moveTo(l*Qg(h),l*t_(h)),c.arc(0,0,l,h,p,!v),f>e_&&(c.moveTo(f*Qg(p),f*t_(p)),c.arc(0,0,f,p,h,v));else{var g,_,y=h,m=p,x=h,b=p,w=d,M=d,T=a.apply(this,arguments)/2,N=T>e_&&(i?+i.apply(this,arguments):n_(f*f+l*l)),k=Kg(Zg(l-f)/2,+r.apply(this,arguments)),S=k,E=k;if(N>e_){var A=Qa(N/f*t_(T)),C=Qa(N/l*t_(T));(w-=2*A)>e_?(A*=v?1:-1,x+=A,b-=A):(w=0,x=b=(h+p)/2),(M-=2*C)>e_?(C*=v?1:-1,y+=C,m-=C):(M=0,y=m=(h+p)/2)}var z=l*Qg(y),P=l*t_(y),R=f*Qg(b),L=f*t_(b);if(k>e_){var q=l*Qg(m),D=l*t_(m),U=f*Qg(x),O=f*t_(x);if(de_?function(t,n,e,r,i,o,u,a){var c=e-t,s=r-n,f=u-i,l=a-o,h=(f*(n-o)-l*(t-i))/(l*c-f*s);return[t+h*c,n+h*s]}(z,P,U,O,q,D,R,L):[R,L],I=z-F[0],Y=P-F[1],B=q-F[0],H=D-F[1],j=1/t_(function(t){return t>1?0:t<-1?r_:Math.acos(t)}((I*B+Y*H)/(n_(I*I+Y*Y)*n_(B*B+H*H)))/2),X=n_(F[0]*F[0]+F[1]*F[1]);S=Kg(k,(f-X)/(j-1)),E=Kg(k,(l-X)/(j+1))}}M>e_?E>e_?(g=rc(U,O,z,P,l,E,v),_=rc(q,D,R,L,l,E,v),c.moveTo(g.cx+g.x01,g.cy+g.y01),Ee_&&w>e_?S>e_?(g=rc(R,L,q,D,f,-S,v),_=rc(z,P,U,O,f,-S,v),c.lineTo(g.cx+g.x01,g.cy+g.y01),S

우리가 직접 그린다면 이 복잡한 코딩을 전부해야 겠지요. d3.js에서 간단히 위의 한줄로 내부반지름과 외부반지름의 값을 지정만 하면 그 원 사이의 영역을 그리게 됩니다.

그리고, innerRadius(0) 이면 순수 원형 챠크가 됩니다.

6) 그릴 위치로 이동

var g = svg.append('g').attr('transform', 'translate(250,250)');

이제는 svg의 500x500 켄버스를 준비 했으면 이미지를 그릴 시작 위치로 이동을 합니다. 즉, svg에 500x500영역에서 'g'가 그려질 위치로 (250,250)이동하라는 명령입니다. 그리고, 앞에 객체변수 선언은 꼭 해주셔야 다음에 연결해서 뭔가의 표현 명령을 계속 이여서 코딩할 수 있습니다. svg이면 svg 객체명으로 표현하고 g이면 g객체명으로 선언하시면 가독성에 아마 좋을 꺼에요. append() 추가함수인데 그 안에 이름으로 객체변수 네임으로 활용하세요.

7) pie Chart 그리기

          g.selectAll('path.slice')
           .data(pieData)
           .enter()
           .append('path')
           .classed('slice', true)
           .attr('d', arc)
           .attr('fill', function(d,i){ return colorData[i]; });

pieData에 각 데이터별 계산된 pie 값을 arc()함수에서 그려 질 전체 pie 영역에서 각 데이터별로 그려집니다. 그리고 그려질 데이터의 'fill'의 생상은 아까 colorData[]에서 만든 랜덤색상으로 칠해지게 됩니다. 원형 챠트를 이해하실려면 html에서 그릴 때 각 요소와 값을 이해하고 오시면 편한데 모르더라도 위 틀을 전체를 외워 뒀다가 pieData, arc 변수값만 만들 수 있으면 위 코딩에서 해당 변수값만 대입하시면 pie Chart를 만들 수 있습니다. 물론 Pie Chart에 추가되는 부분들이 많지만 기본은 이정도만 표현하셔도 간단한 Chart로 표현이 가능하니깐 활용해 보세요.

8) 결과

2. 특정 기간 보팅 카운트 내역 Pie Chart


출처 : Steem.js 보팅카운트 세기 주제로 코딩 쉽게 하기


이제 Steem.js에 위에서 표현한 pie Chart 코딩을 적용해 볼까요.

지난 post에 올린 내용을 기반으로 특정 기간 보팅 카운트 내역 조회 코딩을 간단히 실험했습니다. 그 소스에서 이제는 데이터 시각화로 표현을 해보도록 할께요.

1) 지난 소스

document.getElementById('myDate1').valueAsDate = new Date();
document.getElementById('myDate2').valueAsDate = new Date();

function go(){
 var myId=  $("#myId").val();
 steem.api.lookupAccounts(myId, 1, function(err, lookupAccounts) {
  if(myId!=lookupAccounts) alert('error ID');
  else myVoting(myId);
 });
}

function myVoting(myId) {

 var myDate1 = $("#myDate1").val();
 var myDate2 = $("#myDate2").val();
 
 var dt = new Date(myDate1);
 var startDate = new Date(dt.setHours(dt.getHours() - 9)).toISOString().split('.')[0];
 dt = new Date(myDate2); 
 var endDate = new Date(dt.setHours(dt.getHours() + 15)).toISOString().split('.')[0];

 render(myId, startDate, endDate);
}

function render(author, startTime, endTime){
 steem.api.getAccountVotes(author, function(err, accountVotes) {
   // console.log(err, accountVotes);
  
  var voterCount={};
  var votersort=[];  
 
  for(d in accountVotes){
    if(accountVotes[d].time>=startTime && accountVotes[d].time<=endTime){
      var author = accountVotes[d].authorperm.split('/')[0];
                 
      //보팅한 카운트
      voterCount[author] = voterCount[author]?voterCount[author]+1:1;      
     
   }
  }
  //보팅 정렬
  votersort = Object.keys(voterCount).sort(function(a,b){return voterCount[b]-voterCount[a];});
  
  //보팅 name, voterCount 정보만 따로 변수에 저장
  for(k in votersort){
     ...
  }
 });
}

위 코딩은 지난 소스에서 필요 없는 부분을 다 생략 시킨 소스입니다. 위 코드를 이해 못하신다면 링크 출처에 가셔서 지난 post를 읽기 바랍니다.

2) 추가되는 부분

  //보팅 name, voterCount 정보만 따로 변수에 저장
  for(k in votersort){
     ...
  }

위 부분입니다. votersort 변수에는 보팅 횟수에 따라 정렬된 값이 들어 있습니다.

 //보팅 name, voterCount 정보만 따로 변수에 저장
  for(k in votersort){
    dataset.push({Name: votersort[k], voterCount :voterCount[votersort[k]]});         
  }

이렇게 dataset이라는 배열객체변수를 만들어 넣고 순자척으로 자신이 보팅한 스티미언 ID과 보팅한 횟수를 dataset에 집어 넣습니다.

[결과]

console.log(dataset);

이렇게 dataset 객체벼열변수에 값이 들어가게 됩니다.

3) pie() 함수 추가


  ... 생략
    
  //보팅 name, voterCount 정보만 따로 변수에 저장
  for(k in votersort){
    dataset.push({Name: votersort[k], voterCount :voterCount[votersort[k]]});         
  }
  
  //결과를 원형 그래프로 시각화
  pie(dataset);
 });
}

이렇게 dataset 객체배열변수에 data를 만들어 넣고 위 사용자 정의 함수인 pie() 함수에다가 dataset 값을 인자로 넘겨주면 지난 소스에서의 코딩 수정은 전부 끝납니다. 이제 Pie(dataset) 함수 내부에 코딩만 조금만 수정하면 됩니다.


pie(dataset) 함수로 위의 pie Chart를 연결해볼까요.

function pie(data){    
    var width = 500, height = 500;
    var colorData=[];

    var pie = d3.pie();
    var pieData = pie(data.map(function(d) { return d.voterCount; }));
 
    for(var i in data){
    //  colorData[i]="#" + Math.floor(Math.random()*0xffffff).toString(16);
      colorData[i]="#" + Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16);  
    }

  
    var svg = d3.select('#svg').selectAll('svg').remove();
        svg = d3.select('#svg')
                .append("svg")
                .attr('width', width)
                .attr('height', height)                
                .style("background-color","#f0f0f0")
                .attr("id", "piegraph");                
    var arc = d3.arc().innerRadius(100).outerRadius(200);

    var g = svg.append('g').attr('transform', 'translate(250,250)');
        g.selectAll('path.slice')
           .data(pieData)
           .enter()
           .append('path')
           .classed('slice', true)
           .attr('d', arc)
           .attr('fill', function(d,i){ return colorData[i]; });
  
};

이렇게 연결 되었습니다.

  var pie = d3.pie();
  var pieData = pie(data.map(function(d) { return d.voterCount; }));

이 부분이 약간 차이가 있는데 data 정보는 Name, voterCount의 정보가 들어 있기 때문에 pieData를 만들기 위해서는 voterCount의 값만 넘겨줘야 합니다. 표현은 위와 같습니다.

svg에 아래와 같은 부분이 추가시켰는데 이런식으로 style과 id명을 만들 수 있다는 것을 예를 들기 위해서 추가 했네요. 구지 이 표현을 안해도 상관 없습니다.

   .style("background-color","#f0f0f0")
   .attr("id", "piegraph");                

나머지는 그대로 동일합니다. pie Chart를 만들고 싶을때 data만 있으면 만들어 놓음 사용자 정의 pie()함수로 쉽게 호출해서 그릴 수 있겠죠.

에니메이션 효과를 넣어서 정확히 pieData를 기준으로 어떻게 그려지는지 볼까요.

결과로 본 애니메이션 효과는 부분은 인용한 코딩이라서 사실 실제 아래의 공개된 소스나 최종 결과물에서는 올리지 않았습니다. 별로 공부한 적이 없고 2년전에 잠깐 몇일 공부한게 전부라 css 애니메이션 효과는 지금은 좀 쓰기 불편합니다. 인용 정도로 활용하는 수준이라서 사실 이부분을 post에 추가하기가 그래서 생략합니다. 단지, 위에서 pie Chart가 어떻게 그려지는지 보여드리기 위해서 결과물 이미지만 보여드립니다. pieData 값이 순서대로 이렇게 그려진다는 것을 참고하시면 됩니다.

4) 전체 보팅한 수 출력 추가 기능

    svg.append("text")
            .attr("class", "Count")
            .attr("transform", "translate("+(width/2-70)+", "+(height/2+10)+")")
            .style("font-size","30px")           
            .text("Count:" + d3.sum(data.map(function(d) { return d.voterCount; })));

text를 추가하는데 svg 태그에 추가하게 됩니다. 전체 보팅한 카운터를 pie Chart 정 중앙에 출력하고 싶어서 text가 써질 위치는 transform 요소로 해당 위치로 글이 출력할 위치로 이동하게 합니다 style은 글자 스타일을 여기서 이렇게 지정할 수 있고 css에서 지정 가능합니다. 예를 든 차원입니다. 실제 출력은 text()함수로 출력합니다. d3함수에서 엑셀처럼 합함수가 있는데 sum()함수는 전체 voterCount값을 합산하여 그 결과를 pie Chart 정중앙에 출력합니다.

참고로 svg은 500x500의 켄버스 위치에서 글자가 출력될 위치니깐 대충 transform 요소의 translate(x,y)로 첫글자가 출력될 위치입니다. 만약에 g 객체변수를 기준으로 했다면 영역이 그러진 위치를 기준에서 출발하겠죠. 여기에서는 svg 기준으로 글자를 출력시킨 예제입니다.

5) 마우스 이벤트 추가 기능

마우스 이벤트를 통해서 해당 영역에 마우스가 들어가 그 해당여역의 스티미언 ID와 보팅수를 출력하게 하고 마우스가 해당 영역을 빠져나오면 지우도록 하는 설정입니다.

g 객체변수에서

.on("mouseover", function(d,i) {
      var output = '<button type="button" class="btn btn-primary">'+data[i].Name+'<span class="badge badge-light">'+data[i].voterCount+'</span><span class="sr-only">unread messages</span></button>'
      $('#output').html(output);        
})
.on("mouseout", function(d) {
               $('#output').html(''); 
})        

'mouseover' 상태이면 마우스가 해당 영역에 들어오면 이 함수가 실행 되는데 output에 data[i].Name, data[i].voterCount의 값을 디자인한 태그로 만들어놓고 $('#output').html(output) 명령으로 id가 'output'인 태그로 해당 결과물을 html형식으로 출력하라는 명령입니다. 즉, 마우스가 해당 pie Chart 영역에 들어가면 해당 영역의 스티미언 ID, 보팅수가 출력되는 것이죠.

'mouseout' 상태이면 마우스가 해당 영역에서 벗어나면 이 함수가 실행 되는데 id가 'output'인 태그에 ' ' 공백문자로 초기화 시키면 이전에 html로 출력한 결과가 사라지게 됩니다.

3. 종합 소스


** [pieChart.html 소스]**

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="index.css" rel="stylesheet" type="text/css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  </head>
  <body>
   <form class="form-inline">
    <div class="form-group mb-2">
      <span class="input-group-text" id="basic-addon1">@</span>
      <input type="text" class="form-control" id="myId" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
    </div>
    <div class="form-group mx-sm-3 mb-2">      
      <input class="input-group-text" type="Date" id="myDate1" />
      <span class="input-group-text" id="basic-addon1">~</span>
      <input class="input-group-text" type="Date" id="myDate2" />
    </div>
    <div class="form-group mb-2">
      <button type="button" class="btn btn-primary" onclick="go()">조회</button>
    </div>
   </form>   
   <div id="svg"></div>
   <div id="output"></div>
    <script src="index.js"></script>
  </body>
</html>

**[pieChart.js 소스]

document.getElementById('myDate1').valueAsDate = new Date();
document.getElementById('myDate2').valueAsDate = new Date();

function go(){
 var myId=  $("#myId").val();
 steem.api.lookupAccounts(myId, 1, function(err, lookupAccounts) {
  if(myId!=lookupAccounts) alert('error ID');
  else myVoting(myId);
 });
}

function myVoting(myId) {

 var myDate1 = $("#myDate1").val();
 var myDate2 = $("#myDate2").val();
 
 var dt = new Date(myDate1);
 var startDate = new Date(dt.setHours(dt.getHours() - 9)).toISOString().split('.')[0];
 dt = new Date(myDate2); 
 var endDate = new Date(dt.setHours(dt.getHours() + 15)).toISOString().split('.')[0];

 render(myId, startDate, endDate);
}

function render(author, startTime, endTime){
 steem.api.getAccountVotes(author, function(err, accountVotes) {
   // console.log(err, accountVotes);
  
  var voterCount={};
  var votersort=[];
  var dataset = [];
 
  for(d in accountVotes){
    if(accountVotes[d].time>=startTime && accountVotes[d].time<=endTime){
      var author = accountVotes[d].authorperm.split('/')[0];
                 
      //보팅한 카운트
      voterCount[author] = voterCount[author]?voterCount[author]+1:1;      
     
   }
  }
  //보팅 정렬
  votersort = Object.keys(voterCount).sort(function(a,b){return voterCount[b]-voterCount[a];});
  
  //보팅 name, voterCount 정보만 따로 변수에 저장
  for(k in votersort){
    dataset.push({Name: votersort[k], voterCount :voterCount[votersort[k]]});         
  }

  //결과를 원형 그래프로 시각화
  pie(dataset);
 });
}

function pie(data){    
    var width = 500, height = 500;
    var colorData=[];

    var pie = d3.pie();
    var pieData = pie(data.map(function(d) { return d.voterCount; }));
 
    for(var i in data){
    //  colorData[i]="#" + Math.floor(Math.random()*0xffffff).toString(16);
      colorData[i]="#" + Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16)+ Math.round(Math.random()*255).toString(16);  
    }

      var svg = d3.select('#svg').selectAll('svg').remove();
          svg = d3.select('#svg')
                .append("svg")
                .attr('width', width)
                .attr('height', height)                
                .style("background-color","#f0f0f0")
                .attr("id", "piegraph");                
    var arc = d3.arc().innerRadius(100).outerRadius(200);

    var g = svg.append('g').attr('transform', 'translate(250,250)');
        g.selectAll('path.slice')
           .data(pieData)
           .enter()
           .append('path')
           .classed('slice', true)
           .attr('d', arc)
           .attr('fill', function(d,i){ return colorData[i]; })
           .on("mouseover", function(d,i) {
               var output = '<button type="button" class="btn btn-primary">'+data[i].Name+'<span class="badge badge-light">'+data[i].voterCount+'</span><span class="sr-only">unread messages</span></button>'
               $('#output').html(output);        
            })
           .on("mouseout", function(d) {
               $('#output').html(''); 
            })        

        svg.append("text")
           .attr("transform", "translate("+(width/2-70)+", "+(height/2+10)+")")
           .style("font-size","30px")           
           .text("Count:" + d3.sum(data.map(function(d) { return d.voterCount; })));
};

4. 결과


특정 기간 보팅 카운트 시각화 조회 : https://steemcoding.github.io/dicegame.github.io/pieChart.html



이렇게 스티미언 ID와 특정 기간의 날짜를 지정하고 조회하면 위 그림처럼 자신이 보팅한 내역에서 전체 보팅수랑 보팅을 한 사람들을 색을 보팅수만큼 보여지게 됩니다.

그리고 해당 영역을 마우스로 가져다 대면 아래와 같은 이미지로 출력됩니다.

위그림에서 마우스로 색이 칠해진 pie Chart 영역에 들어가면 그 영역의 ID와 보팅수가 보시는 것처럼 아래 출력됩니다.

참고로, 영역을 벗어나면 아래 ID와 보팅수 태그는 사라지게 됩니다.

마무리


그냥 간단하게 표현한 pie Chart 입니다. 사실 d3.js의 기능을 제대로 활용하지 못한 테스트 실험이였습니다. 제대로 d3.js를 활용했다면 이보다 더 멋진 모습이겠죠. 다 까먹어서 예전에 쓰던 함수들에 대해서 예제들을 찾고 그 함수를 이해하고 코딩을 하다보니깐 토요일 오후에 잠깐 구상한 내용이라서 제대로 결과물이 나오지 못했네요.

post의 의도는 d3.js가 그렇게 어렵지 않고 모르더라도 틀만 만들어 넣으면 위에서 실험했던 것처럼 바로 Steem.js API로 통해 얻은 데이터를 바로 시각화가 가능해 집니다.

여기서, 변형시킨다면 글을 쓰다가 떠오른 생각이지만 저번에 스티미언 분 중에 보팅을 평판에 따른 보팅 시각화가 있었는데 그 표현도 가능합니다. Steem.js ID별 평판 조회하고 0~10평판 , 10~20평판, ... 90~100평판으로 10단계로 쪼개서 10단위 평판별 보팅 Chart도 만들 수 있게 됩니다. 즉, data만 만들어 내면 해당 평판별 챠트도 쉽게 구현이 가능합니다. 이외에 여러분들이 한번 상상해서 다양한 데이터 시각화를 구현해 보세요.

d3.js로 시각화 틀만 한 두개 만들어 놓고 거기에 Steem 블록체인의 정보를 처리한 데이터를 그냥 만든 Chart에 대입만 하면 다양한 시각화가 가능해집니다. d3.js에 공부에 도전해 보세요. Chart 틀만 몇개 만들어 넣으면 Steem.js API로 읽은 블록체인 정보를 데이터 형식으로 만드는 작업만 하시면 만들어 놓은 Chart에 대입하여 활용하면 멋진 Steem 데이터 시각화가 되겠죠.

Sort:  

Steem.js 보팅에 대해 관심이 가네요. 저도 좋은 글 많이 쓰겠습니다.~

보팅도 괜찮지만 스티미언 간의 연결 정보를 잘 데이터화 하면 스티미언 활동을 보다 효율적으로 관리할 수 있어서 괜찮은 것 같아요. 스티미언 간의 교류 쪽으로 관심을 가져보세요.

ㅎㅎㅎㅎ역시 교류는 정말 중요합니다 저도 관심을 가지고 도움이 될 수 있는 포스팅을 할게요

멋지십니다 개발 내용도 정리 잘해주시고 잘 읽고 가요~

감사합니다.

짱짱맨 호출에 출동했습니다!!

짱짱맨 방문에 감사합니다.

Language 도 참 많다는 생각이 듭니다. 다 공부할려면 머리가 아플것 같습니다.

d3.js API로 데이터 시각화하는 함수들을 미리 다 만들어놓은 자바스크립트라고 생각하시면 돼요.
직접 데이터 시각화하는데 코딩할려면 참 복잡한 로직이나 수학적인 부분을 직접 짜셔야 하는데 그걸 대신 함수로 다 만들어 넣고 제공해 주고 있어요.
장점은 쉽고 강력하다는 것이고. 단점은 버전이 바뀔때마가 함수명이나 위치가 수시로 바뀌어서 버전별 충돌을 감수해야한다는 점만 빼면은 엄청 쉬운편에 속해요.
참고로 html의 svg, css, 자바스크립트에 대한 표현을 어느정도 사전 지식이 있으면 배우는 속도는 엄청 빨라져요.

요 근래 한사람이 2개이상의 계정을 이용하여 감성팔이를 하다 걸리셨는데 그런것을 쉽게 알수있는 방법도 보팅 시스탬적으로 분별 가능할까요?

블록체인 정보를 추적하면 어느정도 소유주를 확인 가능합니다. 그리고 예전에 보니깐 스파임대로 부계정임대하는 분도 있엇는데 임대 조회하면 누구에게 임대 했는지 조회가 가능하기 때문에 아예 부계정 일정스파 올리고 시작하는 경우가 있고요.
참고로 스팀/스달을 수익을 옮겨야 하잖아요. 부계정에서 부계정으로 릴레이 뺑뺑이 하시는 블록체인 정보도 본적 있어요. 최종 부계정 에서 upbit로 송금하더군요.
블록체인 공부하다보면 못볼 것도 보고 그래요.

Coin Marketplace

STEEM 0.16
TRX 0.15
JST 0.030
BTC 58510.90
ETH 2522.39
USDT 1.00
SBD 2.36