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

in #kr-dev6 years ago (edited)

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



지난 시간에 코딩에 대해서 이야기 하다가 초보분들에게 한번 예제를 들어서 코딩 과정을 이야기 하면 좋을 것 같아서 오늘 post 주제로 정했네요. 그러면, 코딩을 할 때 초보분들은 어떤식으로 하면 되는지 간단한 주제인 자신이 보팅을 누구에게 했는지 얼마큼 했는지 카운트를 세는 프로그램을 만들어 보면서 살펴보도록 하겠습니다. 사용될 소스는 특정 날짜의 보팅 내역 조회를 간단히 실험한 소스를 기반으로 하는데 이 소스를 가지고 수정해서 만들어 보겟습니다.

1. 기존 소스를 변형 시키기(특정기간보팅내역조회)



소스는 Steem.js로 특정 날짜의 보팅 내역 조회 post를 참조하시고 이곳에서는 그냥 수정 내용만 담겠습니다.

(1) 기존 소스 분석 방법

우선, vodingday.js을 활용하기 때문에 남의 소스라고 가정하고 접근해 보겠습니다. 우선 각 코딩을 나눠 볼까요.

document.getElementById('myDate').valueAsDate = new Date();

function go(){ ... }

function myVoting(myId) { ... }

function votingpost(author, permlink,time){ ... }

이렇게 큰틀로 4개로 나눠지네요. 각각을 개별적으로 실행시켜보셔야 합니다. document 명령문 라인은 html로 시간값을 내보내는 자바스크립트 코딩입니다. 잘 모르는 표현이시라면 "document 자바스크립트"키워드로 구글검색하시면 관련 자료를 구하실 수 있을 꺼에요. id가 "myDate"태그가 html에 어떤 태그인지 가셔서 보시면 입력시간 태그이니깐 만약 모른다면 "입력시간 태그 html"로 관련해서 구글검색하시면 쉽게 찾을 수 있을꺼에요. 이렇게 모르는 것은 쪼개서 하나씩 그 의미를 분석 하시면 됩니다.

다음 함수 go()만 실행해서 결과를 살펴보세요.

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

여기서, go()함수에서
첫번째,

 var myId=  $("#myId").val();
 console.log(myId);

두번째,

steem.api.lookupAccounts(myId, 1, function(err, lookupAccounts) { 
  console.log(err, lookupAccounts);
}

세번째,

  if(myId!=lookupAccounts) console.log(1);
  else console.log(0);

각각의 코딩을 실행했을 때 console.log()함수 어떤 값이 찍히는지 실행해 보셔서 명령문의 결과를 보고 어떤 의미를 갖는지 파악하시면서 이해하셔야 합니다. 그리고 나머지 myVoting(), votingpost()도 비슷한 과정을 거쳐서 살펴보시고, 또, 모르는 함수가 나오면 "함수명 자바스크립트" 키워드로 구글검색하시면 자료를 쉽게 찾을 수 있으니깐 그런식으로 자바스크립트 함수를 배우시면 됩니다.

(2) 특정 구간 보팅 내역 조회 코딩하기

기존 소스를 분석해 봅시다.

 var myDate = $("#myDate").val();
 var dt = new Date(myDate);
 var startDate = new Date(dt.setHours(dt.getHours() - 9)).toISOString().split('.')[0];
 var endDate = new Date(dt.setDate(dt.getDate()+1)).toISOString().split('.')[0];

위 코딩에서 특정 날짜에 보팅내역의 하루의 0~24시 구간이 Date()함수에 의해서 계산되어 나옵니다. 그렇다면 이 부분을 특정 시작날짜와 특정 종료날자로 바꾼다면 어떤게 코딩할지를 머리속에으로 하시든지 아니면 글로서 이렇게 표현하고 싶은 내용을 적어 놓습니다.

statDate => 특정 시작 날짜인데 0시에서 출발한다.
endDate => 특정 종료 날짜인데 24시에서 종료한다.

이부분을 코딩하면 원하는 결과를 얻게 됩니다. 이게 두개의 날짜로 입력을 받게 수정하면 되겠죠. 전체 소스 코딩창에다 바로 코딩 할 수 있지만 결과를 정확하게 하기 위해서 그리고 에러가 발생하지 않도록 하기 위해서 새로운 창에서 먼저 테스트 해야 합니다. 새로운 창에서 기존 코딩을 수정 해보도록 할까요.

 var myDate1 = '2018-05-10'; //시작날짜
 var myDate2 = '2018-05-20'; //종료날짜

이렇게 변수 이름을 제대로 작명해야하는데 테스트니깐 그냥 대충 지었습니다. 시작 날짜와 종료 날짜의 가상날짜를 우선 만들어 놓습니다.

우선, 시작날짜시간(statDate)은 ISO로는 표기상 -9시간이니간 아래와 같이 코딩합니다. Date(), setHours(), toISOString(), split() 중에 모르는 함수가 있다면 해당 "함수명 + 자바스크립트"로 구글 검색하시면 쉽게 해당 함수에 대한 설명과 예제를 쉽게 찾을 수 있고 그 의미를 이해하신 후에 사용하세요. 아래 코딩은 핵심은 "dt.setHours(dt.getHours() - 9)" 명령입니다. 이 의미만 제대로 이해하시면 시간 제어는 쉽습니다.

var dt = new Date(myDate);
var startDate = new Date(dt.setHours(dt.getHours() - 9)).toISOString().split('.')[0]; 
console.log(startDate);

결과 :

"2018-05-09T15:00:00"

이렇게 나옵니다. 종료 날짜는 종료날짜 24시가 되는 시간대인데 ISO 시간으로 한다면 반대로 +15시간 하면 되겠죠.

 dt = new Date(myDate2); 
 var endDate = new Date(dt.setHours(dt.getHours()+15)).toISOString().split('.')[0];
 console.log(endDate);

결과 :
"2018-05-20T15:00:00"

이렇게 해서 특정 기간의 시간을 구할 수 있게 됩니다. 이렇게 새로운 코딩창에서 개별적으로 실행 시켜서 그 결과가 원하는 결과로 나왔을 때에 실제 전체 소스 코딩창에다 삽입하시면 됩니다.

위 코딩을 삽입하면은.

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);
}

