본문 바로가기
Vue.js

[Vue.js] 16. use doughnut chart with label plugin

by 청양호박이 2021. 3. 30.

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 -

댓글