본문 바로가기

1.프로그래밍/JavaScript

[JavaScript] Javascript 세계 코로나 현황판(공공 데이터 API, XMLHttpRequest, Js Simple Pagination ,Google Chart)

728x90
반응형

[JavaScript] Javascript 세계 코로나 현황판(공공 데이터 API, XMLHttpRequest, Js Simple Pagination ,Google Chart)

제목이 좀 길다.
공부하며 사용했던것들을 정리함과 동시에 나중에 필요할 경우 다시 찾아보기 위해 길게 작성하였다.

공공 데이터 API 신청하기

공공데이터포털


위의 사이트에 들어가면 각종 공공데이터 API를 사용할 수 있다.

간단한 회원가입을 진행 후, 필요한 데이터 API를 검색 후 신청을 하면 된다.


image


위의 사진과 같이 필요한 데이터 API에 들어가 활용신청을 한다.


image


위와 같이 간단하게 활용 목적등을 작성하게 되면 신청은 간단하게 완료된다.

신청 후 약 2시간 뒤에 Service Key가 발급이 된다.


해당 서비스 키는 마이페이지에서 확인이 가능하다.

공공 데이터 API 사용하기

사용할 데이터 API 사이트에 보면 요청변수(Request Parmeter) 와 출력 결과(Response Element)를 보여주는
API 명세가 나와있다.


심지어 친절하게 예시코드또한 존재한다.


API 명세
image


Sample Code
image

세계 코로나 API 사용



document.addEventListener("DOMContentLoaded", function(){
    callApi();
})

function callApi(){
    const serviceKey = "서비스 키"


    // 오늘 날짜를 넣어 데이터를 불러오려 했지만
    // 오늘 날짜는 데이터 존재하지 않음
    /*
    let date = new Date();
    let thisYear = date.getFullYear();

    var firstDayOfMonth = new Date( date.getFullYear(), date.getMonth() , 1 );
    var lastMonth = new Date ( firstDayOfMonth.setDate( firstDayOfMonth.getDate() - 1 ) ).getMonth() + 1;
    let lastDay = new Date(date.getFullYear(), lastMonth, 0).getDate();

    if(lastMonth < 10){
        lastMonth = "0" + lastMonth;
    }

    let dateFormat = "" + thisYear + lastMonth + lastDay;
    */

    var xhr = new XMLHttpRequest();
    var url = 'http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19NatInfStateJson'; /*URL*/
    var queryParams = '?' + encodeURIComponent('serviceKey') + '='+ serviceKey; /*Service Key*/
    queryParams += '&' + encodeURIComponent('pageNo') + '=' + encodeURIComponent('1'); /**/
    queryParams += '&' + encodeURIComponent('numOfRows') + '=' + encodeURIComponent('10'); /**/
    queryParams += '&' + encodeURIComponent('startCreateDt') + '=' + encodeURIComponent('20220929'); /**/
    queryParams += '&' + encodeURIComponent('endCreateDt') + '=' + encodeURIComponent('20220929'); /**/
    xhr.open('GET', url + queryParams);
    xhr.onreadystatechange = function () {
        if (this.readyState == 4) {
            console.log("Staus: " + this.status);

            let responseData = this.responseXML;
            let items = responseData.getElementsByTagName("items")[0];

            let dataArray = [];

            for(let i = 0; i < items.childNodes.length; i++){
                let areaNm = items.childNodes[i].getElementsByTagName("areaNm")[0].innerHTML;
                let nationNm = items.childNodes[i].getElementsByTagName("nationNm")[0].innerHTML;
                let natDefCnt = items.childNodes[i].getElementsByTagName("natDefCnt")[0].innerHTML 
                let natDeathCnt = items.childNodes[i].getElementsByTagName("natDeathCnt")[0].innerHTML
                let natDeathRate = items.childNodes[i].getElementsByTagName("natDeathRate")[0].innerHTML

                let dataObject = {
                    areaNm,
                    nationNm,
                    natDefCnt,
                    natDeathCnt,
                    natDeathRate
                }

                dataArray.push(dataObject);
            }        

            dataArray.sort(function(a, b){
                return b.natDefCnt - a.natDefCnt;
            })


            pagination(dataArray);
            google.charts.setOnLoadCallback(drawRegionsMap(dataArray));

        }
    };

    xhr.send('');
}