이렇게 해서 코딩은 끝나게 됩니다. 참고로 html 입력시간 태그에서 두개의 값을 가져와야 하니깐 그 부분도 입력시간태그가 2개가 필요 합니다.

입력 폼은 대충 이렇게 id가 myDate1, myDate2라는 두개의 input 태그로 늘리면 소스가 완성 됩니다.

  <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>

(3) 결과



2. 특정기간보팅카운트


  • 내용 : 특정 기간동안 자신이 보팅을 누구에게 얼마 만큼 했는지 조회를 해보자.

(1) 출발

특정기간 동안 보팅 카운트를 하기 위해서는 기존의 코딩을 조금만 수정하면 되지만 설정은 새로 코딩을 한다고 가정해보고 코딩을 하도록 하겟습니다.

여기서, 필요한 것이 뭘까요. 특정기간 동안 보팅 정보니깐 2가지정도의 정보를 우선 찾아야 합니다.

  • 자신의 보팅한 내역 알 수 있는 Steem.js API 함수
  • 특정기간이니깐 Date() 시간 함수

대충 처음에는 이정도에서 출발하겠죠.

(2) 검색

우선 출발에 필요한 2개의 함수에 대해 조사해 봅시다. 구글 검색사이트에서 해당 키워드로 검색하시면 다양한 정보를 확인 할 수 있습니다.

자신의 보팅내역 함수 찾기
https://github.com/steemit/steem-js/tree/master/doc

 steem.api.getAccountVotes(author, function(err, accountVotes) {
   console.log(err, accountVotes);
 });

date() 함수에 대해 조사
https://www.w3schools.com/jsref/jsref_obj_date.asp
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date
https://msdn.microsoft.com/ko-kr/library/cd9w2te4

대충 조사가 끝나고 함수들에 대해서 어느정도 이해하셨으면 코딩에 들어가게 됩니다. 참고로, 개별적으로 코딩하여 실행한 다음 전체 코딩할 곳에 코딩하는 습관을 가져 주세요.

(3) 코딩 과정



자신의 보팅 내역이 들어 있는 Steem.js API 함수 steem.api.getAccountVotes()함수를 사용하게 됩니다.

steem.api.getAccountVotes(author, function(err, accountVotes) {
   console.log(err, accountVotes);
 });

여기서, 사용자 정의 함수를 하나 만들어서 이 함수를 넣어 둡니다.

코딩할 사용자정의 함수를 하나 만들어 놓습니다. author은 거색할 계정ID입니다. author에 자신의 아디로 우선 테스트 해보세요.

