문제 상황
2022.03.20 - [그 땐 IT활동했지/그 땐 영일영 근무했지] - [010/JavaScripts] chart.js | 범례 커스텀하기(2.4.0 version)
차트를 그리고 범례까지 커스텀하는 것에 성공했다!(이전 포스팅↑) 하지만 chart.js가 옛날 버전이라 자료를 찾거나 최신 기능을 이용하기 힘들었다..
때문에 버전을 올려야 할 필요성을 느꼈고 버전을 올리니 코드도 대폭 바꿔야 했다. 버전이 올라가며 코드 작성 방식이 바뀌었기 때문이다.ㅎㅎ
그럼 chart.js 최신 버전 범례 커스텀 시작!
최신버전 공식문서!
https://www.chartjs.org/docs/latest/
버전 올리기
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
👉🏻버전을 바꾸는 것 자체는 어렵지 않다. CDN script를 위와 같이 최신 버전의 것으로 바꾸면 된다!
범례 새로 쓰기
🐰코드를 새로 쓰는게 어려웠다..ㅎㅎㅠㅠ 그럼 저번 포스팅 처럼 코드를 3부분으로 나누어 보겠다.
1️⃣차트 실행 & 차트 데이터
window.onload = function () {
chartDraw();
let legendDiv = document.getElementById('legend-div');
}
let chartData = {
labels: [
3/13, 3/14, 3/15, 3/16, 3/17, 3/18, 3/19
],
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: [
548000, 548000, 548000, 548000, 548000, 548000, 548000
],
pointRadius: [
3, 3, 3, 3, 3, 3, 3
],
backgroundColor: 'skyblue',
borderColor: 'skyblue',
borderWidth: 2
}
]
}
👉🏻window가 준비완료 되면 차트 그리는 함수를 실행한다.
👉🏻차트에 넣을 데이터이다.
2️⃣차트 실행 함수
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 }
}
},
legend: {
display: false,
},
htmlLegend: {
containerID: 'legend-div',
},
},
interaction: {
intersect: false,
},
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' }
}
}
},
}
},
plugins: [htmlLegendPlugin],
});
}
👉🏻버전이 업데이트되면서 options의 plugins에 legend 속성을 설정해야 한다. 우리가 커스텀할 legend를 넣을 것 이므로 일단 'display: false'로 설정한다. 그리고 커스텀할 legend를 넣을 html 위치(해당 div의 id)를 htmlLegend 속성에 적어준다.
👉🏻그리고 마지막 줄에 plugins에 [htmlLegendPlugin]을 넣어준다. 해당 plugin은 아래에서 작성할 것이다.
3️⃣범례 함수
const getOrCreateLegendList = (myChart, id) => {
const legendContainer = document.getElementById(id);
let listContainer = legendContainer.querySelector('ul');
if (!listContainer) {
listContainer = document.createElement('ul');
legendContainer.appendChild(listContainer);
}
return listContainer;
};
const htmlLegendPlugin = {
id: 'htmlLegend',
afterUpdate(chart, args, options) {
const ul = getOrCreateLegendList(chart, options.containerID);
// Remove old legend items
while (ul.firstChild) {
ul.firstChild.remove();
}
// Reuse the built-in legendItems generator
const items = chart.options.plugins.legend.labels.generateLabels(chart);
items.forEach(item => {
let classText = ''
if ( item.text === '가격1' ) { classText = 'max'}
else{ classText = 'normal'}
const li = document.createElement('div');
li.classList.add('wrap');
// Color box
const boxSpan = document.createElement('span')
boxSpan.classList.add(`box-${classText}`);
boxSpan.style.background = item.fillStyle;
// Text
const textContainer = document.createElement('p');
textContainer.classList.add(`value-${classText}`);
const text = document.createTextNode(item.text);
textContainer.appendChild(text);
const helpCircle = document.createElement('img');
helpCircle.src = '{% static 'imgs/stockList/includes/phone_list_table/help-circle.svg' %}';
helpCircle.onclick = modalOpenClose;
helpCircle.classList.add(`modal-${classText}-price`);
li.appendChild(boxSpan);
li.appendChild(textContainer);
li.appendChild(helpCircle);
ul.appendChild(li);
});
}
};
👉🏻먼저 ul 태그를 추가해주는 getOnCreateLegendList 함수를 짜준다.
👉🏻htmlLegendPlugin 코드를 짜보자!
- getOnCreateLegendList함수를 실행해주고 먼저 그 안에 있는 요소를 제거해준다. 새롭게 만든 요소를 넣어주기 위함이다.
- 아래에서 generateLabels를 호출해 본인이 원하는 요소를 만들고 style을 지정해서 li 태그에 넣어준다.
- 최종적으로 이 li 태그를 ul 태그에 넣어준다.
🐰커스텀을 잘 해 내가 원하는대로 나왔다!
'그 땐 IT활동했지 > 그 땐 영일영 근무했지' 카테고리의 다른 글
[010/JS Library] chart.js | 그래프 커스텀하기 (함수편) (0) | 2022.03.24 |
---|---|
[010/JS Library] chart.js | 그래프 커스텀하기 (일반편) (0) | 2022.03.23 |
[010/JS Library] chart.js | 범례 커스텀하기(2.4.0 version) (0) | 2022.03.20 |
[010/JS Library] chart.js | 기본적인 사용법 (0) | 2022.03.19 |
[010/Django] django-import-export | Widget | ManyToManyWidget (0) | 2022.03.14 |