Front-end/Vue.js

Vue) Vue3 그래프 그리기 chart.js 적용 방법. 막대그래프, 꺽은선그래프

luana_eun 2023. 9. 8. 17:00
728x90

Vue 프로젝트에 데이터 시각화를 위해 그래프를 붙이고 싶었다. 

찾아보니 chart.js 가 있었고, 제일 많이 추천하는 오픈 소스 라이브러리였다. 

 

- 무료

- Js, HTML5, Canvas 기반

- 반응형 지원

이 세가지만 봐도 사용하기 충분했다. 

 

사이트 : https://www.chartjs.org/

 

Chart.js

Simple yet flexible JavaScript charting library for the modern web

www.chartjs.org

 

 

 

1. chart.js 설치하기

npm install chart.js

 

pakage.json 에 가서 버전을 확인하자. 버전을 따로 지정하지 않았으면 아마 최신버전이 설치됐을것이다. 

나는 4.4.0이다. 

 

 

 

2. 기본 Bar 차트 만들어보기

우선 공식문서에서 기본으로 제공하는 차트를 만들어보자.

하.. 진짜 차트만드는데 엄청나게 삽질했다. 

<template>
  <div>
      <h1>Demo example</h1>
      <canvas id="myChart"></canvas>
  </div>
</template>

<script>
import Chart from 'chart.js/auto';
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js'

ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend )

export default {

  , mounted() {
    const ctx = document.getElementById('myChart');

    const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
  
}
</script>

와 너무 잘나온다..

처음에 블로그 찾아가며 삽질해서 온갖오류를 만났는데, 너무 간단했어서 약간 허무..ㅋㅋㅋㅋ

위에 type을 line으로 바꾸면 선 그래프로도 잘 나온다. 

 

 

 

3. 함수와 변수로 데이터 분리하기

데이터는 서버에서 받아와서 바뀌므로 변수화 하고, mounted에 있는것을 함수로 뺐다. 

<template>
  <div>
      <h3>Line Chart</h3>
      <canvas id="myChart"></canvas>
  </div>
</template>


<script>
import Chart from 'chart.js/auto';
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js'

ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend )

export default {
  data() {
    return {
      chartLabels : ['월', '화', '수', '목', '금', '토', '일']
      , chartData : [
          {
            type: 'line',
            label: '책읽기',
            data: [12, 19, 3, 5, 2, 3],
            borderWidth: 1
          }
      ]
    }
    
  } 

  , mounted() {
    this.makeChart();
  },

  methods : {

    makeChart() {
      const ctx = document.getElementById('myChart');
      
      new Chart(ctx, {
        data: {
          labels: this.chartLabels
          , datasets: this.chartData
        },
        options: {
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }

  }

 

 

 

 

 

4. 기타 꾸미기

위에 chart.js 사이트에 들어가보면 문서가 엄청 잘 나와있다. 정말 초보가 봐도 바로 따라할 수 있을만큼

그래프 선의 색깔도 바꿀 수 있고, 글자 색상 등등 원하는대로 커스텀 할 수 가 있다. 

 

 

우선 멀티로 두개 정도 그래프를 하고싶어서 데이터를 하나 더 추가하고

, chartData : [
          {
            type: 'line'
            ,label: '책읽기'
            ,data: [12, 19, 3, 5, 2, 3]
            ,borderWidth: 2
          }
          , {
            type: 'line'
            ,label: '운동'
            ,data: [20, 15, 3, 10, 5, 2, 1]
            ,borderWidth: 1
          }
      ]

 

 

라벨 위치랑 선 색깔을 바꿔봤다. 

 , chartData : [
      {
        type: 'line'
        , label: '책읽기'
        , data: [12, 19, 3, 5, 2, 3]
        , borderWidth: 2
        , backgroundColor : 'lightblue'
        , borderColor : 'lightblue'
      }
      , {
        type: 'line'
        , label: '운동'
        , data: [20, 15, 3, 10, 5, 2, 1]
        , borderWidth: 1
        , backgroundColor : 'purple'
        , borderColor : 'purple'
      }
 ]
options: {
  scales: {
    y: {
      beginAtZero: true
    }
  }

  , plugins : {
    legend : {
      position: 'bottom'
    }
  }
}

 

좋아 성공!!!

 

하면서 여러가지 오류를 만났었는데

오류1) this.renderChart is not a function

renderChart 이 함수를 쓰는건 예전 버전이라고 한다. (어떤 버전인지 봤던거 같은데 기억이 안남)

vue3에 chart.js 4버전대를 쓰고있는 나는 해당 안되는 방법이었다. 

 

 

오류2) Data 가 object 형태로 들어감

 

 

오류3) undefined labels 라벨을 못찾는다고... 이것도 버전이 맞지 않는 방법을 해서가 문제였다. 

위에 방법으로 문서대로 하니 문제 없이 차트가  잘 나온다. 

 

 

이 글이 도움이 되었으면 공감 부탁드립니다!! :)

728x90