function render(author){
 steem.api.getAccountVotes(author, function(err, accountVotes) {
    console.log(err, accountVotes);
 }
);

실행 시켜서 어떤 값을 가지고 있는지 살펴보시고 안에 값들을 분석하셔야 합니다. author='codingman'일때 결과는 다음과 같습니다.


우리에게 필요한 정보는 authorperm의 들어 있군요. authorperm값을 가지고 해당 계정ID를 카운트를 세면 되겠죠. 카운트를 세려면 어떻게 해야할까요. 블록체인 정보에 보면 time이라는 값이 있습니다. 즉, 보팅한 시간을 나타냅니다. 아! 그러면 보팅시간을 기준으로 조회할 날짜 구간을 잡으면 되겠구나 하고 떠올리시면 됩니다.

개별적으로 코딩하여 명령문을 실행시켜서 정상적인 결과가 나올 때만 전체 소스 코딩창에 삽입하라고 했죠. 그러면, 먼저 조회할 특징 날짜 구간을 만들어 내야 합니다. 그 부분을 새로운 코딩창에서 실험하시면 됩니다.

그런데, 시간의 출력형식을 보니 ISO 형식입니다. 한번 현재시간의 ISO 형식으로 새로운 창에서 실행 시켜봐야 겠죠.

var dt = new Date();
console.log(dt.toISOString());

결과 :

"2018-05-20T09:58:26.606Z"
=> Sun May 20 2018 18:58:26 GMT+0900 (대한민국 표준시)

새로운 창에서 실행시켰을 때 한국시간과 9시간을 차이를 발견하게 될꺼에요. 시간을 비교하기 위해서는 한국시간에서 -9시간을 해야한다는 것을 알게 될꺼에요. 그리고 시간을 비교하기 위해서 ISO시간으로 비교해야 하기 때문에 선택한 날짜에 대한 시간은 선택한 날짜에 시간에 -9시간을 해야한다는 것을 깨닫게 됩니다. 그리고 비교할 때는 초 이하를 절삭해야 하기 때문에 다음과 같겠죠.

**
var dt = new Date('시작날짜');
var startDate = new Date(dt.setHours(dt.getHours() - 9)).toISOString().split('.')[0];
**
역으로, 종료 날짜는 선택날짜에 -9시간에서 하루니깐 시간상으로 선택 날짜에서 +15시간을 하게 되면 종료날짜를 구할 수 있게 됩니다.

dt = new Date('종료날짜'); 
var endDate = new Date(dt.setHours(dt.getHours() + 15)).toISOString().split('.')[0];

html에서 입력날짜 태그를 body 태그 안에다가 우선 선언 해 두어야 됩니다.

<input type="Date" id="myDate1" />
<input type="Date" id="myDate2" />

$("#myDate1").val();
$("#myDate2").val();
이렇게 해서 해당 입력시간태그의 날짜값을 가져오게 됩니다. jQuery 문법인데 혹시 코딩이 간단해서 사용했습니다. html 입력태그 관련 키워드로 검색하시면 몇가지 표현하는 예제를 찾을 수 있을꺼에요.
저는 https://www.w3schools.com/jquery/default.asp 사이트에서 jQuery 30분정도 전체적으로 공부하고 나서 사용하게 되었지만요. 아무튼 여러분들도 뭔가 표현하고 싶거나 표현을 모를 때 관련 유사 단어로 검색하시면 됩니다. 어느정도 습득이 되었다면 코딩으로 넘어갑니다.

그러면 위에서 특정기간 구하기 코딩에서 했으니깐 종합해 보면 이렇게 코딩이 됩니다.

 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];

이 코딩은 이제 문제가 없으니깐 전체소스 코딩창에다가 삽입해 놓습니다.

function render(author){
 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];

 steem.api.getAccountVotes(author, function(err, accountVotes) {
    console.log(err, accountVotes);
 }
);

