[Vue.js] HighCharts 조건에 따른 레이블(Lable) 표기 방법 : 수치가 0인 값을 제거 하고 싶다면?
하이차트에서 레이블 표기시 조건에 따라 표기해야하는 경우가 있다, 가령 수치가 0인 값들은 표기하고 싶지 않다면 어떻게 해야할까? 데이터를 변조하는 방법과 하이차트에서 제공하는 포멧터 펑션을 이용하는 방법이 있다.
Vue.js에서 highcharts의 프로퍼티는 다음과 같다.
Parameter | Type | 필수여부 | Description |
:options | Object | yes | Highcharts chart configuration object |
:constructor-type | String | no | Chart constructor type using to init specific chart. Allowed options: ‘chart’, ‘stockChart’, ‘mapChart’. First one is set for default. |
:callback | Function | no | Function passed as a callback during chart init, and triggered when chart is loaded. |
:updateArgs | Array | no | Array of update()’s function optional arguments. Parameters should be defined in the same order like in native Highcharts function: [redraw, oneToOne, animation]. Here is a more specific description of the parameters. |
:highcharts | Object | no | A specific Highcharts instance. It’s useful when required to build charts using different Highcharts versions. |
:deepCopyOnUpdate | Boolean | no | Whether to make a deep copy of object passed to Chart.update() function. In order to avoid passing references of arrays, it’s set to true by default.
NOTE: That can cause a decrease of performance while processing a big amount of data, because copying source data is much expensive, and then it’s recommended to disable that option by setting it to false. |
[main.js] 에 하이차트를 임포트하여 프로젝트 내에서는 어디에서든 사용할 수 있게 되어있다.
import Vue from 'vue';
import HighCharts3D from 'highcharts/highcharts-3d';
import HighCharts from 'highcharts';
HighCharts3D(HighCharts);
...........
다음은 하이차트를 사용중인 통계페이지 샘플 코드 스니펫이다.
<template>
<v-layout class="ubs-pannel bg-white bd-none mb15" row wrap>
<v-flex>
<div class="ml15 mr15">
</div>
<highcharts :options="options" ref="highcharts" class="mt15 mb15" />
</v-flex>
</v-layout>
</template>
import _ from 'lodash';
import moment from 'moment';
import { Chart } from 'highcharts-vue';
import { json2excel } from 'js2excel';
export default {
name: 'UserGoal',
components: {
highcharts: Chart,
},
data: () => ({
customQuery: {
yyyymm: '',
month: '2',
searchPerm: '',
isShow: false,
},
gridList: {
goalHeader: [],
goalList: [],
},
codeList: {
deptList: [],
},
isDatePickerStart: false,
dataOptions: {
chart: {
type: 'column',
// options3d: {
// enabled: true,
// alpha: 15,
// beta: 15,
// depth: 50,
// viewDistance: 25,
// },
},
title: {
text: '',
x: -20, // center
},
subtitle: {
text: '',
x: -20,
},
xAxis: {
// categories: ['202101', '202102', '202103', '202104', '202105'],
categories: [],
},
yAxis: {
min: 0,
title: {
text: '',
},
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
// format: '{point.y:,.1f}',
formatter: function () {
if (this.y > 1) {
return this.y;
}
},
color: '#000000',
style: {
textShadow: false,
textOutline: false,
},
},
},
},
tooltip: {
valueSuffix: '',
},
legend: {
// layout: 'vertical',
align: 'center',
verticalAlign: 'bottom',
borderWidth: 0,
},
series: [{
name: 'SPRING',
data: [],
color: '#00a3f1',
}, {
name: 'SUMMER',
data: [],
color: '#f66b6e',
}, {
name: 'AUTUMN',
data: [],
color: '#ffaa00',
}],
},
}),
async created() {
},
mounted() {
this.onResizeHandler();
},
methods: {
onResizeHandler() {
const currWidth = window.innerWidth;
if (currWidth < 600) {
this.customQuery.month = '3';
} else if (currWidth >= 600 && currWidth < 1264) {
this.customQuery.month = '5';
} else if (currWidth >= 1264) {
this.customQuery.month = '12';
}
},
clearData() {
this.dataOptions.xAxis.categories = [];
this.dataOptions.series[0].data = [];
this.dataOptions.series[1].data = [];
this.dataOptions.series[2].data = [];
},
selectStatusView() {
this.clearData();
if (this.statusValidation()) {
const param = {
ac: 'SELECT_CONTROLLER',
workType: 'SEARCH',
yyyymm: this.customQuery.yyyymm.replace(/-/gi, ''),
month: this.customQuery.month,
};
this.axiosCall(param).then((rs) => {
if (rs.data.errorCode === 'MSG0001' || rs.data.errorCode === 'MSG0006') {
const dataRow = rs.data.resultList;
const xName = dataRow[0];
xName.forEach((e) => {
this.options.xAxis.categories.push(e.CUST_NAME);
});
const dataSeries = dataRow[1];
dataSeries.forEach((e) => {
if (e.ACT_CD === '10') this.options.series[0].data.push((e.CNT > 0 ? e.CNT : ''));
if (e.ACT_CD === '20') this.options.series[1].data.push((e.CNT > 0 ? e.CNT : ''));
if (e.ACT_CD === '30') this.options.series[2].data.push((e.CNT > 0 ? e.CNT : ''));
});
this.gridList.goalHeader.push({ text: '구분', value: 'TYPE', align: 'left' });
xName.forEach((e) => {
this.gridList.goalHeader.push({ text: e.CUST_NAME, value: e.S_DATE, align: 'center' });
});
const grdList = dataRow[2];
this.gridList.goalList = grdList;
this.renderChart();
}
});
}
},
renderChart() {
this.$refs.highcharts.chart.credits.update();
},
},
};
</script>
HighCharts 공식 API 레퍼런스
[방법 1]
엑시오스(axios)를 사용하여 서버로 부터 데이터를 받아 온 후 데이터를 담을 때 값이 0인 경우 빈값으로 치환해준 후 데이터를 담게 되면 차트에서 레이블 표기시 0인 경우 값을 표기 하지 않도록 할 수 있다. 테스트 결과 동작은 정상이다.
const dataRow = rs.data.resultList;
const xName = dataRow[0];
xName.forEach((e) => {
this.options.xAxis.categories.push(e.CUST_NAME);
});
const dataSeries = dataRow[1];
dataSeries.forEach((e) => {
if (e.ACT_CD === '10') this.options.series[0].data.push((e.CNT > 0 ? e.CNT : ''));
if (e.ACT_CD === '20') this.options.series[1].data.push((e.CNT > 0 ? e.CNT : ''));
if (e.ACT_CD === '30') this.options.series[2].data.push((e.CNT > 0 ? e.CNT : ''));
});
이 방법이 싫다면 highCharts에서 제공하는 포멧터 함수를 이용하라
[방법 2]
plotOptions 필터안에 dataLabels필터가 있다. 여기에서 formatter 필터 선언 후 함수를 구현처리한다.
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter: function () {
if (this.y > 1) {
return this.y;
}
},
color: '#000000',
style: {
textShadow: false,
textOutline: false,
},
},
},
},
Vue에.js서 이용할 수 있는 차트들이 많이 있다.
[참고]
[이런 처리도 필요하다면?]