vue-chartjs를 사용하다 보면, 여러가지 custom하고 싶은 욕구가 생기기 마련입니다. 물론 다른 여러가지 chart를 그려주는 library를 사용할때도 마찬가지 입니다. 오늘은 vue-chartjs 중 doughnut chart를 구현할 때, 적용한 여러가지 항목에 대해서 알아보겠습니다.
0. DoughnutChart.vue 생성하기
기본적으로 vue-chartjs는 component로 구성이 됩니다. 따라서 doughnut chart를 그려주는 vue는 default로 제작하며, dataCollection과 options를 그 props로 지정하여 전달하면 됩니다.
[DoughnutChart.vue]
<script>
import { Doughnut, mixins } from 'vue-chartjs';
export default{
extends: Doughnut,
mixins: [mixins.reactiveProp],
props: ['options'],
mounted() {
this.renderChart(this.chartData, this.options);
},
};
</script>
<style>
</style>
이제 나머지 대다수는 options setting에 따라서 달라지며, 필요한 경우에는 plugin을 추가하여 다양하게 구성이 가능해 집니다. 그럼 차례차례 알아보겠습니다.
1. vue-chartjs doughnut chart basic
우선 기본적으로 dataCollection을 넣고, options를 최소화 할 경우 아래와 같이 나타납니다.
[dataCollection]
doughnutCollection: {
labels: ["A", "B", "C", "D", "E"],
datasets: [
{
borderWidth: 5,
backgroundColor: ["#F48FB1", "#AAAAAA", "#D81B60", "#1E88E5", "#FDD835"],
hoverBackgroundColor: ["#F48FB1", "#AAAAAA", "#D81B60", "#1E88E5", "#FDD835"],
hoverBorderColor: ["#F48FB1", "#AAAAAA", "#D81B60", "#1E88E5", "#FDD835"],
data: [10, 90, 20, 70, 50]
}
],
},
dataCollection은 2가지로 구성이 됩니다. 각 chart구성요소의 labels을 지정하는 labels영역과, 실제 데이터 및 각 데이터의 chart의 색 등을 지정하는 datasets가 그것입니다.
2. doughnut chart options
dataCollection을 통해서 기본적인 doughnut chart는 그려봤으니, 세부적으로 options에 대해서 알아보고 최적화를 해보도록 하겠습니다. 실질적인 options은 어마어마하게 있겠지만, 몇가지를 알아보면 아래와 같습니다.
- responsive: true - default는 true이며, true로 해야 반응형으로 size가 자동으로 조정됨. false로 하면 수동 변경 가능
- maintainAspectRatio: false - default는 true이며, chart의 비율이 유지된 채로 그려진다는 설정. 따라서 true를 유지하면 해당 영역을 벗어나서 chart가 그려지는 문제가 발생함 (아래 예시 참조)
- cutoutPercentage: 값(0~90사이 정수) - default는 50이며, 0에 가까울수록 pie chart가 되고... 90에 가까울수록 doughnut이 얇은 chart가 생성
- legend: { display: true, position: 'top' } - default가 true에 top이고, false 및 bottom / left / right가 가능함
- rotation - doughnut chart 자체를 회전시킴 (Math.PI 의 배수만큼 수행)
- circumference - doughnut chart를 half doughnut으로 만들어 줌 (단, Math.PI * 1 로 구현)
- animation: { duration: 3000, } - doughnut chart가 그려지는 시간을 ms단위로 지정 (예시는 3초 임)
- layout: { padding: 7, } - doughnut chart 자체에 padding을 둠
[maintainAspectRatio: true 의 경우 발생 문제 상황]
[cutoutPercentage: 0 예시]
[legend: { display: true, position: 'bottom', } 예시]
[circumference: 1 * Math.PI 예시]
3. place label text in the center of doughnut chart
pie chart가 아닌 doughnut chart는 중간이 비어있어서 항상 유혹을 느끼곤 합니다. 이 비어있는 중간에 어떻게 text를 추가해서 보여줄 수 있을까?? 라는 질문을 하곤 합니다. 하지만 이는 쉽지 않습니다. 누구는 CSS와 이런저런 방식으로 구현이 가능하다고 하지만... CSS에 약한 개발자는 슬프기 그지 없습니다. 그렇다면....
How to I add label text inside (in the center) the doughnut chart using vue-chartjs or chart.js ??
제가 해결한 방법은, 이를 가능하게 하는 plugin의 추가입니다.
[chartjs-plugin-doughnutlabel]
npm repository에 접근해서 chartjs-plugin-doughnutlabel를 검색해 줍니다.
2년전에 최종 published된 plugin이지만 그래도 주간 다운로드는 5천건 이상 존재합니다. 그럼 이를 설치하기 위해서 package.json내에 dependencies에 아래와 같이 추가해 줍니다.
"dependencies": {
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"axios": "^0.21.1",
"vuetify": "2.4.3",
"chart.js": "2.9.4",
"vue-chartjs": "3.5.1",
"chartjs-plugin-doughnutlabel": "2.0.3"
},
아참!! DoughnutChart.vue에 해당 plugin을 사용하기 위해서 import를 수행해 줍니다.
[DoughnutChart.vue]
<script>
import { Doughnut, mixins } from 'vue-chartjs';
import chartjsPluginDoughnutlabel from "chartjs-plugin-doughnutlabel";
이제 options에 plugins를 추가할 수 있습니다.
[options]
plugins: {
doughnutlabel: {
labels: [
{
text: 'first line',
font: {
size: '30',
weight: 'bold',
}
},{
text: 'total',
font: {
size: '20',
weight: 'bold',
}
},
],
},
},
추가할수록 여러줄이 가능합니다. 구현결과는 아래와 같습니다.
4. display doughnut chart datalabels
기본적으로 vue-chartjs를 통해서 구현한 chart의 경우 각 부분 chart영역에 대해서 몇개의 data로 이렇게 그려졌는지 datalabel을 표시해 주지 않습니다. 해당 chart영역에 마우스를 올려야 tooltips로 제공이 됩니다. 이를 강제로 표현하기 위해서는 역시나 plugin의 추가를 통해서 가능합니다.
[chartjs-plugin-datalabels]
npm repository에 접근해서 chartjs-plugin-datalabels를 검색해 줍니다.
역시나 package.json내에 dependencies에 아래와 같이 추가해 줍니다.
"dependencies": {
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"axios": "^0.21.1",
"vuetify": "2.4.3",
"chart.js": "2.9.4",
"vue-chartjs": "3.5.1",
"chartjs-plugin-doughnutlabel": "2.0.3",
"chartjs-plugin-datalabels": "0.7.0"
},
DoughnutChart.vue에 해당 plugin을 사용하기 위해서 import를 수행해 줍니다.
[DoughnutChart.vue]
<script>
import { Doughnut, mixins } from 'vue-chartjs';
import chartjsPluginDoughnutlabel from "chartjs-plugin-doughnutlabel";
import chartjsPluginDatalabels from "chartjs-plugin-datalabels";
이제 options에 plugins를 추가할 수 있습니다.
[options]
datalabels: {
backgroundColor: function(context) {
return context.dataset.backgroundColor;
},
borderColor: 'white',
borderRadius: 25,
borderWidth: 2,
color: 'white',
display: true,
font: {
weight: 'bold'
},
padding: 6,
formatter: Math.round,
},
여기서 options는 몇가지 설명을 하겠습니다.
- backgroundColor - 기본적으로 각 dataset에 할당된 backgroundColor가 적용됨, 하지만 default로 놔두게 되면 chart 영역을 제외한 나머지 부분에서 label이 잘리게 됨
- borderColor - datalabels가 표시된 영역의 테두리 색 지정
- borderRadius - default는 0이고, 0에 가까워 질 수록 사각형이 되고, 숫자가 커질수록 원의 형태를 띔
- borderWidth - default는 0이고, 1이상을 입력할 경우 해당 두께의 테두리가 생김
- color - datalabels의 색상
- display - default는 true 이며, datalabels의 표시 여부를 지정
- formatter - 표시할 datalabels의 포맷을 지정할 수 있음
해당 기능을 적용하면 아래와 같이 표시가 됩니다.
[backgroundColor 설정안할경우 에러]
5. chartjs-plugin-datalabels의 anchor설정
chartjs-plugin-datalabels를 사용하면, datalabels의 표시 위치를 지정할 수 있는 anchor를 설정할 수 있습니다. 하지만 해당 설정은 options에 들어가지 않고... dataCollection안에 들어갑니다.
[anchor설정]
doughnutCollection: {
labels: ["A", "B", "C", "D", "E"],
datasets: [
{
borderWidth: 5,
backgroundColor: ["#F48FB1", "#AAAAAA", "#D81B60", "#1E88E5", "#FDD835"],
hoverBackgroundColor: ["#F48FB1", "#AAAAAA", "#D81B60", "#1E88E5", "#FDD835"],
hoverBorderColor: ["#F48FB1", "#AAAAAA", "#D81B60", "#1E88E5", "#FDD835"],
data: [10, 90, 20, 70, 50],
datalabels: { anchor: 'end' },
}
],
},
anchor는 datasets안에 data와 같은 level에 설정을 수행하며... end / start로 설정할 수 있습니다.
[anchor: 'end' 적용 예시]
[anchor: 'start' 적용 예시]
이렇게 vue-chartjs로 가능한 많은 것들을 설명해 보았습니다. vue.js를 통한 doughnut chart개발에 도움이 되었으면 좋겠습니다.
- Ayotera Lab -
댓글