이제는 특정시작날짜와 특정종료날짜의 시간값을 구했지만 가상 날짜를 기존의 창이면 myDate1, myDate2의 값을 가상 날짜 값으로 세팅하거나 아니면 세로운 창에다가 복사 하셔도 별도로 실험할 준비를 해주세요. 다음 보팅 조회가 실시 하실려면요. 왜! 외부 html 입력시간태그로 값을 가져오지 않느냐면 실행시 계속 html에서 입력 받고 다시 실행하고 번거로움이 생기기 때문에 아예 가상날짜 데이터로 아래와 같이 지정해놓고 바로 결과를 추출한다면 바르게 테스트를 할 수 있게 됩니다. 이제 정해진 구간의 보팅의 횟수를 계산해야 합니다.

 var myDate1 = '2018-05-19'; //시작날짜
 var myDate2 = '2018-05-20'; //종료날짜

 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];


 steem.api.getAccountVotes(author, function(err, accountVotes) {
   // console.log(err, accountVotes);
      새로운 코딩;
   
 });

위 코딩을 새로운 코딩창에다 복사해 놓습니다. 그러면 다음 getAccountVotes()함수 안에 새로운 코딩을 시작하시면 됩니다.

새로운 코딩에 이제 accountVotes 정보에서 선택한 날짜구간에 맞는 보팅한 정보를 뽑아 내야 겠지요. 순차적으로 하나씩 뽑아 낸다면

for(d in accountVotes){
 accountVotes[d]정보를 뽑아서 시간과 비교합니다.
}

뽑아온 보팅 정보중 시간이 시작날짜와 종료날짜에 들어가는지 봐야겠지요

    if(accountVotes[d].time>=startTime && accountVotes[d].time<=endTime){
          여기에 들어온 accountVotes[d].authorperm가 선택한 기간의 보팅한 사람이 되겠습니다.
        }

이렇게 설정하게 됩니다. accountVotes[d].authorperm 안에는 계정ID/게시물주소가 들어 있기 때문에 쪼개야 합니다.

하나의 가상 accountVotes[d].authorperm 값을 새로운 코딩창에서 쪼개기 실험을 하세요.

var authorperm = "codingman/6nbzf";
var author= authorperm.split('/')[0];
console.log(author);

결과 : "codingman"

이렇게 정상적으로 쪼개지면 이 코딩을 render()함수에 삽입합니다.

function render(author){
 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];

 steem.api.getAccountVotes(author, function(err, accountVotes) {
    for(d in accountVotes){
    if(accountVotes[d].time>=startTime && accountVotes[d].time<=endTime){
      var author = accountVotes[d].authorperm.split('/')[0];
                 
      //보팅한 카운트
            
     //전체카운트
   }
  }
 });

이제 카운트를 셀 차례입니다. author를 카운터 셀려면 여러가지 방법이 있지만 배열 요소(키)값을 세는 방식을 키워드로 검색하시면 찾을 수 있을꺼에요. 뭔가를 표현하고 싶으면 뭔가에 대한 키워드를 검색하시면 어느정도 유사한 표현을 찾을 수 있습니다. 찾으셨다면 관련 코드를 새로운 창에서 다시 동작을 테스트 합니다.

var aaa = ['a', 'b', 'a'];
var count = {};

for(k in aaa){
 count[aaa[k]]= count[aaa[k]]?count[aaa[k]]+1:1;
}
console.log(count);

결과 :

[object Object] {
  a: 2,
  b: 1
}

이렇게 원하는 결과가 나왔으면 이 부분을 rendero()함수에 삽입합니다.

  var voterCount={};  
  var cnt = 0;
    if(accountVotes[d].time>=startTime && accountVotes[d].time<=endTime){
      var author = accountVotes[d].authorperm.split('/')[0];
                 
     //보팅한 카운트
      voterCount[author] = voterCount[author]?voterCount[author]+1:1;      
      //전체 카운트
      cnt+=1;
   }

이렇게 해서 voterCount 값을 console.log(voterCount)로 원하는 결과가 나왔는데 다시 한번 테스트 합니다.
var myDate1 = '2018-05-19';
var myDate2 = '2018-05-20';
일때,

{ kiljunyoon: 1,
  cowboybebop: 2,
  mooyeobpark: 1,
  jisung: 1,
  minhan: 1,
  virus707: 2,
  sjchoi: 2,
  silkroadgo: 1,
  wonsama: 2,
  'dorian-lee': 1,
  codingman: 2,
  'curl-j': 1,
  kim0jh0: 1,
  song1: 1,
  goodcontent4u: 1,
  binterest: 1 }

