Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

이것저것

Vue3 Composition API로 개발하기 - 차트 편 본문

Vue

Vue3 Composition API로 개발하기 - 차트 편

씨씨상 2023. 6. 30. 12:00

Vue를 사용해 개발하면서 제가 가장 열이 받았던 부분입니다.

"차트"

별 것 아닌 것 같지만, 누구나 한 번 쯤은 꼭 사용해야 하고, 꼭 필요한 존재.

결론부터 말하자면, 저는 제가 직면한 문제를 풀지 못했기 때문에,
며칠동안 고생하다가 결국 척척박사님께 도움을 받았습니다.
이해만 하면 간단합니다.

 

병아리를 놀리는 고인물

 

 


시작
그동안 자바스크립트로 통계를 보여주기 위해,
우리는 Chart.js라고 하는 훌륭한 라이브러리를 사용해 왔습니다.
그리고 저 같은 병아리 개발자들을 위해서
Vue에서도 Chart.js를 사용할 수 있도록 훌륭한 분들이 이미 손을 써두었습니다.
우리는 그걸 설치하기만 하면 되는 겁니다.

 

npm install vue-chartjs chart.js
공식문서 https://vue-chartjs.org/

 


참고로 Vue3에서 사용하기 위해서는 vue-chart-3 라이브러리가 아니라
반드시 vue-chartjs를 사용해야 합니다.
저는 이걸 몰라서 정말 많은 삽질을 했으니 여러분들은 그러지 마시기 바랍니다.
삽질은 한 사람으로 충분합니다.

참고자료 https://github.com/apertureless/vue-chartjs/issues/695

 


그러나, 공식문서를 아무리 뒤져보아도,
Composition API의 setup 안에서 실행되는 형태의 코드는 없었습니다.

지금 생각해보면 정말 바보 같은 생각이고, 응용만 하면 쉽게 해결할 수 있는데,
병아리 개발자는 그 응용력이 부족하기 때문에
검색 혹은 노가다로 해결해야 하는 상황이었습니다.

 

 

 

세팅
설치를 마쳤으면 차트를 사용하기 위해 import 해줍시다.
이 부분은 Chart.js의 공식문서에도 친절하게 나와 있는 부분입니다.
저는 꺾은선 그래프와 막대 그래프, 이렇게 두 가지를 사용하고 싶었기 때문에
Line과 Bar 컴포넌트를 추가해 주었습니다.

 

import { Line, Bar } from 'vue-chartjs';
import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement, LineElement, PointElement, CategoryScale, LinearScale } from 'chart.js';

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

 

 

 

적용

import를 했으면 template에도 이 컴포넌트들을 추가해 줍시다.
아, 당연하지만, script export default에도 components를 추가해주는 걸 잊지 마시고요.

저는 탭을 클릭하면 차트를 변경해서 보여주고 싶어서 activeTab이라는 것을 따로 만들었지만,
필요없으신 분은 :class를 지워주세요.

 

export default {
  components: {
    Line,
    Bar,
  },
}
<div class="card-body">
	<div class="tab-content p-0">
		<div class="chart tab-pane" :class="activeTab === 0 ? 'active' : ''">
			<Line />
		</div>
		<div class="chart tab-pane" :class="activeTab === 1 ? 'active' : ''">
			<Bar />
		</div>
	</div>
</div>

 

이렇게만 넣으면 차트에 데이터가 없기 때문에 당연히 아무 것도 나오지 않습니다.
저는 서버에서 api로 받아온 데이터를 통계로 만들어 주고 싶었던 것이기 때문에,
서버에서 받아온 데이터를 반응성 데이터로 만들어서 값을 넣어주겠습니다.

 

const xData = ref([]);
const yData = ref([]);

const getData = function () {
	const xArr = [];
	const yArr = [];

	axios.get('your request URL')
	.then(function (response) {
  		if (response !== undefined) {
			for (let i = 0; i < response.data.length; i++) {
				const obj = response.data[i];
				xArr.push(obj.x);
				yArr.push(obj.y);
			}
			xData.value = xArr;
			yData.value = yArr;
		}
	})
	.catch(function (error) {
		console.log(error);
	});
};

 

데이터를 가공할 때 중요한 것은,

for문 안에서 xData.value나 yData.value에 직접적으로 response data를 넣어서는 안된다는 것입니다.
vue-chartjs는 새 데이터나 새 옵션이 전달되면 차트를 업데이트하거나 다시 렌더링하는데,
데이터를 하나하나 바꾸면 렌더링이 많이 일어나서 동작하지 않는 것처럼 보이기 때문입니다.

이것도 역시 공식 문서에 있습니다.

Updating Chart https://vue-chartjs.org/guide/#updating-charts

 

 

그럼 이제 가공한 데이터를 바인딩 해줍시다.

저의 경우 label이 하나만 있으면 되기 때문에 하드코딩 해주었습니다.

 

<div class="card-body">
	<div class="tab-content p-0">
		<div class="chart tab-pane" :class="activeTab === 0 ? 'active' : ''">
			<Line :data="data" :options="option" />
		</div>
		<div class="chart tab-pane" :class="activeTab === 1 ? 'active' : ''">
			<Bar :data="data" :options="option" />
		</div>
	</div>
</div>
const data = computed(function () { 
	return {
		labels: xData.value,
		datasets: [
			{
				label: 'labal data',
				borderWidth: 1,
				borderColor: 'your favorite color',
				backgroundColor: 'your favorite color',
				data: yData.value
			}
		]
	}
});
const option = {
	responsive: true,
	maintainAspectRatio: false,
};

 

 

 

완성

끝~ 제가 완성한 차트는 이렇습니다.

 

완성된 차트

 

하루빨리 Composition API로 개발하는 사람이 많아지길 바랍니다.

병아리 개발자도 먹고 살고 싶습니다.

'Vue' 카테고리의 다른 글

Option API와 Composition API  (0) 2023.07.03
Vue 삽질 일기  (0) 2023.06.19