본문 바로가기
front-end/script

[C3.js] 실시간 라인 그래프 그리기 (Amazon CloudWatch Graph 벤치마킹)

by moonsiri 2022. 6. 15.
728x90
반응형

aws CloudWatch에 있는 그래프를 참고하여 실시간 라인 그래프를 그려보겠습니다.

https://d2908q01vomqb2.cloudfront.net/7719a1c782a1ba91c031a682a0a2f8658209adbf/2018/09/21/Screen-Shot-2018-09-21-at-2.10.29-PM.png

 

 

우선 html에 그래프를 그릴 영역을 잡아줍니다.

<div id="load-graph"></div>

 

위 영역에 그래프를 초기화해줍니다. 차트 라이브러리는 c3.js를 이용하겠습니다.

필요한 라이브러리는 c3.css, d3.js, c3.js입니다.

(c3.js를 선택한 이유는 예전에 사용 경험이 있는 d3.js를 기반으로 만들어진 라이브러리로 간단하게 그래프를 그릴 수 있고, 이미 그려진 그래프에 값을 업데이트할 때 자연스럽게 그려지기 때문입니다.)

$(function () {
    initGraph();
});

let lineGraph;
function initGraph() {
    lineGraph = c3.generate({
        bindto: '#load-graph',
        data: {
            x: 'histYmdt',
            xFormat: '%Y-%m-%d %H:%M:%S',
            type: 'line',
            json: {
                'histYmdt' : [],
            }
        },
        axis: {
            x: {
                type: 'timeseries',
                localtime: true,
                tick: {
                    count: 20,
                    format: '%m-%d %H:%M:%S'
                }
            },
            y: {
                min: 0,
                label: '동접 수'
            }
        },
        point: {
            show: false
        }
    });
}

 

데이터를 불러와 그래프에 load하겠습니다. 아까 초기화해둔 lineGraph 변수로 데이터를 load 시키기만 하면 됩니다.

function loadGraph(intervalCd, periodHour) {
    let _data = {
        intervalCd: intervalCd || $("#intervalCd").val(),
        periodHour: periodHour || $("#periodHour").val()
    };

    $.ajax({
        type: 'GET',
        url: '/getDataForGraph',
        data: _data,
        dataType: 'json',
    }).fail(function (e) {
        console.log(e)
    }).done(function(data) {
        drawGraph(data);
    });
}

function drawGraph(data) {
    lineGraph.load({json: data});
}

 

데이터의 구조는 다음과 같습니다.

drawGraph({
    "histYmdt": ["2022-06-15 14:54:10", "2022-06-15 14:54:20", "2022-06-15 14:54:30", "2022-06-15 14:54:40", "2022-06-15 14:54:50", "2022-06-15 14:55:00", "2022-06-15 14:55:10", "2022-06-15 14:55:20", "2022-06-15 14:55:30", "2022-06-15 14:55:40"],
    "localhost:11111": [10, 15, 12, 12, 12, 18, 18, 11, 11, 11],
    "localhost:11112": [null, null, 0, 2, 2, 1, 3, 3, 2, 2]
});

c3옵션 중 point.show 값을 false로 설정하여 위와 같이 선만 보이는데, true로 설정하면 아래와 같이 보입니다.

 

그리고 x축 type을 timeseries로 설정했기 때문에 중간에 데이터가 유실되어도 자연스럽게 그래프가 그려집니다.

 

마우스 오버하면 tooltip도 기본 제공됩니다.

 

전체 데이터가 있을 때, 전체 데이터만 노출 할 수도 있습니다.

drawGraph({
    "histYmdt": ["2022-06-15 14:54:10", "2022-06-15 14:54:20", "2022-06-15 14:54:30", "2022-06-15 14:54:40", "2022-06-15 14:54:50", "2022-06-15 14:55:00", "2022-06-15 14:55:10", "2022-06-15 14:55:20", "2022-06-15 14:55:30", "2022-06-15 14:55:40"],
    "전체": [10, 15, 12, 14, 14, 21, 21, 14, 13, 13],
    "localhost:11111": [10, 15, 12, 12, 12, 18, 18, 11, 11, 11],
    "localhost:11112": [null, null, 0, 2, 2, 1, 3, 3, 2, 2]
});

lineGraph.hide();
lineGraph.show('전체');
// 또는 lineGraph.hide(['localhost:11111', 'localhost:11112']);

 

 

데이터가 쌓이면 아래 그림과 같이 그래프가 그려집니다.

 

 

마지막으로 그래프 상단 좌측에 있는 기능을 구현하겠습니다.

<div>
    <select id="intervalCd" onchange="loadGraph(this.value)">
        <option value="TEN_SECONDS" selected="">10초</option>
        <option value="ONE_MINUTE">1분</option>
        <option value="FIVE_MINUTES">5분</option>
        <option value="THIRTY_MINUTES">30분</option>
        <option value="ONE_HOUR">1시간</option>
        <option value="SIX_HOURS">6시간</option>
        <option value="ONE_DAY">1일</option>
    </select>
    <div class="btn-periodHour-group">
        <input type="hidden" id="periodHour" value="1" />
        <button class="on" value="1" onclick="changePeriodHour(this)">1h</button>
        <button value="3" onclick="changePeriodHour(this)">3h</button>
        <button value="12" onclick="changePeriodHour(this)">12h</button>
        <button value="24" onclick="changePeriodHour(this)">1d</button>
        <button value="72" onclick="changePeriodHour(this)">3d</button>
        <button value="168" onclick="changePeriodHour(this)">1w</button>
    </div>
    <div>
        <button onclick="loadGraph()"><i class="fa fa-rotate-right"></i></button>
        <select onchange="reloadGraph(this.value)">
            <option value="0" selected>끄기</option>
            <option value="10">10초</option>
            <option value="60">1분</option>
            <option value="120">2분</option>
            <option value="300">5분</option>
            <option value="900">15분</option>
        </select>
    </div>
</div>
/* 검색 기간 변경 */
function changePeriodHour(othis) {
    $(".btn-periodHour-group").find("button").removeClass("on");
    $(othis).addClass("on");
    $("#periodHour").val(othis.value);

    loadGraph();
}

/* 실시간 새로고침 */
let interval;
function reloadGraph(value) {
    clearInterval(interval);
    if (value === "0") {
        return;
    }

    interval = setInterval(function() {
        console.log(value + "s");
        loadGraph();
    }, value * 1000)
}

 

 

[Reference]

https://c3js.org/

728x90
반응형

댓글