前言
Highcharts 通过 getSelectedPoints API 获取图表选中的点。在 Vue 项目中使用时发现,基于 Highcharts 封装的饼图组件,直接调用 getSelectedPoints 无法准确地获取到当前选中的饼图块的点的集合。
基于 Highcharts 封装的饼图组件
<template>
<div class="pie-chart"></div>
</template>
<script>
import { chartMixin } from '@/mixin/chart_mixin'
var Highcharts = require('highcharts')
export default {
name: 'PieChart',
mixins: [chartMixin],
props: {
series: {
type: Array,
required: true
}
},
data: function () {
return {
pieChartRef: undefined,
seriesData: []
}
},
methods: {
initChart () {
const self = this
this.pieChartRef = Highcharts.chart(this.$el, {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: null
},
credits: {
enabled: false
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
}
},
series: {
events: {
click: function (event) {
// 通过 setTimeout 创建宏任务,在宏任务中通过 getSelectedPoints 获取饼图块 id
setTimeout(() => {
self.$emit('sclick', self.pieChartRef.getSelectedPoints())
}, 0)
}
}
}
},
series: [{
name: '占比',
colorByPoint: true,
data: [
{
name: 'text',
y: 10.84
}
]
}]
})
this.initChartRef(this.pieChartRef)
},
updateChartData (data) {
this.pieChartRef.series[0].update({
data: data
})
},
getSelectedSliced () {
return this.pieChartRef && this.pieChartRef.getSelectedPoints()
}
},
watch: {
series: {
immediate: true,
deep: true,
handler (newVal) {
this.seriesData = newVal
setTimeout(() => {
this.updateChartData(this.seriesData)
this.pieChartRef.reflow()
}, 5)
}
}
},
mounted: function () {
this.initChart()
setTimeout(() => {
this.pieChartRef.reflow()
}, 5)
}
}
</script>
在上述代码中,在 series 的点击事件中,通过 setTimeout 创建一个宏任务,并在宏任务中通过 getSelectedPoints 来获取对应的饼图选中块,并向父组件 emit 当前的选中块,这样就可以解决获取饼图选中块失准的问题。
父组件中使用
在父组件中,引入 PieChart 组件,并监听 sclick 事件,通过方法 onPieChartClick 进行处理。
<PieChart
ref="piechart"
@sclick="index => onPieChartClick(index)"
:series="getPieChartData(tab.key)"/>
事件监听处理
onPieChartClick (sliceList) {
this.sliceList = sliceList
setTimeout(() => {
const sliceIdList = this.getPieSliceIdList(sliceList)
if (sliceIdList.length > 0) {
this.$set(this.btnDisabledList, this.tabIndex, false)
} else {
this.$set(this.btnDisabledList, this.tabIndex, true)
}
}, 150)
}
在事件处理中,需要筛选饼图块的 id 值集合。饼图块中原始的选中集合,格式类似如下:
[
{
id: 1
name: '饼图块1',
y: 50
}
...
]
饼图块 id 筛选
getPieSliceIdList (sliceList) {
const sliceIdList = sliceList.map(function (item) {
return item.id
})
return sliceIdList
}