03.업/15.Vue.js
lineChart 작업
봄날의차
2023. 10. 25. 13:31
chart.js 3.0.0버전으로 설치 후 vue2.6으로 작업
데이터쿼리 조회는 springboot로 작업
파일1 D:***\bidCalCre.vue
파일2 D:***\bidCalLineChart.vue
>>파일1
1.vue <template></template>
<!-- 그래프 -->
<div class="flex flex-col mx-auto" style="width: 1168px;">
<div class="flex mt-2 mb-5">
<p>*변동율 추이 line</p>
</div>
<table>
<tr>
<td>
<chart :list_dat_avg="list_dat_avg_line" />
<!--
bidCalLineChart.vue 참조파일에서 호출할 데이터 값 지정
list_dat_avg 호출할 속성변수명
-->
</td>
</tr>
</table>
</div>
<!-- 그래프 끝 -->
2.script
<script lang="ts">
import Vue from 'vue'
// 1.참조페이지 호출
import chart from '~/bidCalLineChart.vue'
..
// 2.컴포넌트 호출
components: {
chart
},
// 3.data로 지정:전역변수지정 LIST_DAT_AVG 계산시 활용할 변수로 지정해서 사용함...list_dat_avg_line를 이용해서 지정없이 해도 될까..?
data(){
...
, LIST_DAT_AVG: [] as any
, list_dat_avg_line: [] as any
...
}
// 4.페이지로드시에 실행선그래프를 위한 계산을 호출 해서 선그래프를 그린다.
mounted () {
...
this.getDatAvgList(); // 선그래프를 위한 계산
...
}
// 5.선그래프를 위한 계산 : springboot 호출
async getDatAvgList(){ //
this.LIST_DAT_AVG = [] ; // 초기화
const res_list_dat_avg = await this.$axios.post('/***/getDatAvgList', this.BasBidInf );
this.LIST_DAT_AVG = res_list_dat_avg.data;
this.initializeLineData() ; // 선그래프호출
},
// 6.선그래프 작성
initializeLineData() { //getDatAvgList
// 데이터를 1부터 12까지 생성하여 rows 배열에 할당
this.list_dat_avg_line = [];
let len = this.LIST_DAT_AVG.length;
if(this.LIST_DAT_AVG && Array.isArray(this.LIST_DAT_AVG) && this.LIST_DAT_AVG.length > 0 ){
//데이터맵핑
for(let i=1;i<=len; i++){
if(i<=this.LIST_DAT_AVG.length){
this.list_dat_avg_line.push({
id: i,
ym: this.LIST_DAT_AVG[i-1].YM,
avg_con_amo: this.LIST_DAT_AVG[i-1].AVG_CON_AMO
})
} else {
this.list_dat_avg_line.push({
id: 1,
ym: '',
avg_con_amo: 0
});
}
}
} else {
for (let i = 1; i <= len; i++) {
this.list_dat_avg_line.push({
id: 1,
ym: '',
avg_con_amo: 0
});
}
}
},
>>파일2
// 1.canvas 설정 id
<template>
<div class="line_chart">
<canvas id="lineChart" width="60" height="60"></canvas>
</div>
</template>
// 2.chart.js 참조
<script lang="ts">
import Vue from "vue";
import { Chart, registerables } from "chart.js";
Chart.register(...registerables);
// 3.list_dat_avg lineChart 데이터 속성 추가
// data에lineChart 프로퍼티 전역변수 추가: rowList, lineChart
// watch에list_dat_avg이 변경될 때 실행되는 로직과 새로운 데이터로 차트 업데이트 등의 로직 추가
// mounted에데이터 맵핑과 새로운 데이터로 차트 업데이트로직추가: this.rowList = this.list_dat_avg; 데이터 맵핑 this.updateChart(); 새로운 데이터로 차트 업데이트
// beforeDestroy : 챠트새로그리기 위해 destroy시킨다.
// renderChart updateChart 구현
export default Vue.extend({
//name: 'LineChart',
props: {
list_dat_avg: { // lineChart 데이터 속성 추가
type: Array,
required: true,
},
},
data() {
return {
rowList: [] as any,
lineChart: null as Chart | null, // lineChart 프로퍼티 전역변수 추가
};
},
watch: {
list_dat_avg: {
handler(newRows) {
// list_dat_avg이 변경될 때 실행되는 로직
this.rowList = newRows;
// 새로운 데이터로 차트 업데이트 등의 로직을 수행할 수 있습니다.
this.updateChart();
},
deep: true,
immediate: true, // 컴포넌트가 마운트될 때도 실행
},
},
mounted() {
this.rowList = this.list_dat_avg;
this.updateChart();
},
beforeDestroy(){
if (this.lineChart) {
this.lineChart.destroy();
}
},
methods: {
renderChart() {
const canvas = document.getElementById('lineChart') as HTMLCanvasElement;
if (!canvas) {
console.error("Canvas element not found");
return;
}
const ctx = canvas.getContext('2d');
if (!ctx) return;
// 데이터맵핑
const labels = this.rowList.map((d) => d.ym);
const data = this.rowList.map((d) => d.avg_con_amo);
this.lineChart = new Chart(ctx, {
type: 'line',
data: {
labels,
datasets: [{
label: 'Average Data',
data,
fill: false,
borderColor: 'rgb(75, 192, 192)',
}],
},
options: {
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
},
},
},
});
},
// 기존 차트 인스턴스를 파괴한 후 Vue의 nextTick 함수를 사용하여 DOM 업데이트 사이클이 완료될 때까지 기다립니다
async updateChart() {
if (this.lineChart) {
this.lineChart.data.labels = this.rowList.map((d) => d.ym);
this.lineChart.data.datasets[0].data = this.rowList.map((d) => d.avg_con_amo);
this.lineChart.update();
} else {
this.renderChart();
}
},
},
});
</script>
<style scoped>
.line_chart {
width: 1160px;
height: 400px;
}
</style>