공공데이터 이용하기 17 (코드 수정 줄이기 및 슬라이더 구현)

KHW·2021년 5월 19일
0

Danfo.js

목록 보기
21/23

Pi_Chart_Bar_Chart.js

기존에는 특정 날짜를 input 태그를 이용해 날짜를 설정 한 후에
원 차트 추가 버튼 or 막대 차트 추가 버튼을 통해 해당 날짜의 시도별 코로나 확진자 수 결과를 조회하였다.


문제점 제기

매번 날짜를 일일히 입력해야하고 버튼을 눌러야하는 번거로움 이라는 내용으로 피드백이 들어와서 이를 해결하고자 슬라이더 기능을 구현하였다.


코드 변경

  1. Pi_Chart_Bar_Chart.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/danfojs@0.1.2/dist/index.min.js"></script>
    <script src="https://code.jquery.com/jquery-1.9.1.js"></script>
    <script src="https://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
</head>
<body>
<h1>원하는 날짜의 코로나 지역별 증가수 확인 (현재 2020년 03월 04일 부터 04월 30일까지만 가능</h1>

<h2 id="div1" >
</h2>
<input id="range" type="range" style="width:50%">
<button type="submit" id="cancel_plot">원 차트 삭제 버튼</button>
<div id="plot_div"></div>
<br>

<h2 id="div2" >
</h2>
<input id="range2" type="range" style="width:50%">
<button type="submit" id="cancel_bar">막대 차트 삭제 버튼</button>
<div id="bar_div"></div>
<button class="but">download</button>
<script src="js/Pi_Chart_Bar_Chart.js" type="module">
</script>
</body>
</html>

  1. Pi_Chart_Bar_Chart.js
import {url} from './utils/Data.js'
import {end} from './utils/Set_Date.js'

let input = document.getElementById('input')
let Plot_Button = document.getElementById('plot');
let Bar_Button = document.getElementById('bar');
let Cancel_Plot_Button = document.getElementById('cancel_plot');
let Cancel_Bar_Button = document.getElementById('cancel_bar');

function downloadCSV(location, increase){
  let array = [];
  array.push(location);
  array.push(increase);

  let val = "";

  // jquery 사용하지 않는 경우
  for (let j = 0; j < location.length; j++) {
    val += array[0][j]+',';
  }
  val +=  "\r\n";
  for(let k=0;k<increase.length;k++){
    val += array[1][k]+',';
  }
  val +=  "\r\n";

  let downloadLink = document.createElement("a");
  let blob = new Blob(["\ufeff"+val], { type: "text/csv;charset=utf-8" });
  let url = URL.createObjectURL(blob);
  downloadLink.href = url;
  downloadLink.download = "data.csv";

  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
}



Cancel_Plot_Button.addEventListener('click',function(){
  if(document.getElementById('plot_div').childNodes[0]==undefined){
    alert('삭제할 내용이 없어');
    return 0;
  }

  let chart = confirm("원 차트를 지우겠습니까?");
  if (chart == false)
    alert('지우기 취소')
  else
    document.getElementById('plot_div').childNodes[0].remove();
})

Cancel_Bar_Button.addEventListener('click',function(){
  if(document.getElementById('bar_div').childNodes[0]==undefined){
    alert('삭제할 내용이 없어');
    return 0;
  }

  let chart = confirm("막대 차트를 지우겠습니까?");
  if(chart == false)
    alert('지우기 취소')
  else
    document.getElementById('bar_div').childNodes[0].remove();
})


document.querySelector('#range').setAttribute('min',1583247600);
document.querySelector('#range').setAttribute('max',new Date(end).getTime() / 1000);
document.querySelector('#range').setAttribute('step',86400);

document.querySelector('#range2').setAttribute('min',1583247600);
document.querySelector('#range2').setAttribute('max',new Date(end).getTime() / 1000);
document.querySelector('#range2').setAttribute('step',86400);

$(document).ready(function() {
  $('#range').change(function(){

    var val = $(this).val();
    let result =(Unix_timestamp(val));
    document.querySelector('#div1').innerHTML= result;
    dfd.read_csv(`${url}${result.replace(/-/gi,'').slice(2,8)}.csv`)
      .then(
        function(data) {
          const incDec_Length_Except_Sum = data.body__items__item__incDec.data.length-1;
          const gubun_Length_Except_Sum = data.body__items__item__gubun.data.length-1;

          let df = new dfd.DataFrame({
            Price: data.body__items__item__incDec.data.slice(0,incDec_Length_Except_Sum),   //표의 맨 아래 합계를 제거한 내용들
            Location : data.body__items__item__gubun.data.slice(0,gubun_Length_Except_Sum),
            Type: data.body__items__item__gubun.data.slice(0,gubun_Length_Except_Sum)
          })

          document.querySelector('.but').addEventListener('click',()=>downloadCSV(df.Location.data,df.Price.data));
          df.plot("plot_div").pie({ values: "Price", labels: "Type" })

        }
      )
      .catch(() => {

        alert('저장된 데이터 이외의 날짜를 클릭했습니다.');
      })

  });

});


$(document).ready(function() {
  $('#range2').change(function() {

    var val = $(this).val();
    let result =(Unix_timestamp(val));
    document.querySelector('#div2').innerHTML= result;
    dfd.read_csv(`https://khw970421.github.io/covid/Modify_Danfo/Data/Date/${result.replace(/-/gi, '').slice(2, 8)}.csv`)
      .then(
        function (data) {
          const incDec_Length_Except_Sum = data.body__items__item__incDec.data.length - 1;
          const gubun_Length_Except_Sum = data.body__items__item__gubun.data.length - 1;

          let df = new dfd.DataFrame(
            {
              '확진자수': data.body__items__item__incDec.data.slice(0, incDec_Length_Except_Sum),   //표의 맨 아래 합계를 제거한 내용들
              Type  : data.body__items__item__gubun.data.slice(0, gubun_Length_Except_Sum)
            },
            {index: data.body__items__item__gubun.data.slice(0, gubun_Length_Except_Sum)}
          )

          document.querySelector('.but').addEventListener('click', () => downloadCSV(df.Location.data, df.Price.data));
          df.plot("bar_div").bar()
        }
      )
      .catch(() => {
        alert('저장된 데이터 이외의 날짜를 클릭했습니다.');
      })

  })})


function Unix_timestamp(t){
  var date = new Date(t*1000);
  var year = date.getFullYear();
  var month = "0" + (date.getMonth()+1);
  var day = "0" + date.getDate();
  return year + "-" + month.substr(-2) + "-"+ day.substr(-2)
}

  1. Data.js

const url = 'https://khw970421.github.io/covid/Modify_Danfo/Data/Date/'

export {url};

기본적인 url을 통일하여 가독성을 부여했다.


  1. Set_Data.js
let start = '2020-03-03'
let end = '2020-07-31'

function Set_Date(){
  let sdt = new Date(start); // 2020년 03월 04일 부터 시작
  let edt = new Date(end);
  let dateDiff = Math.ceil((edt.getTime()-sdt.getTime())/(1000*3600*24));

  let Year,Month,Day;                 // 각 날짜별 날짜 생성
  const date_array = [];              // 해당 필요부분 넣을 배열 생성
  for(let i=0;i<dateDiff;i++)              // 2020년 3월 4일부터 마지막 데이터 csv까지의 날짜의 차이에서 +1 한 값이 150 (ex 현재는 7월 31일까지)
  {
    sdt.setDate(sdt.getDate()+1)        // 3월 4일 계산 후 하루씩 증가
    Year = sdt.getFullYear().toString().slice(2,4);       // 2020년이 아닌 뒤의 두자리 수만 필요하므로 slice 사용
    Month = (sdt.getMonth()+1).toString().length==1 ? '0'+ (sdt.getMonth()+1).toString() :(sdt.getMonth()+1).toString() ; // 한자리 수 인경우 앞에 0을 붙인다.
    Day = sdt.getDate().toString().length==1? '0'+sdt.getDate().toString() : sdt.getDate().toString();
    date_array.push(Year+Month+Day);    //합친 내용을 배열로 만들어 준다.
  }
  return date_array;     //해당 배열을 반환한다.
}

export {Set_Date,end}

필요에 따라 데이터가 추가되면 해당 부분으니 end 부분만 날짜를 수정하면 해당 html말고도 다른 html도 전부 영향을 주어 간단하게 데이터 수정을 할 수 있다.


결과

시작 창


원 차트 슬라이더를 움직였을때


막대 차트 슬라이더를 움직였을때


원 차트 삭제 버튼을 클릭 한 후


위와같이 정상적으로 동작하며
1. setDate.js 로 분리하여 좀 더 수정에 용이해지고
2. 슬라이더를 이용하여 사용자에게 있어서 불편함을 줄이게 되었다. (해당 슬라이더 드래그 후 관련 날짜가 슬라이더 위에 있어 어떤 날짜에 대한 것 인지도 도움이 된다.)

해당 url

profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글