jineecode
chart.js 본문
내가 맡은 업무 중 하나인 그래프 만드는 업무에 chart.js가 들어가기로 했다.
버전이 여러 번 업데이트 되는 것 같았고 그럴수록 설치 방법부터 코드도 뒤바뀌는 느낌이다.
예전 버전은 파일을 zip으로 다운로드 받아서 script에 넣었다면 지금은 npm install chart.js 로 대체하는 느낌.
npm으로 설치하면 노드 모듈 파일이 깔린다.
상황에 따라 어떻게 설치할지, 어떻게 import 할 지 고려해서 달리 쓰면 될 것 같다.
*플러그인을 쓰려고 할 경우 너무 높은 버전을 설치하면 일부 코드가 작동하지 않는다. 나 같은 경우
npm i chart.js@2.9.3
으로 설치하였다.
*라벨 위에 숫자를 표기하고 싶다면 아래 cdn을 넣는다.
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0"></script>
공식사이트
한글화 chart.js 사이트
https://yeon22.github.io/Chartjs-kr/
한글화 GIT SITE
https://github.com/Yeon22/Chartjs-kr
아래는 사이트에서 제공해주는 예제 코드.
나는 연습 삼아서 npm으로 chart.js를 설치해보았고 경로는 로컬에 맞게 잡아주었다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./node_modules/chart.js/dist/chart.js"></script>
</head>
<body>
<div>
<canvas id="myChart" width="400" height="400"></canvas>
</div>
롸
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
</body>
</html>
차트의 옵션이 정말 많은데 하나하나 건드려보면서 감을 잡는 게 중요한 것 같다. 개인적으로 커스텀하는 게 가장 어려웠고 당장 내가 해결해야하는 부분이기 때문에 하나하나 만져보면서 포스팅 하려고 한다.
1. line
//DOM
var ctx = document.getElementById('myChart');
//여기부터 옵션을 지정하여 그래프를 렌더링합니다
var myChart = new Chart(ctx, {
type: 'line', //차트타입: line, bar, radar, doughnut, bubble 등...
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
//각 데이터 라벨명 (즉, x축에 놓여지는 데이터명)
datasets: [{
label: '# of Votes',
// 라벨 이름
data: [12, 19, 3, 5, 2, 3],
//각 데이터의 값
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
//그래프 컬러
//차트 타입에 따라 다릅니다. ex : 막대그래프는 몸통 색깔, 직선은 꼭지점 색깔
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
//그래프의 테두리 컬러
borderWidth: 1
//테두리 두께
}]
},
options: {
scales: {
yAxes: [{
//y축
ticks: {
beginAtZero: true
//0부터 시작
}
}]
}
}
});
아래에 바다처럼 꽉 찬 배경색을 없애고 싶으면 fill: false를 해주면 없어진다.
...
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1,
fill: false
}]
},
...
곡선이 그려지는 게 싫다면 tension: 0을 준다
...
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1,
fill: false
tension: 0
}]
...
간단한 예제
datasets: [{
label: '# of Votes',
data: [12, null, 3, 5, 2, 3],
// 포인트
backgroundColor: [
// 포인트를 채울 색상을 지정합니다.
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
pointBorderColor: [
// 포인트 테두리 색상을 지정합니다.
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
pointBorderWidth: 3,
// 포인트 테두리의 두께를 픽셀단위로 지정합니다.
pointRadius: 10,
// 포인트 모양의 반지름을 지정합니다. 만약 0으로 지정하면, 포인트는 그려지지 않습니다.
borderWidth: 1,
pointStyle: 'star',
// 선 스타일링
borderColor: 'rgba(153, 102, 255, 1)',
// 선 색상.
fill: false,
// 선 아래 영역을 어떻게 채울지 지정합니다
tension: 0,
// 선의 곡선 장력을 지정
showLine: true,
//false이면, 이 데이터집합에 대한 선은 그려지지 않습니다.
spanGaps: true
//true이면, 데이터가 없거나 null인 점 사이에 선이 그려집니다.
//false이면, NaN 데이터가 있는 포인트가 줄에 끊김을 생성합니다.
}]
spanGaps 가 false 일 경우 데이터가 없을 때 줄이 끊겨 보인다
2. ajax를 통해 data를 넣어야 하는 경우
1) ajax로 최저기온, 최대기온을 받아와 data에 넣어주고, 평균 기온을 계산하여 그래프로 그려주어야 한다.
ajax로 데이터를 push해주기 위해서 빈 배열을 미리 준비해둔다.
// 예보 날씨
const minData = [];
const maxData = [];
const avgData = [];
2) ajax
기본적인 ajax 구조
$.ajax({
type: 'POST', //post method
url: 'url', //ajaxformexample url
dataType: "json",
success: function (result, textStatus, jqXHR)
{
chart.data = result;
chart.update();
}
});
적용
// 예보 날씨 최대최저평균 기온값
function minMaxData() {
ajaxCall(
"GET",
"날씨 url",
null,
function (data) {
for (let i = 0; i < data.data.length; i++) {
minData.push(data.data.week[i].maxtemp);
maxData.push(data.data.week[i].mintemp);
avgData.push((minData[i] + maxData[i]) / 2);
forecastWeatherChart.update();
}
},
null,
null
);
}
minMaxData();
이때 주의할 점은, ajax로 데이터를 push 해주고서 반드시 차트를 update()를 해주어야 반영이 된다.
나는 차트의 이름을 forecastWeatherChart으로 새롭게 선언했기 때문에 forecastWeatherChart.update로 해주었다.
이렇게 update를 해주지 않으면 배열이 독특한 형태를 띄게 된다.
결론 chart canvas
// 예보 날씨
const minData = [];
const maxData = [];
const avgData = [];
// 예보 날씨 최대최저 기온값, 이미지
function minMaxData() {
ajaxCall(
"GET",
"url",
null,
function (data) {
for (let i = 0; i < 5; i++) {
minData.push(data.data.week[i].maxtemp);
maxData.push(data.data.week[i].mintemp);
avgData.push((minData[i] + maxData[i]) / 2);
forecastWeatherChart.update();
}
},
null,
null
);
}
forecastDay();
minMaxData();
// 예보 날씨 그래프
let forecastWeatherChart = new Chart(ctxforecastWeather, {
type: "line",
data: {
labels: daysLabel,
datasets: [
{
label: "min",
backgroundColor: "transparent",
borderColor: "#transparent",
data: minData, //data 부분에 위에서 선언해둔 최저 기온 minData를 넣는다.
borderWidth: 0,
fill: false,
radius: 0,
showLine: false,
datalabels: {
display: true,
align: "bottom",
anchor: "end",
color: "black",
borderWidth: 2,
padding: {
bottom: 0,
},
},
},
{
label: "avg",
backgroundColor: "#005500",
borderColor: "#005500",
data: avgData, //data 부분에 위에서 선언해둔 평균 기온 avgData를 넣는다.
fill: false,
borderWidth: 1.5,
datalabels: {
display: false,
},
},
{
label: "max",
backgroundColor: "transparent",
borderColor: "#transparent",
borderWidth: 0,
data: maxData, //data 부분에 위에서 선언해둔 최대 기온 maxData를 넣는다.
fill: false,
line: false,
radius: 0,
showLine: false,
datalabels: {
display: true,
align: "top",
anchor: "end",
color: "black",
borderWidth: 2,
padding: {
bottom: 0,
},
},
},
],
},
plugins: [
{
...
});
3. 차트 위에 숫자를 띄우는 법
https://chartjs-plugin-datalabels.netlify.app/
1) html에 아래 cdn이 있어야 한다.
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0"></script>
2) datasets 아래에 datalabels 를 코딩한다.
let temperatureChart = new Chart(ctxTemperature, {
type: "line",
data: {
labels: ["현재", "13시", "14시", "15시", "16시"],
datasets: [
{
data: [12, 13, 15, 14, 16],
borderWidth: 1,
backgroundColor: "rgb(0, 85, 0)",
borderColor: "rgb(0, 85, 0)",
fill: false,
tension: 0,
datalabels: { //이 부분이 핵심
display: true,
align: "top",
anchor: "end",
color: "black",
borderWidth: 2,
padding: {
bottom: 0,
},
},
},
],
},
4. chartjs 글로벌로 css 바꾸는 법
javascript에 console.log(chart.defaults.global)을 써보면 어떤 속성을 바꿀 수 있는지 나타난다. 개중 내가 썼던 것은 다음과 같다.
Chart.defaults.global.tooltips.enabled = false; // 툴팁을 보일 일이 없어서 false로 없애버렸다.
Chart.defaults.global.defaultFontColor = "#000000"; //폰트 컬러
Chart.defaults.global.defaultFontFamily = "Noto Sans KR"; //폰트
Chart.defaults.global.defaultFontSize = 13; //폰트 사이즈
Chart.defaults.global.defaultLineHeight = 1.33; //폰트 Lineheight
이렇게 global하게 적용시켜둔 뒤, 세부적인 조정은 각 chart의 option 에서 변경하는 것이 좋다.
'JS' 카테고리의 다른 글
javascript 뒤로가기 방지 코드 (0) | 2021.07.08 |
---|---|
onclick 링크 (새창/팝업/현재창/프레임) (0) | 2021.06.30 |
웹 스토리지 (localStorage, sessionStorage) 사용법 (0) | 2021.06.21 |
webpack 뜯어보기 (0) | 2021.05.28 |
reduce 파헤치기 (0) | 2021.05.21 |