일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- JavaScript
- 데이터 시각화
- html
- 상태값 저장 유지
- thymeleaf
- vscode
- ui인터페이스
- jsp
- IndexedDB
- 초보 개발자
- MYSQL
- Eclipse
- 자바
- tomcat
- vsc
- open in browser
- spring boot
- @requstbody
- git
- 여러 종류의 사용자 정의 함수
- css
- chart.js 라이브러리
- resutful api
- java
- 자바스크립트
- 자바빈
- 게시판
- github
- chart.js
- 실시간 상태값 저장
- Today
- Total
수월한 IT
chart.js를 사용한 데이터 시각화하기 #2/3 본문
https://jobtc.tistory.com/146 (기본 차트)
https://jobtc.tistory.com/147 (실시간 차트)
https://jobtc.tistory.com/148 (서버 데이터 차트)
안녕하세요 IT여행자입니다.
두 번째 시간으로 이번에는 로컬에서 실시간으로 변경되는 데이터를 사용하여 그래프를 동적으로 그려서, 보다 생동감 있는 데이터 시각화를 해 보도록 하겠습니다.
주요 요점은 아래의 2가지입니다.
- line 그래프에서 꺾인 부분을 부드럽게 표현하기
- 실시간으로 데이터를 발생시켜 그래프에 적용하기
1. line 그래프에서 꺾인 부분을 부드럽게 표현하기
line 그래프에서 꺾인 부분을 부드럽게 표현하려면 tension 속성값을 지정하면 됩니다. tension은 곡률을 의미하는데, tension의 범위는 0~1까지입니다. 0으로 갈수록 직선이 되며, 1로 갈수록 곡선형으로 변경됩니다.
{
label: '판매',
data: data,
type : 'line',
borderWidth: 2, /* 선의 굵기 */
borderColor: '#00f',
pointBackgroundColor:colors, /* 포인트의 색상 */
pointRadius: 4, /* 포인트의 크기 */
tension : .35 /* 곡률 */
},
2. 실시간으로 그래프 그리기
데이터가 서버로부터 전달되는 것이 아니라 로컬에서 변경되는 상황이라 설정하고 그래프를 동적으로 그리도록 하겠습니다.
<button onclick="next()">next</button>
<button onclick="auto()">auto</button>
먼저 버튼 3개 만들고 각각 이전 데이터(prev), 다음 데이터(next), 실시간 변경데이터(auto) 형식으로 작업하도록 하겠습니다. prev 버튼과 next 버튼이 클릭되면 아래와 같은 함수가 호출됩니다.
var data=[44,22,66,44,88,55,77]
myChart.data.datasets[0].data = data;
myChart.data.datasets[1].data = data;
myChart.update();
}
var next = ()=>{
var data=[77,66,55,88,99,33,88]
myChart.data.datasets[0].data = data;
myChart.data.datasets[1].data = data;
myChart.update();
}
임의의 데이터를 data변수에 담은 뒤, myChart.data.datasets [0]과 myChart.data.datasets [1]은 화면에 그려진 첫 번째 그래프와 두 번째 그래프를 의미하며 이 객체의 data 속성에 동일한 데이터를 대입하여 같은 값을 갖는 그래프를 화면에 표시하였습니다. 그러나 전체 코드를 보면 알 수 있듯이 첫 번째 그래프는 막대그래프를 그리게 되고, 두 번째 그래프는 선 그래프를 그리게 됩니다.
auto 버튼을 클릭하면 약 20회에 걸쳐 렌덤 하게 발생한 데이터가 두 개의 그래프에 각각 적용되어 그래프의 모양은 다르지만 같은 값의 데이터가 화면에 출력됩니다.
let cnt=0;
while(cnt<20){
var data = [];
for(i=0; i<7; i++){
data.push(Math.random()*90+10);
}
myChart.data.datasets[0].data = data;
myChart.data.datasets[1].data = data;
myChart.update();
cnt++;
await new Promise(resolve => setTimeout(resolve, 1000)); /* 시간 지연 */
}
}
반복문 while을 다시 반복하기 전에 setTimeout() 함수를 사용하여 시간 지연 효과를 집어넣었습니다. new Promise()는 새로운 promise를 생성하는데 이를 해결하기 위해서는 resolve 콜백함수를 리턴 받아야 합니다. 따라서 setTimeout의 두 번째 인수값이 1000(1초)이 지나면 콜백 함수인 resolve를 실행하여 resolve를 리턴합니다. 이 resolve가 리턴될 때까지 기다리도록 하기 위해 new Promise() 앞에 await 명령을 추가하였습니다. 그런데 await 명령은 반드시 동기화 블록 내에서만 사용할 수 있기 때문에 해당 함수 블록의 시작 부분에 async명령을 사용하게 된 것입니다.
만약 이런 식으로 시간 지연이 일어나지 않으면 차트를 렌더링 하기도 전에 반복문이 모두 처리되고 말 것이기 때문에 정상적인 그래프를 볼 수 없게 됩니다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="http://cdn.jsdelivr.net/npm/chart.js"></script> <title>chart step 2</title> <style> #chart { width: 600px; height: 300px; position: relative; } .btnZone { display: flex; justify-content: center; } </style> </head> <body> <h3 class="info"> 동적 챠트 그리기 </h3> <div id="chart"> <canvas id="myChart"></canvas> <div class="btnZone"> <button onclick="prev()">prev</button> <button onclick="next()">next</button> <button onclick="auto()">auto</button> </div> </div> <script> var ctx = document.querySelector('#myChart').getContext('2d') var data = [10, 50, 30, 70, 90, 40, 55] var x_labels = ['1월', '2월', '3월', '4월', '5월', '6월'] var colors = ['#f55a', '#5f5a', '#ff5a', '#f5fa', '#345a', '#123a', '#986a'] var myChart = new Chart(ctx, { data: { labels: x_labels, /*x축 라벨 */ datasets: [ { label: '판매', data: data, type: 'line', borderWidth: 2, /* 선의 굵기 */ borderColor: '#00f', pointBackgroundColor: colors, /* 포인트의 색상 */ pointRadius: 4, /* 포인트의 크기 */ tension: .35 /* 곡률 */ }, { label: '순이익', data: data, type: 'bar', borderWidth: 0, backgroundColor: colors, }, ] }, options: { responsive: true, /* 차크 크기 자동 조정 */ plugins: { title: { display: true, text: '전체 판매현황', } }, scale: { y: { min: 0, max: 110, ticks: { stepSize: 20, } } } } }) var prev = () => { var data = [44, 22, 66, 44, 88, 55, 77] myChart.data.datasets[0].data = data; myChart.data.datasets[1].data = data; myChart.update(); } var next = () => { var data = [77, 66, 55, 88, 99, 33, 88] myChart.data.datasets[0].data = data; myChart.data.datasets[1].data = data; myChart.update(); } var auto = async () => { let cnt = 0; while (cnt < 20) { var data = []; for (i = 0; i < 7; i++) { data.push(Math.random() * 90 + 10); } myChart.data.datasets[0].data = data; myChart.data.datasets[1].data = data; myChart.update(); cnt++; await new Promise(resolve => setTimeout(resolve, 1000)); } } </script> </body> </html>

auto 버튼이 클릭되면 차트의 모양이 20회 실시간으로 변화되는 것을 확인해 볼 수 있습니다.
'BOOKS > 수월한 자바스크립트' 카테고리의 다른 글
localStorage VS indexedDB를 사용한 현재 상태값 실시간 저장하기 (0) | 2025.03.22 |
---|---|
chart.js를 사용한 데이터 시각화하기 #3/3 (4) | 2024.12.27 |
chart.js를 사용한 데이터 시각화하기 #1/3 (4) | 2024.12.26 |
개발 초보자를 위한 상위 Top10 구하기 (0) | 2023.02.24 |
초보 개발자를 위한 스무 고개 게임 만들기 (0) | 2023.02.20 |