<canvas id="doughnutChartCanvas"></canvas>
const canvas = document.getElementById("doughnutChartCanvas");
const data = {
labels: ["Red", "Blue", "Yellow"],
datasets: [
{
label: "My First Dataset",
data: [300, 50, 100],
backgroundColor: [
"rgb(255, 99, 132)",
"rgb(54, 162, 235)",
"rgb(255, 205, 86)",
],
hoverOffset: 4,
},
],
};
new Chart(canvas, {
type: "doughnut",
data,
});
const canvas = document.getElementById("doughnutChartCanvas");
const value = 60;
const data = {
datasets: [
{
data: [value, 100 - value],
backgroundColor: ["#e15449", "#ffffff00"],
borderWidth: 0,
borderRadius: 30,
},
],
};
const options = {
cutout: '78%',
}
new Chart(canvas, {
type: "doughnut",
data,
options,
});
이는 canvas element로부터 크기 변화를 감지할 수 없기 때문이라 이야기 하고 있다.
<div class="doughnut-chart" id="doughnutChart">
<canvas id="doughnutChartCanvas"></canvas>
</div>
.doughnut-chart {
position: relative;
width: 200px;
height: 200px;
background: url("./images/doughnutBackground.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
const canvas = document.getElementById("doughnutChartCanvas");
const value = 60;
const data = {
datasets: [
{
data: [value, 100 - value],
backgroundColor: ["#e15449", "#ffffff00"],
borderWidth: 0,
borderRadius: 30,
},
],
};
const options = {
cutout: '78%',
hover: { mode: null },
plugins: {
legend: {
display: false,
},
tooltip: {
enabled: false,
},
},
}
new Chart(canvas, {
type: "doughnut",
data,
options,
});
원하는 endpoint를 canvas에 그려야 하고 해당 endpoint가 animation과 함께 움직여야 한다.
chartjs에서는 animation중일 때 다음과 같은 callback을 지원한다.
canvas 요소에서 애니메이션을 구현하는 방식 (mdn docs)
초기 상태 저장
애니메이션 할 도형을 그림
저장한 시점으로 캔버스 복원
2~4 반복
요약하자면 animation 처럼 보이도록 계속 그리고 지우고를 반복하는 것이다.
그럼 endpoint를 그리려면?
chartjs는 chart를 canvas에 그리기 위해 chart 객체 내에 data를 저장해둔다.
console로 chart 객체를 보자
animation: {
onProgress: function (animation) {
console.log(animation.chart);
},
},
animation: {
onProgress: function (animation) {
console.log(animation.chart.getDatasetMeta(0).data[0]);
},
},
중심(x,y)으로부터 endPoint까지의 길이
각도 계산
중심좌표
endPoint 중심좌표
endPoint canvas 시작좌표
즉, 3번의 좌표에서 endPoint를 그려나가면 된다. 코드로 표현해보자
function drawEndPoint(context, image) {
// endpoint draw
const curChart = context.chart;
const curCtx = context.chart.ctx;
const endPointRad =
curChart.getDatasetMeta(0).data[0].outerRadius / 2 +
curChart.getDatasetMeta(0).data[0].innerRadius / 2; // length from center to endPoint
const er = 23; // endpoint radius (half image size)
// endPoint canvas start point (px, py)
const px =
curChart.getDatasetMeta(0).data[0].x -
endPointRad *
Math.sin(
curChart.getDatasetMeta(0).data[0].circumference - Math.PI
) -
er;
const py =
curChart.getDatasetMeta(0).data[0].y +
endPointRad *
Math.cos(
curChart.getDatasetMeta(0).data[0].circumference - Math.PI
) -
er;
// draw endPoint image to canvas
curCtx.drawImage(image, px, py);
}
위와같이 구현된다.
잘봤어요! 근데 궁금한게 있는데요.. 저도 같이 따라서 해봤는뎅, borderRadius를 줬을 때 각 데이터 간에 borderRadius값이 따로 들어가던데.. 맨 끝쪽에만 값이 들어가는거죠?? 제가 사용한 버전은 4.2.1 이에요!