공공데이터 이용하기 13 (Compare_City 수정하기)

KHW·2021년 3월 14일
1

Danfo.js

목록 보기
17/23
post-custom-banner

기존에 있던 내용(Compare_City.html, Compare_City.js)

기존에는 두 데이터를 서로 비교하는 방식으로 작동을 시켜왔다.


새로운 의견

이를 두 도시가 아닌 다수도 가능한 것이냐에 대한 의견이 제시되고 이를 적용시키기 위해 Danfo.js 공식 홈페이지를 검색했다.

let a = {
    		'pig': [20, 18, 489, 675, 1776], 
  		'horse': [1000, 25, 281, 600, 1900],
  		'ppp':[10,2,2,3,4]
    	}
        df = new dfd.DataFrame(a, {index: [1990, 1997, 2003, 2009, 2014]})
        df.plot("plot_div").line()

이런식으로 객체에 프로퍼티와 값을 넣고 이를 출력하는것도 정상적으로 작동했다. -> 즉, 제대로된 키와 값을 가진 프로퍼티만 존재한다면 결과를 여러개 한번에 보일 수 있다.


코드 수정하기 (기존코드)

기존코드

import {url} from './Data.js'
let input1 = document.getElementById('city1')
let input2 = document.getElementById('city2')
let button = document.getElementById('but');

button.addEventListener('click',getServerData);

function getServerData() {

    async function load() {
      try {
        const get_date = [];
        const get1 = [], get2 = [];
        let city_index1, city_index2;
        let city_name1 = input1.options[input1.selectedIndex].text;
        let city_name2 = input2.options[input2.selectedIndex].text;

        const datas = await Promise.all(setDate().map(date => {
            return dfd.read_csv(`${url}${date}.csv`)
          }
        ));         //모든 데이터 값 읽어오기

        datas[0].body__items__item__gubun.data.forEach((data) => {
          if (data == city_name1)
            city_index1 = datas[0].body__items__item__gubun.data.indexOf(data);
          if (data == city_name2)
            city_index2 = datas[0].body__items__item__gubun.data.indexOf(data);
        });         //해당 지역을 가진 index 찾기

        datas.forEach(data => {
          get1.push(data.body__items__item__incDec.data[city_index1]);
          get2.push(data.body__items__item__incDec.data[city_index2]);
          get_date.push(data.body__items__item__stdDay.data[0]);
        })      //해당 지역을 가진 index를 통해 날짜별 증가량 배열에 저장

        let df_sum1 = new dfd.DataFrame({city_name1: get1, city_name2: get2}, {index: get_date});  //df_sum은 Series 형태이므로 DataFrame 형태로 변환
        df_sum1.plot('plot').line();        // 각각의 지역의 증가량 출력
      }
      catch(err){
        alert('데이터가 존재하지 않거나 잘못되었습니다.');
      }
    }

  load();
}

function setDate(){
  let input = document.getElementById('input')
  let days = document.getElementById('days');
  let returnDay = checkDuring(days.options[days.selectedIndex].text);
  let tDate = new Date(input.value); // 2020년 03월 04일 부터 시작
  let Year,Month,Day;                 // 각 날짜별 날짜 생성
  const date_array = [];              // 해당 필요부분 넣을 배열 생성

  for(let i=0;i<returnDay;i++)
  {
    tDate.setDate(tDate.getDate()+1)        // 3월 4일 계산 후 하루씩 증가
    let stringMonth = (tDate.getMonth()+1).toString();
    Year = tDate.getFullYear().toString().slice(2,4);       // 2020년이 아닌 뒤의 두자리 수만 필요하므로 slice 사용
    Month = stringMonth.length==1 ? '0' + stringMonth.toString() :stringMonth.toString() ; // 한자리 수 인경우 앞에 0을 붙인다.
    Day = tDate.getDate().toString().length==1? '0'+tDate.getDate().toString() : tDate.getDate().toString();
    date_array.push(Year+Month+Day);    //합친 내용을 배열로 만들어 준다.
  }

  return date_array;     //해당 배열을 반환한다.
}

function checkDuring(day){
  const $sample = {
    '1주일' : 7,
    '2주일' :  14,
    '3주일' : 21,
    '한달' : 30
  }
  return $sample[day];
}

일단 솔직히 정신이 없다. 이를 보기쉽게 수정해주고 새로 의도한 값들을 추가한다.


코드 수정하기(수정코드)

import {url} from './Data.js'
const cityTag = document.getElementById('city')
const addButton = document.getElementById('addButton');
const cityTitle = document.querySelector('.cityMember');
let button = document.getElementById('but');

let cityMember=[];

const addEventListener1 = ()=>{
  cityTitle.insertAdjacentHTML('beforeend',`<button type="button" class="m-1 btn btn-primary">${cityTag.value}</button>`);
  cityMember.push(cityTag.value)
}

addButton.addEventListener('click',addEventListener1);
button.addEventListener('click',getServerData);

