본문 바로가기
Front-end/React

[react-chartjs-2] 누적 그래프 + 라인 그래프 합치기

by 꼬바리 2022. 7. 12.

리액트 차트를 만들면서 가장 오류/버그 적게 사용한 차트 라이브러리는 react-chartjs-2

react-chartjs-2 의 단점은

공식사이트의 정보가 다소 부족하고 ( 다른 라이브러리도 동일)

화려한 애니메이션이 기본으로 제공되지 않다.

 

그러나 충분히(많이 찾아보고) 커스텀 가능 하다

 

react-chartjs-2 라이브러리에선 

누적 바 차트 / 라인 차트 가 분리되어 있지만

바 차트 + 라인차트 같이 출력하는 코드를 보고

누적 바 + 라인 차트를 커스텀해 만들어보았다.

 

 

출력되는 그래프

toolTip 도 커스텀 해서 출력 하였다

 

 

😁 npm install

//기본 설치
npm i chart.js

//차트제이에스 2를 사용하기 위한 설치
npm install react-chartjs-2 chart.js

//플러그인을 사용하기 위한 설치 
npm install chartjs-plugin-datalabels

 

 

😁 import

import { Chart as ChartJS } from 'chart.js/auto'    //미사용하지만 안적어주면 오류남
import { Bar } from 'react-chartjs-2';
import ChartDataLabels from 'chartjs-plugin-datalabels';

 

위 라이브러리를 설치하고

임포트를 해주면 출력 준비 끝

(무엇을 설치하고 임포트 해야하는 지 정보가 워낙 부족했다 수백가지 시도를 하여 알아냄;;)

 

😁 HTML

<div className="chart">
    <Bar
        data={data}
        options={options}
        plugins = {data.plugins}
    />
</div>

바 차트기준으로 출력해준다.

data 에 출력할 데이터 값을넣어주고

option에 그래프의 모양이나 onClick 툴팁 레전드 등 이벤트를 넣어줄수있다.

 

 

 

 

😁 Script

const data = {
        plugins: [ChartDataLabels],	//플러그인 사용을 위해 연결
        labels: labels, //그래프상 날짜 데이터
        datasets: [
            {
                label: eventTypeList[0],	//라벨명 ex)쓰러짐
                data: falldownData,			// 날짜 데이터 순서의 value list
                datalabels: dataFont,		//폰트 사이즈 및 색상 
                backgroundColor:objColor[0],//bar차트의 색상
                borderColor: objColor[0],	//bar의 테두리 색상
                order: 1,					//순서 non-important
            },
           //.........생략... 누적 바 차트의 데이터...
            {
                label: eventTypeList[6],
                data: crowdData,
                datalabels: dataFont,
                backgroundColor: objColor[6],
                borderColor: objColor[6],
                order: 1,
            },		//누적 bar 차트의 데이터 끝
            {
                label: "전체",		//라인차트 데이터
                data: total,		 //날짜 label데이터 순서 출력할 라인 차트의 데이터 리스트
                datalabels:{		// 라인차트의 CSS
                    // color: 'white'
                    color: lineColor,
                    backgroundColor : 'white',
                    font:{size:13,weight: 'bold'},
                },
                lineTension: 0.1, // 각 꼭지점 근처 라인의 border-radius(뾰족하게 할지, 둥글게 할지)  0-1 사이의 숫자
                backgroundColor: lineColor,
                borderColor: lineColor,
                borderDash: [5, 5],
                borderWidth : 1,
                fill: false,
                pointHoverRadius: 0,
                pointHoverBorderWidth: 0,
                type: "line",
                order: 0,
                pointRadius : 0,  //포인트 스타일 - 포인트 모양의 반지름 0일시, 그려지지않음
            },
        ],
      };
const options = {
        interaction: {
            mode: 'index',  	//툴팁 전체 출력
            intersect: false,
        },
        maxBarThickness: 15,    // bar 타입 막대의 최대 굵기
        layout: {
            padding: {
                top : 30
            }
        },
        plugins: {
            legend: {
                position: 'bottom',		//레전드 위치 
            },
            title: {
                display: false,		//타이틀 
                text: "Total",
                fontSize: 25,
            },
            datalabels: {
                anchor: 'end',  //start , end 
                align: 'top',   //top bottom middle 데이터 라벨 표시 위치
                formatter: function(value, context) { 
                     //데이터 값이 0 이면 출력 안함
                    if(context.dataset.label !== '전체'){
                        if(value == 0){
                            return null;
                        }else{
                            return value;
                        }
                    }else{
                        if(value == 0){
                            return null;
                        }else{
                            let result = value.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",")
                            return result;
                        }
                    }
                },
            },
            tooltip: {	
                // backgroundColor: 'rgba(124, 35, 35, 0.4)',
                padding: 10,
                // bodySpacing: 5,     //툴팁 내부의 항목 간격
            }  
        },
        maintainAspectRatio: false, //false :  상위 div에 구속
        responsive: true, //false : 정적 true: 동적
        scales: {
            x: {
                stacked: true,
            },
            y: {
                stacked: true,
                // beginAtZero: true
            },
        },
        onClick: function(evt, element) {
            // onClickNot working element null
            console.log(evt, element);	//클릭시 이벤트 추가 가능
        }
    };

차트에 해당 Data 와 Option을 설정해주면 출력가능하다.

옵션이나 데이터에 대한 정보는 주석으로 설명 

728x90
반응형

댓글