여기서 API 통신은 예시 코드에 나와있는 XMLHttpReqeust를 그대로 사용하였다.


공식문서


XMLHttpRequest는 Javascript에서 서버와 상호작용할 떄 사용하는 객체로서, 비동기 통신을 사용하기 위해 사용한다.


Jquery를 사용하게 되면 $.ajax()가 존재하고, Javascript에서는 더 발전된 Fetch API가 존재한다.


Fetch API의 사용법 또한 그렇게 복잡하진 않다. 하지만 정확한 개념을 알고 사용하고 싶었고,
그러러면 Javascript의 CallBackPromise에 대해 정확히 이해하고 사용해야될 것 같다는 생각을 갖고 일단 XMLHttpRequest를 이용하여 구현하기로 했다.


이제 간단히 사용한 XMLHttpRequest의 메서드들에 알아보겠다.

XMLHttpRequest.onreadystatechange : xhr의 상태가 변경될 때의 이벤트
XMLHttpRequest.readyState : xhr 요청의 상태를 나타내는 숫자를 반환한다.
XMLHttpRequest.responseXML : 요청에 대한 응답을 XML으로 반환해준다.
XMLHttpRequest.send() : API에 대한 요청을 보낸다. 비동기 통신의 경우 send()는 요청을 전송하는 즉시 반환받는다.


XMLHttpRequest StateCode

Value State Description
0 UNSET 객체가 생성되었지만, open() 호출되진 않음
1 OPENED open() 호출이 된 상태
2 HEADERS_RECEIVED send() 호출이 되었고, 헤더 및 상태를 사용 가능
3 LOADING responseText 부분 데이터를 보유
4 DOEN 작업이 완료됨

위와 같은 메서드들이 사용되었고,
필자가 사용한 API는 XML형식이기 때문에 getElementByTagName을 사용하여 각 XML 태그에 맞는 필요한 데이터를 갖고와 배열을 만들어 보내주는 형식으로 만들어, 이를 통해 Pagination과 Google Chart(GeoChart)를 만들었다.

Javascript Simple Pagination

const perPageData = 8;  // 페이지당 데이터
let currentPage = 1;   // 현재 페이지 (시작 1)
let amountPage;     // 총 필요한 페이지 수
let copyArray = [];     // dataArray 복사 시킬 배열

function calcAmountPage(amountData){
    return Math.ceil(amountData / perPageData);
}

const prevBtn = document.querySelector(".prev");
const nextBtn = document.querySelector(".next");

prevBtn.addEventListener("click", function(){
    console.log("perv click");
    if(currentPage > 1){
        currentPage--;
        console.log("currentPage: " + currentPage);
        pagination(copyArray);
    }
});

nextBtn.addEventListener("click", function(){
    console.log("next click");
    if(currentPage < amountPage){
        currentPage++;
        console.log("currentPage: " + currentPage);
        pagination(copyArray);
    }
});