function getServerData() {
  async function load() {
    try {
      let cityIndex =[],getDate=[];
      let totalContent={};

      const datas = await Promise.all(setDate().map(date => {
          return dfd.read_csv(`${url}${date}.csv`)
        }
      ));         //모든 데이터 값 읽어오기

      addCityIndex(datas,cityMember,cityIndex); //해당 지역을 가진 index 찾기
      checkIndex(datas,cityIndex,totalContent); //해당 지역을 가진 인덱스마다의 객체의 프로퍼티인 배열에 값을 넣는다
      addCityDate(datas,getDate);               //해당 지역을 가진 index를 통해 날짜 배열인 get_date저장

      const df_sum1 = new dfd.DataFrame(totalContent, {index: getDate});  // totalContent와 날짜인 get_date를 통해 df_sum 생성
      df_sum1.plot('plot').line();      //결과 출력

      // 해야할 부분 : 추가한 도시 버튼 클릭시 삭제기능 구현 , 전반적 코드 정리 필요

    }
    catch(err){
      alert('데이터가 존재하지 않거나 잘못되었습니다.');
    }
  }
  load();
}

const addCityIndex = (datas,cityMember,cityIndex)=>{
  datas[0].body__items__item__gubun.data.forEach((data) => {
    if (cityMember.indexOf(data) !== -1)
      cityIndex.push(datas[0].body__items__item__gubun.data.indexOf(data))
  });
}


const checkIndex = (datas,cityIndex,totalContent)=>{
  datas[0].body__items__item__gubun.data.forEach((data) => {
    cityIndex.map(index=>{
      if(data === datas[0].body__items__item__gubun.data[index])   //해당 지역을 가진 인덱스라면
        pushValue(totalContent,datas,data,index); //객체의 프로퍼티인 배열에 값을 추가
    })
  });
}

const pushValue = (totalContent,datas,data,index)=>{
  for(let i=0;i<datas.length;i++) {
    if(i===0)     //첫값은 배열 형태로 넣고
      totalContent[data] = [datas[i].body__items__item__incDec.data[index]];
    else          //배열형태이므로 나머지는 push메소드를 이용해 넣는다.
      totalContent[data].push(datas[i].body__items__item__incDec.data[index]);
  }
}

const addCityDate = (datas,getDate)=>{
  datas.forEach(data => {
    getDate.push(data.body__items__item__stdDay.data[0]);
  })
}

const setDate = ()=>{
  let input = document.getElementById('input')
  let days = document.getElementById('days');
  let returnDay = checkDuring(days.options[days.selectedIndex].text);
  let tDate = new Date(input.value); // 2020년 03월 04일 부터 시작
  let Year,Month,Day;                 // 각 날짜별 날짜 생성
  const date_array = [];              // 해당 필요부분 넣을 배열 생성

  for(let i=0;i<returnDay;i++)
  {
    tDate.setDate(tDate.getDate()+1)        // 3월 4일 계산 후 하루씩 증가
    let stringMonth = (tDate.getMonth()+1).toString();
    Year = tDate.getFullYear().toString().slice(2,4);       // 2020년이 아닌 뒤의 두자리 수만 필요하므로 slice 사용
    Month = stringMonth.length==1 ? '0' + stringMonth.toString() :stringMonth.toString() ; // 한자리 수 인경우 앞에 0을 붙인다.
    Day = tDate.getDate().toString().length==1? '0'+tDate.getDate().toString() : tDate.getDate().toString();
    date_array.push(Year+Month+Day);    //합친 내용을 배열로 만들어 준다.
  }
  return date_array;     //해당 배열을 반환한다.
}

const checkDuring = (day) => {
  const $sample = {
    '1주일' : 7,
    '2주일' :  14,
    '3주일' : 21,
    '한달' : 30
  }
  return $sample[day];
}

이전 코드에 비해 getServerData()부분이 확연히 줄어든 것을 알 수 있다. (함수 분리)


코드 분석

getServerData() : await Promise.all와 setDate 함수를 통해 모든 해당하는 날짜를 가진 datas를 가져온다. (datas들은 날짜의 범위에 따라 갯수가 달라지는 배열이다.)

● 일주일 기준

● 일주일 및 이주일 기준 (데이터 각각 7개 14개)


addCityIndex,checkIndex,addCityDate 함수 실행 후 데이터를 바탕으로 const df_sum1 = new dfd.DataFrame(totalContent, {index: getDate}); df_sum 생성하여 df_sum1.plot('plot').line();를 통해 출력시킨다.

addCityIndex : 말그대로 배열값에 추가한 도시들에 대한 index값을 추가한다.

checkIndex : 추가한 index값을 확인하여 해당 index(지역)에 대한 데이터를 가진 내용에서 일일 확진자를 totalContent 객체에 키를 도시로 하고 값에 배열 형태로 날짜마다를 추가한다.

addCityDate : 정해진 기간 기준으로 기간을 배열을 통해 저장한다.

이를 통해 얻어진 totalContentgetDate 데이터를 통해 마지막 출력을 진행할 DataFrame을 만들고 출력시킨다.


결과 확인하기

기존 코드 결과

수정 코드 결과

경기 대구 뿐만 아니라 제주까지도 추가할경우 적용이되서 같이 출력됨을 알 수 있다.

부족한 점

해당 추가한 경기 대구 제주와 같은 버튼들을 클릭시 제거할 수 있는 핸들러 구현이 필요하다. (선택을 다양하게 만들기 위해)

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

0개의 댓글