[D3.js] 공공데이터를 table로 출력

in #dclick6 years ago (edited)

[D3.js] 공공데이터를 table로 출력



오늘은 제대로 된 데이터를 읽어서 table로 출력해보고 싶어서 한번 시도해 보았습니다. d3.js에서 제공되는 d3.csv()함수를 이용하여 적당한 공공데이터를 하나 찾아서 csv 파일로 다운로드 한 다음 그 데이터를 table로 출력해보도록 하겠습니다.

1. 공공데이터 가져오기



승하차인원 통계 자료를 csv 파일로 제공하네요. 수정일은 2018-06-08 이네요. 체크하시고 선택 다운로드 누르시면 해당 데이터 정보를 가져오게 됩니다.

미리보기 창이 있는데 어떤 데이터가 있는지 확인을 할 수 있게 되어 있네요. 3개의 정보가 들어 있네요.

2. 공공데이터 읽기 주의


우선 공공데이터는 csv 파일이지만 d3.csv()함수로 읽기 위해서는 encoding을 맞춰야 합니다. 그냥 읽게 되면 데이터가 숫자를 제외만 모든 문자가 깨져서 나옵니다.

그러면 엑셀로 열어 데이터가 깨진 걸 받아왔는지 확인해 볼까요.

정상적으로 다운로드를 했습니다. 문제는 encoding 때문에 깨져서 나옵니다.

메모장으로 열어볼까요.

메모장에서도 정상적인 데이터를 확인 할 수 있습니다. 다른이름으로 저장을 누르고 encoding을 보시면 ANSI형태로 되어 있습니다. 정상적으로 읽기 위해서는 이 부분이 UTF-8로 변경해서 저장해야 합니다.

그렇게 하면 다음과 같이 정상적으로 데이터가 안깨지고 정상적으로 출력 되네요.

참고로, 단순 무식하게 위 과정으로 수정했는데 d3.csv()에서 encoding을 세팅하는 방법이 있다고 하긴 하는데 잘 안되더군요. 그래서 그냥 읽어 올 파일형식을 UFT-8 형태로 변경한 후 편하게 읽도록 했네요.

하지만 이 방법도 다소 문제가 있습니다. 이렇게 변경해 놓으면 나중에 엑셀로 읽게 되면 데이터들이 다 깨져서 나오게 됩니다. 그럼 다시 ANSI형태로 변경해야하는 번거로움이 있겠죠.

2. 정렬 시 또 다른 문제


이전 post에서 문자열과 숫자 정렬을 구분하여 정렬을 할 수 있게 되었습니다. 그런데 또다른 문제가 발생하게 됩니다. 바로 콤마가 붙은 숫자값을 문자열로 인식하기 때문에 정상적으로 정렬이 이루어지지 않습니다.

위그림에서 보는 것처럼 순위랑 일평균을 숫자로 변경해야겠죠. 그래서 다음과 같은 방법으로 아예 콤마를 제거하고 숫자형으로 만들었네요.

function type(d){

      d.순위=+d.순위; //이것도 숫자로 인식
      d.일평균=parseInt(d.일평균.replace(/,/g, ""));
      return d;
}
d3.csv("data1.csv",type).then(function(data){
   ... 생략 ...
}

d.일평균 데이터에서 콤마를 제거하고 그 값을 정수형으로 변경만 하면 됩니다. 그럼 콤마가 없이 숫자만 나오게 됩니다.

3. 완성



getbootstrap.css로 약간 깔끔하게 표현을 하겠습니다.

link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

그 다음으로,

      var table = d3.select('body').append('table')
            .attr("class","table table-striped");
      var thead = table.append('thead')
            .attr("class","thead-dark");

사전학습의 소스에다가 위에서 수정했던 코딩을 합쳐서 완성해 보겠습니다.

[전체소스]

<body>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script type="text/javascript" src="http://d3js.org/d3.v5.min.js"></script>

<script type="text/javascript">

function type(d){
      d.순위=+d.순위;
      d.일평균=parseInt(d.일평균.replace(/,/g, ""));
      return d;
}

d3.csv("data1.csv",type).then(function(data){
      var sortstate = true;          
      var title = d3.keys(data[0]); 

      var table = d3.select('body').append('table')
            .attr("class","table table-striped");
      var thead = table.append('thead')
            .attr("class","thead-dark");
      var tbody = table.append('tbody');

      var header = thead.append('tr')
                       .selectAll('th')
                       .data(title).enter()
                       .append('th')
                       .text(function (d) {return d;})
                       .on('click', function (d) {
                         sortstate = !sortstate;
                         rows.sort(function(a,b){
                           if(isNaN(a[d])){
                             if (sortstate) return b[d] > a[d]; 
                             else return a[d] > b[d];
                           }else{
                             if (sortstate) return b[d] - a[d]; 
                             else return a[d] - b[d];
                           }
                         });
                       });
     var rows = tbody.selectAll('tr').data(data)
                     .enter()
                     .append('tr');

     var cells =  rows.selectAll('td')
                      .data(function (d) {
                               return title.map(function (title) {
                                     return { 'title': title, 'value': d[title]};
                               });
                      })
                      .enter()
                      .append('td')
                      .text(function (d) { return d.value;});
});
</script>
</body>

[결과]

마무리


post를 하나 쓸 때마다 문제가 하나씩 생기네요. 아무튼 이렇게 해서 공공데이터를 하나 가져와서 정상적으로 table로 출력하고 정렬도 문자열 or 숫자 정렬로 정상적으로 동작하네요.

오늘 다룬 내용은 데이터를 그냥 table로 출력했지만 이 데이터를 다른 형태로 시각화해서 출력하면 좀 더 멋질거에요. 그리고 공공데이터 포털에서 실시간 데이터를 제공해주기도 하는데 API 키를 제공 받아서 실시간 데이터를 가지고 실시간 시각화를 할 수 있습니다. 문제는 해당 기관에 신청해야 하기 때문에 무지 번거롭습니다. 그래서 이 부분은 post로 쓰면 좋은데 아쉽지만 포기하네요


Sponsored ( Powered by dclick )

dclick-imagead

Sort:  

공공데이터를 제공 하기도 하는군요!
세상엔 모르는게 참 많아요....
스팀 고래의 꿈.jpg

공공데이터 보면 재밌는 데이터를 좀종 있는데 대부분은 일정 시간이 지난 죽은 데이터들 뿐이라 좀 아쉽긴 해요.

짱짱맨 호출에 응답하여 보팅하였습니다.

짱짱맨 방문을 환영합니다.

data를 가져와 이렇게 잘 활용하는 분도 계시네요.

실시간 데이터를 가져와서 놀아야 하는데 그건 절차가 귀찮아서 해보진 못했네요.
보면 어플을 제작하는 분들이 은근히 많더군요.

이런 방법도 있군요~. 소개해 주셔서 감사합니다

Posted using Partiko iOS

공부하다가 삽질 좀 했네요.

Coin Marketplace

STEEM 0.20
TRX 0.13
JST 0.030
BTC 62946.22
ETH 3453.83
USDT 1.00
SBD 2.50