function pagination(dataArray){
    console.log("pagination dataArray: ");
    console.log(dataArray);

    amountPage = calcAmountPage(dataArray.length);
    copyArray = [...dataArray];

    let selectPage = document.querySelector(".selectPage");
    let maxPage = document.querySelector(".amountPage");
    const table = document.querySelector(".main_table tbody");
    table.innerHTML = "";

    if(currentPage < 1){
        currentPage = 1;
    }

    if(currentPage > amountPage){
        currentPage = amountPage;
    }

    maxPage.innerHTML = amountPage;
    table.innerHTML = "";

    // 전체 데이터에서 어디부터 시작할지 && 그리고 해당 페이지의 데이터 끝까지
    for (var i = (currentPage-1) * perPageData; i < (currentPage * perPageData) && i < dataArray.length; i++){
        let sendData = 
            `
            <tr>
                <td><a onclick="openSpecificArea('${dataArray[i].nationNm}')" id="${dataArray[i].nationNm}" class="specificArea">${dataArray[i].nationNm}</a></td>
                <td>${parseInt(dataArray[i].natDefCnt).toLocaleString()}</td>
                <td class="deathRate">
                    <p>${parseFloat(dataArray[i].natDeathRate).toFixed(1)}%</p>
                    <p> (${parseInt(dataArray[i].natDeathCnt).toLocaleString()}) </p>    
                </td>
            </tr>
            `

        table.innerHTML += sendData;
    }

    selectPage.innerHTML = currentPage;

    if(currentPage == 1){
        prevBtn.style.visibility = "hidden";
    } else {
        prevBtn.style.visibility = "visible";
    }

    if(currentPage == amountPage){
        nextBtn.style.visibility = "hidden";
    } else {
        nextBtn.style.visibility = "visible";
    }
}

위의 코드는 매우 간단한 pagination을 만들기 위해 작성한 코드이다.
왼쪽과 오른쪽의 화살표를 이용한 페이징만 가능하도록 구현되었다.


매우 간단한 코드이므로, 조금만 보면 이해가 가능하고 바로 사용할 수 있을 것이다.

Google Chart

차트 만들기를 도와주는 라이브러리는 다양하게 존재하는 것으로 알고있다.
그 중 개인적으로 쉽게 바로 적용이 가능한 Google Chart를 이용해 보았다.


https://developers.google.com/chart


구글차트에는 정말 다양한 종류의 차트들이 존재한다.
그 중 세계에 걸맞게 세계지도를 차트화 시켜주는 GeoChart를 사용해 보았다.


https://developers.google.com/chart/interactive/docs/gallery/geochart


위의 docs에 가게 되면 샘플 코드부터 각종 custum에 대한 option 설정에 대한 설명이 자세히 나와있다.


하지만, GeoChart는 Google Maps Platform이라는 곳에서 API 키를 인증받고 발급받아야 정상적으로 사용이 가능하다.

아마 다른 차트는 별도의 인증 키 없이 사용 가능할 것이다.


https://developers.google.com/maps/documentation/javascript/get-api-key


image


위의 링크를 들어가서 아래 이미지의 버튼으로 이동하여 간단한 인증을 하면 간단히 키를 발급받아 사용 할 수 있게 된다.
단, 주의할 점으로는 일정 사용량(?)이 넘어갈 경우 요금이 부과될 수 있다는 점이다.

하지만, 로컬환경에서 혼자 공부하는 용도로는 신경쓰지 않아도 될것이다.


google.charts.load('current', {
    'packages': ['geochart'],
    'mapsApiKey': 'Your key'
});

function drawRegionsMap(dataArray) {

    let chartDataArray = [];
    chartDataArray.push(['Country', 'CODIV-19']);

    for(let i = 0; i < dataArray.length; i++){
        chartDataArray.push([dataArray[i].nationNm, parseInt(dataArray[i].natDefCnt)]);
    }

    var data = google.visualization.arrayToDataTable(chartDataArray);

    var options = {};

    var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));

    chart.draw(data, options);

}

기존의 Google Chart에서 동적으로 데이터를 넣을 경우,
google.visualization.DataTable()이라는 객체를 생성하여
addColumn()addRow() 메서드들을 이용하여 데이터를 넣어줘야 했다.


하지만, GeoChart의 경우 google.visualization.arrayToDataTble()을 사용하고,
배열의 첫 요소에 대륙(?)과 hover시 나타낼 메시지(?)을 넣어주면 되고,

그 이후에 각 데이터를 한번에 넣어주게 되면 끝이난다.

완성본

image
image


이상으로 글을 마치도록 하겠다.

728x90
반응형

'1.프로그래밍 > JavaScript' 카테고리의 다른 글

[Javascript] FormData 란?(Ajax 이미지 첨부)  (0) 2022.05.27