아파트 실거래 내역을 이용해 아파트 거래가 변경 추이를 한눈에 볼 수 있도록 차트를 넣기로 했다.
데이터만 준비 되어있다면 간편하게 시각화를 시켜주는 chart.js 라이브러리를 사용하였다.
프로젝트 Vue 버전 : 2.6.14
Chart.js | Open source HTML5 Charts for your website
New in 2.0 New chart axis types Plot complex, sparse datasets on date time, logarithmic or even entirely custom scales with ease.
www.chartjs.org
시작하기
npm 으로 설치해서 불러올 수도 있지만 간단하게 cdn방식으로 사용하였다.
vue 프로젝트의 public/index.html의 head에 chart.js cdn을 삽입해준다.
//public/index.html
<!-- chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
차트 그릴 공간 지정
html 태그 삽입 : chart를 그릴 영역에 canvas 넣기.
id는 꼭 chart로 지정 해 주어야 한다.
<canvas id="chart" width="350" height="350"></canvas>
js 에서 canvas 객체 가져오기
차트를 그릴 컴포넌트가 마운트 되면 canvas 객체를 가져와서 data에 저장 해 둔다.
...
data() {
return {
context: null,
};
},
...
mounted() {
this.context = document.getElementById("chart");
},
chart 설정
모양 설정
새로운 Chart 객체를 생성하고 설정들을 입력 해 준다.
선형 차트로 생성할 것이기 때문에 line차트로 생성했다.
차트 타입은 chart.js 페이지에 가면 확인 가능하다.
차트의 세로축이 0부터 시작하길 위해서 옵션에서 beginAtZero: true 설정을 주었다.
그래프의 선 아래부분에 색을 채우기 위해 fill:"start" 옵션 설정.
그 외 배경 색과 선 색을 지정해주었다.
const myChart = new Chart(this.context, {
type: "line",
data: {
datasets: [
{
label: "# of ",
data: 데이터 생성 함수에서 리턴해줄 것
backgroundColor: ["rgba(54, 162, 235, 0.2)"],
borderColor: ["rgba(75, 192, 192, 1)"],
borderWidth: 1,
fill: "start",
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
데이터 설정
데이터의 레이블과 값들을 labels,data로 분리 해서 입력할 수도 있지만
data에 {x:레이블, y:값} 으로 구성된 오브젝트 배열을 넣어주면 알아서 차트를 그려준다.
차트에 넣을 데이터를 만들기 위해 배열을 리턴하는 makeData()함수를 만들었다.
makeData() {
let labels = [];
this.deals.forEach((deal) => {
labels.push({
x: deal.dealYear + "." + deal.dealMonth, // 레이블
y: parseInt(deal.dealAmount.split(",").join("")), //데이터
});
});
return labels; // 과거 -> 최신순으로 보여주기 위해서 reverse
},
이 함수에서 리턴한 것을 차트 설정의 data값으로 넣어주면 된다.
const myChart = new Chart(this.context, {
type: "line",
data: {
// labels: this.makeLables(this.deals),
datasets: [
{
label: "# of ",
data: this.makeData(),
backgroundColor: ["rgba(54, 162, 235, 0.2)"],
borderColor: ["rgba(75, 192, 192, 1)"],
borderWidth: 1,
fill: "start",
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
차트 생성 함수 실행
차트를 그릴 컴포넌트가 마운트 되면 차트를 생성하는 함수를 실행하도록 한다.
mounted() {
this.context = document.getElementById("chart");
this.makeChart();
},
전체 코드
// DealChart.vue
<template>
<div class="">
<canvas id="chart" width="350" height="350"></canvas>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "DealChart",
computed: {
...mapState("houseStore", ["deals"]),
},
data() {
return {
context: null,
};
},
methods: {
makeData() {
let labels = [];
this.deals.forEach((deal) => {
labels.push({
x: deal.dealYear + "." + deal.dealMonth,
y: parseInt(deal.dealAmount.split(",").join("")),
});
});
return labels.reverse(); // 과거 -> 최신순으로 보여주기 위해서 reverse
},
makeChart() {
const myChart = new Chart(this.context, {
type: "line",
data: {
// labels: this.makeLables(this.deals),
datasets: [
{
label: "# of ",
data: this.makeData(),
backgroundColor: ["rgba(54, 162, 235, 0.2)"],
borderColor: ["rgba(75, 192, 192, 1)"],
borderWidth: 1,
fill: "start",
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
},
},
mounted() {
//console.log("chart");
this.context = document.getElementById("chart");
//console.log(this.context);
this.makeChart();
},
};
</script>
<style></style>
차트 데이터를 변경해야 할 때
html의 canvas태그를 가져와서 차트 객체를 생성 하는데, 한번 사용한 canvas를 사용해 새롭게 new Chart를 하면 에러가 난다.
데이터를 변경하려고 한다면 chart.js 에서 제공하는 방법을 사용해야 한다.
https://www.chartjs.org/docs/latest/developers/updates.html
하지만..
내가 한 프로젝트의 경우 데이터를 따로 조작할 일은 없었기 때문에 이런식으로 데이터를 변경해 줄 필요는 없었다.
그냥 차트를 보여주는 ui를 닫으면 destroy 됐다가 열면 새롭게 created 됐기 때문에 계속 새로운 차트를 생성 하면 됐다.