이제 출력은 어떻게 해야 할까요. 우선 요소(키값) 계정ID과 그 요소값은 보팅 카운트 값입니다. "배열 or 객체 요소(키)값 출력 자바스크립트" 키워드로 구글검색하시면 Object.keys()함수가 있습니다. 이걸로 요소(키)값을 가져올 수 있습니다. 이게 어떻게 돌아가는지 새로운 코딩창에서 테스트 합니다.

var aaa = ['a', 'b', 'a'];
var count = {};

for(k in aaa){
 count[aaa[k]]= count[aaa[k]]?count[aaa[k]]+1:1;
}
var bbb = Object.keys(count);

console.log(bbb);

결과 : ["a", "b"]

요소값을 배열로 해서 순차적으로 bbb라는 배열변수에 저장되었네요.

추가로 카운트까지 결과가 정상적으로 나오는지 확인합니다.

var aaa = ['a', 'b', 'a'];
var count = {};

for(k in aaa){
 count[aaa[k]]= count[aaa[k]]?count[aaa[k]]+1:1;
}
var bbb = Object.keys(count);

for(k in bbb){
  console.log(bbb[k]+' : '+count[bbb[k]]);
}

결과:
"a : 2"
"b : 1"
정상적으로 작동하니깐 render()함수에 삽입합니다.

  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;      
      //전체 카운트
      cnt+=1;
   }
  }
  votersort = Object.keys(voterCount)
  for(k in votersort){
    console.log(votersort[k]+' : '+voterCount[votersort[k]]);
  }

결과 :

kiljunyoon : 1
cowboybebop : 2
mooyeobpark : 1
jisung : 1
minhan : 1
virus707 : 2
sjchoi : 2
silkroadgo : 1
wonsama : 2
dorian-lee : 1
codingman : 2
curl-j : 1
kim0jh0 : 1
song1 : 1
goodcontent4u : 1
binterest : 1

결과를 보면 오름차순이든 내림차순이든 정렬이 되면 좀 더 깔끔하겠죠. 여기서 또 정렬하는 법을 "정렬+자바스크립트" 키워드로 구글검색을 합니다. 그리고, 설명과 예제를 보시고 테스트 합니다.

votersort = Object.keys(voterCount).sort(function(a,b){return voterCount[b]-voterCount[a];});

sort라는 함수가 있는데 요소(키)값을 추출한 배열 변수에 새로운 창에서 가상 데이터를 위에 위 테스트 예제 중 a,b를 해놓은 소스에 적용해서 테스트 해서 정상적으로 작동했다는 전제하에 이 명령문을 render()함수에 삽입합니다. 위 정렬은 요소(키)값을 기준으로 정렬을 하는데 그 키 값은 voterCount[]배열은 요소(키)의 카운터 값을 담고 있기 때문에 그 값을 비교해서 정렬을 하게 됩니다. 한번 따로 새로운 코딩창에서 가상 데이터를 넣고 테스트 하면 그 의미를 이해하실 수 있을꺼에요. 정상적으로 작동하니깐 render()함수에 삽입하면 우리고 얻고자 하는 결과를 만들어 낼 수 있게 되었습니다.

이제 다 종합한 소스로 html 로 이쁘게 출력하면 됩니다.

결과가 나왔다면 이제 html로 출력을 해볼까요.

  <div id ="count"></div>
  <table class="table table-striped" id="output"></table>

출력 위치를 정해 놓고 전체 카운트는 div 태그에 그리고 보팅한 계정ID는 테이블로 출력하도록 설정할 경우에 이 표현을 넣기 위해서 또 새로운 코딩창에서 테스트 합니다. 테이블을 형식을 잘 모른다면 테이블 태그 검색을 하시면 됩니다.

https://getbootstrap.com/docs/4.1/content/tables/

위 소스가 간단히 나와 있으니깐 가셔서 공부하시면 됩니다. 이렇게 필요할 때는 검색을 하고 그 부분을 실행 시켜서 사용하시면 됩니다.

새로운 창에서

  var count = '<button type="button" class="btn btn-primary">Count <span class="badge badge-light">'+13+'</span><span class="sr-only">unread messages</span></button>'
  $('#count').html(count);

이렇게 코딩을 했다면 실행시키면

마음에 들면 전체소스에 삽입하면 됩니다. 테이블 역시 삽입하면

