[010/JS Library] chart.js | 그래프 커스텀하기 (일반편)
문제 상황
2022.03.21 - [그 땐 IT활동했지/그 땐 영일영 근무했지] - [010/JavaScripts] chart.js | 범례 커스텀하기(3.7.1 version)
차트를 만드는 것까지는 성공! 하지만 원하는 모양으로 만들기 위해 또 커스텀이 필요하다.ㅎㅎ
아래 공식문서에도 잘 나와있지만 실제 코드를 뜯어보며 어떻게 쓰는지 알아보자!
(시작하기 전에 범례 커스텀 부분은 이전 포스팅에 자세히 설명되어 있어 아예 뺐다. 궁금하다면 위 링크 참조!!)
코드 간단 설명
let chartData = {
labels: [
'3/10', '3/11', '3/12', '3/13', '3/14', '3/15', '3/16'
],
datasets: [
{
label: '가격1',
fill: false,
data: [
620000, 620000, 620000, 620000, 620000, 620000, 620000
],
pointRadius: [
3, 3, 3, 3, 3, 3, 3
],
borderColor: 'pink',
backgroundColor: 'pink',
borderWidth: 2,
},
{
label: '가격2',
fill: false,
data: [
70000, 70000, 70000, 70000, 70000, 70000, 70000
],
pointRadius: [
3, 3, 3, 3, 3, 3, 3
],
backgroundColor: 'skyblue',
borderColor: 'skyblue',
borderWidth: 2,
}
]
}
👉🏻차트 데이터를 chartData라는 변수에 따로 담아줬다.
let chartDraw = function () {
let context = document.getElementById('myChart').getContext('2d');
let lastDataIndex = chartData.datasets[0].data.length - 1;
Chart.register(ChartDataLabels);
window.myChart = new Chart(context, {
type: 'line',
data: chartData,
options: {
layout: {},
plugins: {
datalabels: {
color: 'black',
anchor: 'end',
clamp: true,
clip: true,
align: '-135',
offset: 1,
formatter: function (value, context){
let result = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result + '원'
},
display: function(context) {
if ( context.dataIndex === lastDataIndex ) { return 1 }
else { return 0 }
}
},
},
scales: {
y: {
type: 'linear',
position: 'right',
grace: '5%',
grid: {
display: false,
},
ticks: {}
},
x: {
grid: {
display: false,
},
ticks: {
alignment: 'end',
color: function (ctx) {
if ( ctx.index === lastDataIndex ) { return '#426AE6' }
else { return 'black' }
}
}
},
}
},
});
}
👉🏻차트를 실행하는 전체 코드이다.
👉🏻data 부분에 chartData를 넣어줬다.
👉🏻차트의 다양한 요소의 속성은 options에서 설정해주면 된다. 이제 아래에서 options에서 어떤 속성을 어떻게 설정할지 알아보자!
데이터레이블 위치
options: {
plugins: {
datalabels: {
color: 'black',
anchor: 'end',
clamp: true,
clip: true,
align: '-135',
offset: 1,
formatter: function (value, context){
let result = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return result + '원'
},
display: function(context) {
if ( context.dataIndex === lastDataIndex ) { return 1 }
else { return 0 }
}
},
},
}
👉🏻데이터레이블은 options의 plugins에 적어야 한다. datalabel은 'chartjs-plugin-datalabels'를 사용한다. 아래 링크를 참조하자! 직관적인 color와 같은 것만 빼고 독특한 것만 살펴보겠당
https://chartjs-plugin-datalabels.netlify.app/
1️⃣anchor - 데이터레이블의 위치
👉🏻영어로는 '닻을 내리다, 정박하다'이다. 즉 데이터레이블이 차트 축에서 얼마나 떨어져있는지 정한다.
- start: 차트에서 가장 가까이 있다.
- center: default값이고 차트에서 중간 거리만큼 떨어져있다.
- end: 차트에서 가장 멀리 떨어져있다.
👉🏻차례대로 속성을 start, center, end로 줬을 때이다.(미세한 차이!)
2️⃣clamp - 가시적인 부분에서의 데이터레이블의 위치
👉🏻가끔 데이터레이블이 차트 바깥부분으로 나가면 보이지 않는 경우가 생긴다. 이때 보이도록 할 것인지 원래의 위치에 그대로 위치시킬 것인지 정한다.
- true: 차트 안쪽 위치로 이동시킨다.
- false: 차트 바깥쪽(원래) 위치에 둔다.
👉🏻얘는 직접 상황을 만들어 캡쳐하기 어려워서 공식문서 사진으로 대체ㅎ
3️⃣clip - 데이터레이블이 일부 가려질 때
👉🏻가끔 데이터레이블이 완전히 차트 바깥으로 나가지 않고 일부만 가릴 때가 있다. 이때 완전히 보이지 않게 할지 반정도만 가려진 상태로 둘지 정한다.
- true: 데이터레이블을 아예 가린다.
- false: 데이터레이블이 일부만 가려진 상태로 둔다.
👉🏻위 사진은 각각 clip 속성이 false, true일 때 모습니다. false일 때는 일부 가려진채로 두고 true일 때는 완전히 가려버린 모습을 볼 수 있다.
3️⃣align & offset - 데이터레이블의 방향
👉🏻align은 데이터레이블의 세세한 방향을 각도로 정한다.
👉🏻offset은 차트와 떨어진 거리를 나타내고 default가 4이다. align이 center일 때는 적용되지 않는다.
👉🏻각각 align이 45도, 135도, -135도인 모습이다. 45도일 때는 데이터 레이블이 오른쪽으로 밀려 아예 안 보이고 왼쪽의 데이터레이블이 빼꼼한 모습을 볼 수 있다.
👉🏻각각 offset이 5, 20, 50일 때이다. 점점 멀어지는 것을 볼 수 있다.
🐰이후 formatter와 display 속성은 함수를 사용했기 때문에 이후 포스팅할 함수편에서 만나보자!ㅎㅎ
x축과 y축
🐰x축과 y축은 options의 scales 속성 안에서 설정해준다.
options: {
scales: {
y: {
type: 'linear',
position: 'right',
grace: '5%',
grid: {
display: false,
},
},
x: {
grid: {
display: false,
},
ticks: {
color: function (ctx) {
if ( ctx.index === lastDataIndex ) { return '#426AE6' }
else { return 'black' }
}
}
},
}
},
}
👉🏻x축과 y축 모두 동일하게 같은 설정을 줄 수 있다. 처음부터 살펴보자!
1️⃣type
👉🏻축의 형태로 linear, time, radar 등등이 있다.
2️⃣position
👉🏻축의 위치이다. 아래 사진은 y축의 position을 각각 right, left로 설정했을 때이다.
3️⃣grace
👉🏻축의 범위이다. 값이 커질수록 범위가 커진다. 아래 사진은 y축의 grace가 각각 5%, 50%, 100%일 때이다. 퍼센트로 설정한다.
4️⃣grid
👉🏻보조선이다. 아래는 y축이 각각 true, false일 때다.
🐰ticks의 color에도 함수가 사용되었으니 다음에 만나도록 하자ㅎㅎ