자바스크립트 애니메이션 차트를 이용해 데이터 시각화하기

안녕하세요. 이번 시간에는 javascript로 chart.js를 활용해서 데이터 시각화를 위한 애니메이션 차트 만드는 법을 알아볼 거예요. chart.js는 canvas를 이용해서 다양한 유형의 차트를 그릴 수 있는 오픈소스 라이브러리예요. 사용법이 간편하고 많은 옵션이 제공돼서 누구나 쉽게 차트를 만들고 커스터마이징 할 수 있답니다.

이번에 만들 차트는 일반적으로 많이 사용하는 대표적인 막대, 라인, 원형 3종 차트입니다. 코드가 너무 길어지면 소스코드 의 가독성이 덜어지기 때문에 html 파일은 따로 만들고 디자인은 최소한으로 해서 코드를 줄일 거예요.

 

화면 우측에는 그래프를 보여주고, 좌측은 x축과 y축 각각 데이터를 입력할 수 있는 텍스트 필드를 만들어줄게요. 데이터를 입력할 수 있도록 추가하기 버튼도 만들어야겠죠! 데이터를 입력하면 실시간으로 그래프가 그려지도록 하겠습니다.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Bar Chart</title>
		<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
		<style>
			* {box-sizing: border-box;}body{display: flex;height: 100vh}
			.inputs {flex: 0 0 400px;padding: 10px;background-color: #f2f2f2;display: flex;justify-content: flex-start;align-items: flex-start;}
			.input-field {display: flex;align-items: flex-start;}label,
			input[type="text"] {margin-right: 10px;padding: 5px;}
			input[type="text"] {width: 80px;border-radius: 5px;border: none;}
			.add-button {padding: 5px 10px;background-color: #4CAF50;color: #fff;border: none;border-radius: 5px;cursor: pointer;}
			.chart-container {flex: 1;display: flex;justify-content: center;align-items: center;}
		</style>
	</head>
	<body>
		<div class="inputs">
			<button class="add-button">Add Field</button>
			<div class="input-fields">
				<div class="input-field">
					<label>x축:</label>
					<input type="text" class="x-value">
					<label>y축:</label>
					<input type="text" class="y-value">
				</div>
			</div>
		</div>
		<div class="chart-container">
			<canvas id="myChart"></canvas>
		</div>
		<script src="example.js"></script>
		<script>
		   // 입력 필드에 이벤트 리스너를 등록하여 값이 변경될 때마다 차트를 업데이트
		   inputFields.addEventListener('input', updateChart);
		   // 추가 버튼에 클릭 이벤트 리스너를 등록하여 새로운 입력 필드를 생성
		   addButton.addEventListener('click', () => {
			   // 새로운 입력 필드를 생성하고 inputFields에 추가
			   const inputField = document.createElement('div');
			   inputField.classList.add('input-field');
			   inputField.innerHTML = '<label>x축:</label><input type="text" class="x-value"> <label>y축:</label><input type="text" class="y-value">';
			   inputFields.appendChild(inputField);
			  
			  // 새로 생성된 입력 필드의 x값과 y값에 대한 이벤트 리스너를 등록
			   const xValue = inputField.querySelector('.x-value'),
			   yValue = inputField.querySelector('.y-value');
			   xValue.addEventListener('input', updateChart);
			   yValue.addEventListener('input', updateChart);
		   });
		</script>
	</body>
</html>

기본 화면은 이렇게 간단하게 만들었습니다. 이 한 화면으로 그래프를 만들어주는 example.js만 수정해서 종류별로 보여줄게요.

 

막대그래프

//example.js
// 차트를 그릴 캔버스, x축,y축 텍스트필드, 추가 버튼을 가져온다
const ctx = document.querySelector('#myChart').getContext('2d');
const addButton = document.querySelector('.add-button');
const inputFields = document.querySelector('.input-fields');

// 초기 라벨과 데이터를 빈 배열로 만듭니다.
let labels = [],
    data = [];
// Chart.js를 이용해 차트 생성
const chart = new Chart(ctx, {
    type: 'bar', // 차트의 종류 막대로 설정
    data: {
        labels, // x축에 해당하는 라벨을 빈 배열로 설정
        datasets: [{
            label: '', // 데이터셋의 라벨을 빈 문자열로 설정
            data, // y축 데이터를 빈 배열로 설정
            // 그래프의 색상을 배열로 설정
            backgroundColor: ['#ffcd56', '#ff6384', '#36a2eb', '#4bc0c0', '#9966ff', '#ff9f40', '#c9cbcf'],
            borderColor: '#4dc9f6' // 테두리 색상을 설정
        }]
    },
    options: {
		responsive: true, // 차트 크기가 자동으로 조절되도록 설정
		maintainAspectRatio: true, // 차트의 가로 세로 비율을 유지하지 않음
        // 차트 애니메이션 효과를 설정
        animation: {
            duration: 2000, // 애니메이션 지속 시간을 설정
            easing: 'ease-in-out' // 애니메이션의 변화 속도 설정
        },
        scales: {
            y: {
                beginAtZero: true // y축의 시작 값을 0으로 설정
            }
        },
        plugins: {
            legend: {
                display: false // 범례 표시 안함
            },
            title: {
                display: true,
                text: '쭈미로운 생활 막대그래프 예제 '
            },
        }
    }
});
// Chart.js의 API를 이용해 차트에 새로운 데이터를 추가하는 함수
function addData(chart, label, data) {
    chart.data.labels.push(label); // 라벨 배열에 새로운 라벨을 추가
    chart.data.datasets[0].data.push(data); // 데이터 배열에 새로운 데이터를 추가
    chart.update(); // 차트를 업데이트
}
// 입력 필드의 값을 바탕으로 차트 데이터를 업데이트하는 함수
function updateChart() {
    // x값과 y값을 입력한 input 값을 가져온다
    const xValues = document.querySelectorAll('.x-value');
    const yValues = document.querySelectorAll('.y-value');
    // 각 input 요소에서 x값과 y값을 가져와, 데이터 배열을 업데이트
    for (let i = 0; i < xValues.length; i++) {
        // x값과 y값을 가져옵니다.
        const x = xValues[i].value,
            y = yValues[i].value;
        if (i < labels.length) {
            // 이미 입력된 데이터가 있을 경우, 변경된 데이터가 있는지 확인하고 업데이트
            if (labels[i] !== x || data[i] !== y) {
                labels[i] = x; // 라벨 배열에서 해당 인덱스의 값을 새로운 값으로 업데이트
                data[i] = y; // 데이터 배열에서 해당 인덱스의 값을 새로운 값으로 업데이트
                chart.update(); // 차트를 업데이트
            }
        } else {
            // 새로운 데이터를 추가
            addData(chart, x, y);
        }
    }
}

 

실행 화면 ▼

막대그래프 예제
.

 

라인 그래프

자바스크립트 코드는 new Chart 부분에서 type만 'line'으로 설정해 주면 됩니다. 저는 라인의 색상도 한번 변경해 봤습니다.

//example.js
const chart = new Chart(ctx, {
    type: 'line', // 차트의 종류 라인으로 설정
    data: {
        labels, // x축에 해당하는 라벨을 빈 배열로 설정
        datasets: [{
            label: '', // 데이터셋의 라벨을 빈 문자열로 설정
            data, // y축 데이터를 빈 배열로 설정
			backgroundColor: 'rgba(54, 162, 235, 0.2)', //그래프 색상을 설정
			borderColor: 'rgba(54, 162, 235, 1)', // 테두리 색상을 설정
			borderWidth: 2,
        }]
    },
  options //기존과 동일 
});

 

실행 화면 ▼

라인그래프 예제

 

위 예제는 한 가지의 데이만으로 그래프를 만들지만, 라인 그래프는 보통 두 가지의 데이터를 비교하는 경우가 많죠. 예를 들어 2023년과 2022년의 데이터를 비교해 연도별 추세를 비교하는 것처럼요. 그럴 경우에는 datasets 배열에 여러 개의 데이터 셋을 추가하면 됩니다.

   data: {
        labels: ['1월', '2월', '3월', '4월', '5월', '6월'],
        datasets: [{
            label: '서울',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: 'rgba(153, 102, 255, 0.2)',
            borderColor: 'rgba(153, 102, 255, 1)',
            borderWidth: 2
        }, {
            label: '경기',
            data: [5, 3, 8, 12, 7, 9],
            backgroundColor: 'rgba(54, 162, 235, 0.2)',
            borderColor: 'rgba(54, 162, 235, 1)',
            borderWidth: 2
        }]
    },

 

실행 화면 ▼

라인그래프 예제2

 

원형 그래프

원형 그래프 역시 new Chart 부분에서 type만 'doughnut'로 변경하면 되지만 원형 그래프에 맞는 범례와 y축의 기준 데이터를 안 보이게 수정을 하는 게 좋아요. 그리고 animateRotate: true 설정으로 원형 애니메이션을 효과를 가지도록 해야 합니다.

const chart = new Chart(ctx, {
    type: 'doughnut', // 차트의 종류 막대로 설정
    data: {
        labels, // x축에 해당하는 라벨을 빈 배열로 설정
        datasets: [{
            label: '', // 데이터셋의 라벨을 빈 문자열로 설정
            data, // y축 데이터를 빈 배열로 설정
	        backgroundColor: ['#FFC107', '#9C27B0', '#2196F3', '#4CAF50', '#F44336', '#795548', '#00BCD4'], // 그래프의 색상을 배열로 설정
            borderColor: '#fff', // 테두리 색상을 설정
            borderWidth: 1 // 테두리 두께를 설정
        }]
    },
    options: {
		responsive: true, // 차트 크기가 자동으로 조절되도록 설정
		maintainAspectRatio: true, // 차트의 가로 세로 비율을 유지하지 않음
        // 차트 애니메이션 효과를 설정
        animation: {
			animateRotate: true, // 원형 차트 회전 애니메이션을 활성
            duration: 2000, // 애니메이션 지속 시간을 설정
            easing: 'ease-in-out' // 애니메이션의 변화 속도 설정
        },
        scales: {
            y: {
                display: true, // y축의 눈금 표시 설정
				ticks: {
					display: false, //y축 기준 데이터 표시 설정
				},
            },
        },
    plugins: {
            legend: {
                position: 'bottom', // 범례 위치 설정
                labels: {
                    fontColor: '#333', // 범례 레이블 글자 색상 설정
                    fontSize: 14 // 범례 레이블 글자 크기 설정
                }
            },
            title: {
                display: true,
                text: '쭈미로운 생활 원형그래프 예제 '
            },
        }
    }
});

 

실행 화면 ▼

원형그래프 예제

 

 

오늘은 이렇게 다양한 그래프 만드는 방법을 간단하게 살펴보았는데요. chart.js는 여러 가지 설정과 애니메이션 효과에 따라 더욱 멋진 그래프를 만들 수 있어서 데이터 시각화에 매우 유용하답니다.  - 끝 -