function render(author){
 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];
 
 steem.api.getAccountVotes(author, function(err, accountVotes) {
   // console.log(err, accountVotes);
  
  var voterCount={};
  var votersort=[];
  var cnt = 0;
  var output='<thead class="thead-dark"><tr><th>ID</th><th>VOTING COUNT</th></tr></thead><tbody>';
  
 
  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;      
      //전체 카운트
      cnt+=1;
   }
  }
  votersort = Object.keys(voterCount).sort(function(a,b){return voterCount[b]-voterCount[a];});
  for(k in votersort){
   output += '<tr><td>'+votersort[k]+'</td><td>'+voterCount[votersort[k]]+'</td></tr>';   
  }
  output +='</tdoby>';
  $('#output').html(output);

  var count = '<button type="button" class="btn btn-primary">Count <span class="badge badge-light">'+cnt+'</span><span class="sr-only">unread messages</span></button>'
  $('#count').html(count); 
 });
}

계정ID로 입력 태그로 검색을 하고 싶다면

steem.api.lookupAccounts(myId, 1, function(err, lookupAccounts) {
  console.log(err, lookupAccounts);
 });

이 함수를 사용하는데 Steem.js로 특정 날짜의 보팅 내역 조회 post의 "2. 계정 ID 조회 가능한지 판단" 내용을 참고하시면 되겠습니다. 너무 길어져서 이 부분은 생략할께요

그리고 세부분으로 나눠서 사용자 정의 함수로 나눌께요. 참고로 사용자 정의 함수로 만들어서 쪼갤 때는 여러분이 원하는 스타일로 쪼개면 됩니다. 나주엥 뭔가 분류해서 새롭게 추가할지 삭제할지 모르기 때문에 뭔가 구상하신 것들이 있으면 그 기준으로 쪼개서 사용자 함수로 만드시면 됩니다.

  • 계정 ID 확인 => go()
  • 특정날짜기간 => myVoting(myId)
  • 보팅카운트 => render(author, startTime, endTime)

이렇게 사용자정의 함수로 분리 시켜서 코딩을 배치하면 마무리 됩니다.

(4) 전체 소스


[votingCnt.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>
</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 ="count"></div>
  <table class="table table-striped" id="output"></table>

  <script src="votecnt.js"></script>
</body>

</html>


[votingCnt.js]


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

function go(){
 //var myId= document.getElementById("myId").value;
 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 cnt = 0;
  var output='<thead class="thead-dark"><tr><th>ID</th><th>VOTING COUNT</th></tr></thead><tbody>';
  
 
  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;      
      //전체 카운트
      cnt+=1;
   }
  }
  votersort = Object.keys(voterCount).sort(function(a,b){return voterCount[b]-voterCount[a];});
  for(k in votersort){
   output += '<tr><td>'+votersort[k]+'</td><td>'+voterCount[votersort[k]]+'</td></tr>';   
  }
  output +='</tdoby>';
  $('#output').html(output);

  var count = '<button type="button" class="btn btn-primary">Count <span class="badge badge-light">'+cnt+'</span><span class="sr-only">unread messages</span></button>'
  $('#count').html(count); 

 });
}

(5) 결과



마무리


좀 두서없이 오늘 post가 되었네요. 일요일이라 글쓰기 참 싫었던 것 같네요

위에서 코딩을 보면 사실 제 경우 제대로 공부한 적은 없고 필요한 표현이 있으면 그 표현을 구글 검색을 통해서 관련 된 자바스크림트 함수를 찾아서 함수의 의미를 이해하고 가상 데이터로 테스트 해보고 문제가 없을 시 전체 소스에다가 삽입하는 방식으로 진행을 합니다. 이런식으로 진행하시면 사실 전체소스가 있는 곳에서는 에러가 발생할 가능성은 거의 없습니다. 이미 사전에 테스트가 완료된 상태에서 코딩한 명령문들을 삽입하기 때문에 에러가 생길일이 없겠죠. 단, 원하는 결과가 안나올 수 있습니다. 그 경우는 대개 명령문과 명령문 사이의 연결 값들이 제대로 넘겨주는지 코딩을 삽입할 때마다 체크해 주셔야 합니다. 그부분을 빼먹으면 나중에 전체 소스를 완성해도 원치 않는 결과가 나오면 그 원인을 찾기 힘들 수 있습니다. 하지만 일일히 가상 데이터로 테스트 하고 삽입하기 때문에 문제가 발생하더라도 찾는데 그리 오래 걸리지 않습니다.

