129 chart.js 3버전 (이거 많이쓰니깐 잘 알아둬야돼..) (정리중..)
source: categories/study/vue-experiance/vue-experiance_9-99_30.md
129 chart.js 3버전 (이거 많이쓰니깐 잘 알아둬야돼..) (정리중..)
<template>
<div class="canvas_area">
<canvas id="myChart" ref="lineChart" width="400" height="400"></canvas>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { Chart, registerables } from 'chart.js';
import moment from '@/plugins/moment';
Chart.register(...registerables);
export default {
name: 'DeviceChartLine',
props: {
period: {
type: Number,
required: true,
},
},
data() {
return {
myChart: null,
chartData: {
type: 'line',
data: {
labels: [],
datasets: [
// period 48시간 이내
// {
// label: '데이터값',
// backgroundColor: 'rgba(78,118,222,0.3)',
// pointBackgroundColor: '#fff',
// borderWidth: 2,
// borderColor: '#4E76DE',
// pointBorderColor: '#4E76DE',
// data: [40, 85, 90, 20, 60],
// fill: true, // true 일 경우 색상이 채워진다.
// lineTension: 0.4, // 곡선 라인
// pointStyle: ['circle', 'circle', 'crossRot', 'circle', 'circle'],
// },
{
label: '일 평균',
backgroundColor: 'rgba(78,118,222,0.3)',
pointBackgroundColor: '#fff',
borderWidth: 2,
borderColor: '#4E76DE',
pointBorderColor: '#4E76DE',
data: [40, 85, 90, 20, 60],
fill: true, // true 일 경우 색상이 채워진다.
lineTension: 0.4, // 곡선 라인
pointStyle: ['circle', 'circle', 'crossRot', 'circle', 'circle'],
},
{
label: '최소값',
backgroundColor: 'transparent',
borderWidth: 1,
borderDash: [5, 5],
borderColor: '#000',
pointBorderColor: '#000',
data: [10, 10, 10, 10, 10],
pointBackgroundColor: '#fff',
fill: false,
pointRadius: 0,
pointHitRadius: 5,
},
{
label: '최대값',
backgroundColor: 'rgba(78,118,222,0.3)',
pointBackgroundColor: '#fff',
borderWidth: 1,
borderColor: '#C0502A',
pointBorderColor: '#C0502A',
data: [10, 10, 10, 10, 10],
fill: false,
lineTension: 0.4,
},
],
},
options: {
grid: {
display: true,
},
interaction: {
intersect: false,
},
scales: {
yAxes: {
beginAtZero: true,
},
},
plugins: {
legend: {
display: true,
},
tooltip: {
enabled: true,
position: 'nearest',
intersect: false,
alignment: 'center',
custom(tooltip) {
if (!tooltip) {
return;
}
tooltip.displayColors = false;
},
callbacks: {
title(tooltipItem) {
const { label } = tooltipItem[0];
// const { datasetIndex, label } = tooltipItem[0];
// return datasetIndex === 0 ? label : '평균';
return label;
},
},
},
},
},
},
// 측정값 또는 일평균
dataSetType1: {
label: '',
backgroundColor: 'rgba(78,118,222,0.3)',
pointBackgroundColor: '#fff',
borderWidth: 2,
borderColor: '#4E76DE',
pointBorderColor: '#4E76DE',
data: [],
fill: true, // true 일 경우 색상이 채워진다.
lineTension: 0.4, // 곡선 라인
pointStyle: ['circle', 'circle', 'crossRot', 'circle', 'circle'],
},
// 최소값
dataSetType2: {
label: '',
backgroundColor: 'transparent',
borderWidth: 1,
borderDash: [5, 5],
borderColor: '#000',
pointBorderColor: '#000',
data: [],
pointBackgroundColor: '#fff',
fill: false,
pointRadius: 0,
pointHitRadius: 5,
},
// 최대값
dataSetType3: {
label: '',
backgroundColor: 'rgba(78,118,222,0.3)',
pointBackgroundColor: '#fff',
borderWidth: 1,
borderColor: '#C0502A',
pointBorderColor: '#C0502A',
data: [],
fill: false,
lineTension: 0.4,
},
};
},
computed: {
...mapGetters('info', [
'deviceChartDataList',
'deviceChartMaxDataList',
'deviceChartMinDataList',
]),
},
watch: {
deviceChartDataList() {
this.setChartData();
this.initChart(this.$refs.lineChart, this.chartData);
},
},
beforeDestroy() {
// 차트 정보 삭제
if (this.myChart) {
this.myChart.destroy();
}
},
mounted() {
this.setChartData();
this.initChart(this.$refs.lineChart, this.chartData);
},
methods: {
initChart(ref, chartData) {
const ctx = ref.getContext('2d');
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, 'rgba(78,118,222,0.3)');
gradient.addColorStop(1, 'rgba(78,118,222,0.3)');
this.chartData.data.datasets[0].backgroundColor = gradient;
if (this.myChart) {
this.myChart.destroy();
}
this.myChart = new Chart(ctx, {
type: chartData.type,
data: chartData.data,
options: chartData.options,
});
},
setChartData() {
const keys = this.deviceChartDataList.map(item => item.name);
const values = this.deviceChartDataList.map(item => item.value);
const dataList = values.map(item => (item !== '' ? item : 0));
const maxValues = this.deviceChartMaxDataList.map(item => item.value);
const maxDataList = maxValues.map(item => (item !== '' ? item : 0));
const minValues = this.deviceChartMinDataList.map(item => item.value);
const minDataList = minValues.map(item => (item !== '' ? item : 0));
const pointStyle = values.map(item =>
item !== '' ? 'circle' : 'crossRot',
);
if (this.period < 2) {
this.chartData.data.labels = keys.map(item =>
moment.getConvertFormat(item, 'MM/DD HH:mm'),
);
this.$set(this.chartData.data, 'datasets', [
{
...this.dataSetType1,
label: '측정값',
pointStyle,
data: dataList,
},
]);
} else {
this.chartData.data.labels = keys.map(item =>
moment.getConvertFormat(item, 'MM/DD'),
);
this.$set(this.chartData.data, 'datasets', [
{
...this.dataSetType1,
label: '일 평균',
pointStyle,
data: dataList,
},
{
...this.dataSetType2,
label: '최소값',
data: minDataList,
},
{
...this.dataSetType3,
label: '최대값',
data: maxDataList,
},
]);
}
},
},
};
</script>
<style></style>