[chart.js] chart 3.2(3.x) + 다중 차트 + 클릭 이벤트 + 상시 레이블 출력
기능
- 라인 다중 차트(line multiple chart)
- 다중 차트 클릭 이벤트 제어(multiple chart click event control)
- 상시 레이블 출력( show label without mouseover)
html
canvas에 cMultiLineChart 생성
<canvas id="cMultiLineChart" style="min-height: 400px; height: 400px; max-height: 1000px; width: 700px; max-width: 100%;"></canvas>
javascript
chart.min.js : chart.js 3.x 사용을 위해 추가
chartjs-plugin-datalabels@2.0.0 : 마우스 오버없이 레이블을 항상 표시하기 위해 추가 ( chart.js 3.x 버전 부터는 2.0.0 사용)
[상시 레이블 출력 로직]
chart.js 3.x 버전에서 datalabels을 사용하기 위해서 반드시 chart config에 plugins: [ChartDataLabels] 추가 (중요)
plugins: [ChartDataLabels]를 추가하지 않는 경우, CDN을 추가하더라도 datalabels 인식이 되지 않음
data의 labels를 외부에서 입력 하는 경우
MultiLineChart.data.labels.push('월');
MultiLineChart.data.labels.push('화');
...
MultiLineChart.data.labels.push('일');
MultiLineChart.update();
group별 datasets의 data는 일반적으로 외부(DB)에서 조회 후 아래 형태로 입력
Chart_config.data.datasets[0].data.push(11);
Chart_config.data.datasets[0].data.push(22);
Chart_config.data.datasets[1].data.push(33);
Chart_config.data.datasets[1].data.push(44);
Chart_config.data.datasets[2].data.push(55);
Chart_config.data.datasets[2].data.push(66);
MultiLineChart.update();
datasets의 datalabels Color는 function을 사용하여 ctx값 추출하여 처리
예제는 value가 5 이상인 경우만 Color를 적용
function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 5 ? ctx.dataset.backgroundColor : null;
}
color : label의 색상
backgroundColor : label 배경 색상
formatter : label 출력값
[클릭 이벤트 로직]
이벤트 발생 정보 조회
chart.js 3.x 이후 버전부터 getElementsAtEventForMode를 사용
var activePoints = C_Issue_analysis_range.getElementsAtEventForMode(evt, 'point', C_Issue_analysis_range.options);
클릭한 Chart의 그룹 인덱스 정보 ( 예제 에서는 Group 1, Group 2, Group 3 의 인덱스)
var datasetIndex = activePoints[0].datasetIndex
클릭한 그룹의 Value를 참조하기 위한 Index
var index = activePoints[0].index
Group label 정보
var label = MultiLineChart.data.datasets[datasetIndex].label;
클릭한 x좌표의 값 정보
var xlavel = MultiLineChart.scales["x"]._labelItems[index].label;
클릭한 Group의 Value값
var value = MultiLineChart.data.datasets[datasetIndex].data[index];
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
// Chart ctx Create
var Chart_ctx = document.getElementById('cMultiLineChart').getContext('2d');
// Chart Config Set
Chart_config = {
plugins: [ChartDataLabels],
type: 'line',
data: {
labels: ['월','화','수','목','금','토','일'],
datasets: [
{
label: 'Group 1',
data: [1,1,2,2,3,3,4],
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 3,
datalabels: {
labels: {
value: {
align: 'top',
backgroundColor: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 0 ? ctx.dataset.backgroundColor : null;
},
borderWidth: 2,
borderRadius: 4,
color: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 0 ? 'black' : null;
},
padding: 4
}
}
}
},
{
label: 'Group 2',
data: [4,4,5,5,0,0,1],
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 3,
datalabels: {
labels: {
value: {
align: 'top',
backgroundColor: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 0 ? ctx.dataset.backgroundColor : null;
},
borderWidth: 2,
borderRadius: 4,
color: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 0 ? 'black' : null;
},
padding: 4
}
}
}
},
{
label: 'Group 3',
data: [0,0,7,8,9,4,1],
backgroundColor: 'rgba(50, 220, 20, 0.2)',
borderColor: 'rgba(50, 220, 20, 1)',
borderWidth: 3,
datalabels: {
labels: {
value: {
align: 'top',
backgroundColor: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 5 ? ctx.dataset.backgroundColor : null;
},
borderWidth: 2,
borderRadius: 4,
color: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 5 ? 'black' : null;
},
padding: 4
}
}
}
}
]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
},
plugins: {
legend: {
position: 'left',
},
title: {
display: true,
text: '그룹별 주간 카운트',
font: {
size: 30
}
}
}
}
};
// Chart Create
var MultiLineChart = new Chart(Chart_ctx, Chart_config);
// Chart Click Event
document.getElementById("cMultiLineChart").onclick = function(evt) {
var activePoints = MultiLineChart.getElementsAtEventForMode(evt, 'point', MultiLineChart.options);
var datasetIndex = activePoints[0].datasetIndex
var index = activePoints[0].index
var label = C_Issue_analysis_interval.data.datasets[datasetIndex].label;
var xlavel = C_Issue_analysis_interval.scales["x"]._labelItems[index].label
var value = C_Issue_analysis_interval.data.datasets[datasetIndex].data[index]
//alert(label + " : " + value + " : " + xlavel);
//Process
};
참고
https://v2_0_0--chartjs-plugin-datalabels.netlify.app/guide/getting-started.html#installation
https://www.chartjs.org/docs/3.2.1/samples/tooltip/interactions.html
https://www.chartjs.org/docs/latest/getting-started/v3-migration.html
https://www.chartjs.org/docs/latest/developers/api.html
https://stackoverflow.com/questions/50515985/get-ylabel-value-onclick-chart-js
'DevOps > Web' 카테고리의 다른 글
web page에 반응형 임베드 ( google ppt or 동영상 ) 넣기 (0) | 2021.09.09 |
---|---|
textarea에 text와 함께 image를 첨부하여 작성 ( div contentEditable 형태로 구현 ) (0) | 2021.07.30 |
[javascript/html] 현재 Page에서 열기 / 새탭에서 Page 열기 (0) | 2021.07.19 |
[javascript] 날짜 관련 함수 정리 (0) | 2021.07.19 |
HTML Table 동적 추가/삭제/조회 (0) | 2021.07.19 |