본문 바로가기

미분류/SIDE

D3.js 를 사용하여 그래프 그리기

D3.js를 사용하여 그래프 그리기

세상엔 알아야 할 것들이 너무나 많다. 그 중 하나가 전공지식 아닐까? 여태 배웠는데 아침에 눈을 뜨면 또 배울 것들이 태산이다. 요즘 하는 데이터 크롤링에게 필연적으로 따라오는 요소가 시각화이다. 파이썬에서 갖가지 기능들을 제공하고 있지만, 스터디 분야가 웹이였기 때문에 D3.js로 도전해봤다.

참고로 엄청나게 많은 추측들을 담고 있는 글이다.

1. 데이터 수집

만만한게 기상데이터다. 자료도 많고 표현할 수 있는 방법도 많다. 서울열린데이터에서 제공하고 있는 서울특별시 관측소별 기상관측 정보(시간단위) 데이터를 사용하였다. 고맙게도 API를 제공하고 있어 쉽게 가져올 수 있다. 나는 구로구의 데이터를 json으로 한 시간마다 가져와 rect 형식으로 추가해주는 그래프를 구상하였다.

하지만 D3.js를 알기전에 알아야 할 지식들이 있다. 바로 Javascript와 CSS이다. 놀랍게도 나는 웹에 대해 하나도 모른다. 기껏 해봤자 학부 때 HTML 조금 공부한게 다인데 이마저도 잊어버린지 오래고 <div></div> 정도밖에 모른다. 그래서 생활코딩 자바스크립트에서 하루동안 속성으로 변수나 명령어 정도만 익힌 뒤에 시작했다.

API로 수집되는 Json 형식은 아래와 같다.

{
    "RealtimeWeatherStation": {
        "list_total_count": 1,
        "RESULT": {
            "CODE": "INFO-000",
            "MESSAGE": "정상 처리되었습니다"
        },
        "row": [{
            "SAWS_OBS_TM": "2019022708",
            "STN_NM": "구로",
            "STN_ID": "1156",
            "SAWS_TA_AVG": 7.3,
            "SAWS_HD": 42.7,
            "CODE": "13",
            "NAME": "서",
            "SAWS_WS_AVG": 0.9,
            "SAWS_RN_SUM": 0.0,
            "SAWS_SOLAR": 0.0,
            "SAWS_SHINE": 0.0
        }]
    }
}

한 시간에 하나씩 추가되고 이전 값은 사라지므로 제때 제때 가져오지 않으면 영원히 알 수 없다. 물론 다른 API를 참고하면 되겠지만 일단은 그렇다. 정부 API의 json 형식은 전부 다 저런식으로 되어있는데 API이름:{토탈 row 수,결과, row[]} 필요한 값은 row에 있는 값이다. 눈치봐서 적당히 편집해주면 된다.

2. 데이터 저장

여기서부터 고민이 시작된다. D3.js에서도 json 형식의 처리를 도와주고 있고 javascript에서도 도와주고 있으며 jquery에서도 가능하다. 또한 한 시간 마다 한 번씩 데이터를 추가 해주는 모양이기 때문에 가지고 있는 데이터를 잠시나마 저장해줄 필요도 있다. 그래서 D3에서 json을 배열[오브젝트,오브젝트 -] 형식으로 저장해준 다음에 그래프를 그릴 때 배열을 불러와서 그리게 하였다.
그리고 24시간 값만 보여주기 원했기 때문에 길이를 측정하여 24개가 넘으면 첫번째 원소를 삭제해주고 push 해주었다.

function insertData() {
    d3.json(url).then(function(data) {
        data = data.RealtimeWeatherStation.row;
        temp = guroWeatherData.slice(-1)[0];
        if(guroWeatherData.length > 24){
            guroWeatherData.shift();
        }
        if(temp == undefined || temp.SAWS_OBS_TM != data[0].SAWS_OBS_TM){
            var guroWeather = {
                SAWS_OBS_TM : data[0].SAWS_OBS_TM,
                SAWS_TA_AVG : data[0].SAWS_TA_AVG,
                SAWS_HD : data[0].SAWS_HD
            };
            guroWeatherData.push(guroWeather);
        }
    });
}//데이터 10분에 한 번씩 조회하여 값이 변했을 때에 배열에 집어넣음 24개까지 저장, 24개가 넘어가면 이전 데이터 폐기

데이터는 30분에 한 번씩 조회하여 변화가 생겼을 때 push하도록 하였다. 사용한 기능은 setInterval이다.

3. 그래프 그려보기

이제 데이터도 준비가 되었다.

4. 수정점

  • 24시간 x축을 먼저 구현해놓고 모양의 변화가 없는 그래프. axis 축을 잘 조정하면 될 것 같은데 쉽지 않다.
  • 현재 그래프의 추가 svg를 삭제 -> svg의 생성으로 하고있다. 이렇게 비효율적일수가! 이 를 보면 svg의 update 방식에 대해 설명하고 있다. 참고하여 주말 내에 변경할 예정이다.
  • 그래프가 추가 될 때 마다 mouseover x값이 밀린다. 수정해야한다.
  • 현재는 습도 그래프만 포함하고 있으므로 온도 그래프도 꺾은선으로 넣어야 한다. 그리고 이렇게 보일 수 있도록 구현해본다.
  • setInterval이 아닌 서버 시간을 이용해서 10분 단위로 데이터를 받아올 수 있게 해본다.
  • 그래프를 예쁘게 만들어본다. 목표는 이런 모양이다.
  • document를 많이 참고하자.