はじめに
Highchartsは、 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>
上記のコードでは、シリーズのクリックイベントで、setTimeoutを通してマクロタスクを作成し、マクロタスクの中で、getSelectedPointsを使って円グラフの対応する選択ブロックを取得し、現在の選択ブロックを親コンポーネントに出力することで、円グラフの選択ブロックの取得の不正確さの問題を解決しています。
親コンポーネントは
親コンポーネントでPieChartコンポーネントを導入し、onPieChartClickメソッドで処理されるsclickイベントをリッスンします。
<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: 'PieChartBlock1',
y: 50
}
...
]
円グラフブロック id フィルタ
getPieSliceIdList (sliceList) {
const sliceIdList = sliceList.map(function (item) {
return item.id
})
return sliceIdList
}