본문 바로가기

그 땐 IT활동했지/그 땐 영일영 근무했지

[010/JS Library] chart.js | 범례 커스텀하기(2.4.0 version)

728x90

문제 상황

chart.js의 기본적인 범례는 간단한 편이다! 그래도 본인 마음대로 범례를 커스텀할 수 있는데 그 방법을 알아보겠다.

 

오늘도 공식문서 참고ㅎㅎ(오늘 내 예시는 2.4.0버전을 사용해서 옛날 공식문서를 가져왔다. 2.4.0버전 공식문서는 못 찾겠음ㅜㅜ)

https://www.chartjs.org/docs/2.7.3/getting-started/

 

Getting Started · Chart.js documentation

No results matching ""

www.chartjs.org

chart.js 범례 커스텀하기!
/* HTML */
<section id="section-chart">
    <div>
        <div id="legend-div" class="legend-div"></div>
        <canvas id="myChart"></canvas>
    </div>
</section>

👉🏻HTMl 코드는 다음과 같다. chart를 담을 cavas 이외에 범례를 담을 div도 만들어 주었다.

<script type="text/javascript" id="inChart">
    window.onload = function () {
        chartDraw();
        let legendDiv = document.getElementById('legend-div');
        legendDiv.innerHTML = window.myChart.generateLegend();
    }

    let chartData = {
        labels: [
            '02/13', '02/14', '02/15', '02/16', '02/17', '02/18', '02/19'
        ],
        datasets: [
            {
                label: '가격1',
                fill: false,
                data: [
                     550000, 550000, 550000, 550000, 550000, 550000, 550000
                ],
                pointRadius: [
                    3, 3, 3, 3, 3, 3, 3
                ],
                backgroundColor: 'pink',
                borderColor: 'pink',
                borderWidth: 2,
            },
            {
                label: '가격2',
                fill: false,
                data: [
                    5500, 5500, 5500, 5500, 5500, 5500, 5500
                ],
                pointRadius: [
                    3, 3, 3, 3, 3, 3, 3
                ],
                backgroundColor: 'skyblue',
                borderColor: 'skyblue',
                borderWidth: 2,
            }
        ]
    }
    
    let chartDraw = function () {
        let helpCircleImg = "{% static 'help-circle.svg' %}"
        let context = document.getElementById('myChart').getContext('2d');

        window.myChart = new Chart(context, {
            type: 'line', // 차트의 형태
            data: chartData,
            options: {
                legend: {
                    display: false,
                },
                legendCallback: function (chart) {
                    let legend = document.createElement('div');
                    legend.id = "legend-wrap"
                    legend.innerHTML += `<div class="normal-wrap">
                                            <div class="box-normal" style="background-color: pink"></div>
                                            <div class="value-normal">가격1</div>
                                            <img onclick="modalOpenClose()" class="modal-normal-price" src=${helpCircleImg}>
                                        </div>
                                       <div class="min-wrap">
                                            <div class="box-min" style="background-color: skyblue"></div>
                                            <div class="value-min">가격2</div>
                                            <img onclick="modalOpenClose()" class="modal-min-price" src=${helpCircleImg}>
                                        </div>`
                    return legend.outerHTML
                },
                scales: {
                    yAxes: [{
                        position: 'right',
                        gridLines: {
                            display: false,
                        },
                    }],
                    xAxes: [{
                        gridLines: {
                            display: false,
                        },
                    }],
                }
            }
        });
    }
</script>

👉🏻내 코드는 다음과 같은데 너무 길어서 조금씩 잘라서 설명해보겠다!

 

1️⃣코드 실행 부분

window.onload = function () {
    chartDraw();
    let legendDiv = document.getElementById('legend-div');
    legendDiv.innerHTML = window.myChart.generateLegend();
}

👉🏻가장 먼저 차트를 실행하는 부분이다! document가 다 준비되기도 전에 차트를 그리는 함수를 실행해버리면 차트가 나오지 않아 window.onload를 사용해 준비가 다 되면 chartDraw()를 통해 차트를 그렸다. 해당 함수는 아래에서 더 자세히 보겠다!

👉🏻아래 두 줄은 범례를 넣는 코드이다. 옛날 버전에서 범례를 넣으려면 generatedLegend()함수를 이용해야한다! 이 함수를 호출해야 커스텀한 범례를 표시할 수 있다. 범례를 커스텀하는 과정은 아래에서 보겠다! 

 

2️⃣차트 데이터

let chartData = {
    labels: [
        '02/13', '02/14', '02/15', '02/16', '02/17', '02/18', '02/19'
    ],
    datasets: [
        {
            label: '가격1',
            fill: false,
            data: [
                 550000, 550000, 550000, 550000, 550000, 550000, 550000
            ],
            pointRadius: [
                3, 3, 3, 3, 3, 3, 3
            ],
            backgroundColor: 'pink',
            borderColor: 'pink',
            borderWidth: 2,
        },
        {
            label: '가격2',
            fill: false,
            data: [
                5500, 5500, 5500, 5500, 5500, 5500, 5500
            ],
            pointRadius: [
                3, 3, 3, 3, 3, 3, 3
            ],
            backgroundColor: 'skyblue',
            borderColor: 'skyblue',
            borderWidth: 2,
        }
    ]
}

👉🏻이 부분은 차트 데이터를 chartData 변수에 할당한 것이다. 그냥 아래의 myChart(차트 그리는 함수)에 넣어도 되지만 너무 길어져서 변수에 할당해 넣어줬다. 이부분은 그저 나의 편의를 위한 것이므로 별 중요한 내용이 없어 넘어가겠다!

 

3️⃣차트 그리는 함수

let chartDraw = function () {
    let helpCircleImg = "{% static 'help-circle.svg' %}"
    let context = document.getElementById('myChart').getContext('2d');

    window.myChart = new Chart(context, {
        type: 'line', // 차트의 형태
        data: chartData,
        options: {
            legend: {
                display: false,
            },
            legendCallback: function (chart) {
                let legend = document.createElement('div');
                legend.id = "legend-wrap"
                legend.innerHTML += `<div class="normal-wrap">
                                        <div class="box-normal" style="background-color: pink"></div>
                                        <div class="value-normal">가격1</div>
                                        <img onclick="modalOpenClose()" class="modal-normal-price" src=${helpCircleImg}>
                                    </div>
                                   <div class="min-wrap">
                                        <div class="box-min" style="background-color: skyblue"></div>
                                        <div class="value-min">가격2</div>
                                        <img onclick="modalOpenClose()" class="modal-min-price" src=${helpCircleImg}>
                                    </div>`
                return legend.outerHTML
            },
            scales: {
                yAxes: [{
                    position: 'right',
                    gridLines: {
                        display: false,
                    },
                }],
                xAxes: [{
                    gridLines: {
                        display: false,
                    },
                }],
            }
        }
    });
}

👉🏻범례를 커스텀하려면 일단 options를 손봐야 한다. 일단 기본적으로 나오는 범례를 숨겨야 하므로 legend의 속성을 display: none으로 설정한다.

👉🏻그리고 legendCallback 함수를 호출한다. 범례를 넣을 div를 불러와서 legend라는 변수에 할당해 준다. 그리고 innerHTML을 통해 범례를 원하는 모양으로 꾸며준다. 그리고 꼭! legend.outerHTML을 써줘야 한다!

커스텀 이전 범례

👉🏻커스텀 하기 전에는 살짝 투박한 기본적인 범례이다.

커스텀한 범례

🐰커스텀하고 나니 내가 원하는 대로 잘 바뀌었다ㅎㅎ

728x90