토요일 post를 쓰다가 예제로 보여드리기에 기존 post한 소스를 기반으로 두가지 상황을 만들어 새로운 결과를 얻게 되었네요. 조금만 관점을 바꾸니깐 특정 날짜에서 특정기간의 결과를 얻을 수 있게 되었습니다. 또 조금만 관점을 바꾸니깐 보팅한 사람들에 대한 보팅 횟수 결과를 얻을 수 있게 되었습니다. 똑같은 함수를 사용하더라도 이렇게 관점에 따라서 결과가 다양하게 나오게 됩니다.

좀 잘 정리하고 post해야 하는데 진짜 일요일이라 제대로 글을 못섰네요. 좀 쉽게 의도를 전달하자 했는데 어렵게 됐네요.

  • 표현하고자 하는 것이 생각나면 "관련표현단어+자바스크립트" 키워드로 검색한다.
  • 찾아낸 함수는 가상데이터로 테스트 하고 자신의 것으로 만든다.
  • 원하는 표현을 가상데이터로 테스트 한뒤에 원하는 결과가 나오면 전체소스에 삽입한다.

이 세가지만 지키시면 초보분들도 왠만한 코딩을 하실 수 있습니다. 절대 한번에 코딩해서도 안되고 함수를 사용하더라도 다이렉트로 전체소스가 코딩되는 곳에서 바로 삽입시켜서 실행시키지 마시고 먼저 새로운 코딩창에서 테스트를 거치고 나서 자신의 것이 되었을 때 전체소스창에다가 삽입하시기 바랍니다.

Sort:  

고팍스야, 이 정성스런 포스팅에 풀봇 드려라~

^^
관심이 너무 많이오면 부담스러워져요.
어제 평소보다 많이 찾아와서 post에 찾아오신분들 어떤 글로 활동하시는지 찾아가야하는데 다 못 찾아뵙고 있네요.

후아 회사라 자세히 보진 못했는데 집에 얼른 가서 테스트 하고 싶네요!!

예를 든 것 뿐이라.
실험하실려면 참조 Post를 먼저 보시고 와야 이해가 더 빠를 꺼에요

You received 3.37 % upvote as a reward From round 2 on 2018.05.21. Congrats!

자바스크맆트 관련 함수가 엄청 많다고 들었는데... 점점 복잡해 지네요.

사용하는 함수가 많죠. 저도 다 몰라요. 자바스크립트 30분도 공부 안해봤어요.
단지. C언어 기본만 잡혀 있어요.
그런데, 사용할 수 있는 이유는요. 전부 다 알고 있으면 좋기는 하는데 필요할 때 찾아서 그 함수를 사용하시면 돼요.
문자열을 쪼개고 싶다면 "문자열 나누기 자바스크립트" 이런식으로 구글 검색키워드에서 레퍼런스나 예제같은 것을 보고 아! 이런식으로 문자열을 쪼갤 수 있구나 하고 자신의 것으로 만드시면 돼요.
Steem.js API은 블록체인이 스티미언 활동 내역 DB를 가지고 있잖아요. 장부(기록) 정보니깐 문자열과 시간 함수만 제대로 정리해놓으면 왠만한 표현은 다 가능해져요.

나머지 부수적으로 html로 출력시키기 위해서. html, css, js 등의 문법들이 좀 필요하고요.

어렵게 생각하시지 마시고 다 만들어진 소스를 보지 마시고 Steem.js API 함수 하나를 선택해서 그 함수에서 가져오는 블록체인 정보를 보고 이 정보로 뭘할 까 하고 기초적인 전체 출력과 부분 출력에서 부터 시작해서 표현하고 싶은 걸 하나씩 접근해나가시면 돼요.

음....ㅠㅠ 오늘따라 유난히 더 어렵게 느껴지네요..ㅋㅋ 친구 대꼬와야겠어요 ㅋㅋㅋ

좀 어렵게 글을 쓴거 같네요.
하나만 상황 정해서 쓸 것을 두개의 상황을 정해서 쓰다 보니깐 post가 좀 문제가 있네요.

멋진 포스팅 감사합니다 !! ㅎㅎ 남는 시간을 이용해서 이런 양질의 포스팅이라니 !! 정말 멋지세용 ~

변변찮은 글에 감사합니다.

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

방문해 주셔서 감사합니다.

Coin Marketplace

STEEM 0.16
TRX 0.15
JST 0.030
BTC 58476.88
ETH 2522.41
USDT 1.00
SBD 2.34