はじめに
以前書いたNuxtでChart.jsを利用するで実装したdoughnut-chart
にて、hover時とレンダリング完了時にそれぞれイベントが発行されるよう改修しました。
hoverイベントを発行
doughnut-chart
はChart.jsのDoughnut Chart
を利用しており、hover時に処理を実行するためにはoptions.onHover
にコールバック関数を渡すことで可能となります。
https://www.chartjs.org/docs/latest/general/interactions/events.html
そのため、doughnut-chart
ではコールバック関数をコンポーネントのメソッドとして実装し、renderChart時にonHoverプロパティの値として定義することとしました。
// ・・・省略
mounted() {
this.renderChart(this.chartData, { onHover: this.hover, ...this.options });
},
methods: {
hover: function(point, event) {
const element = event[0] || null;
if (element === null) {
return;
}
this.$emit('hover', element._index);
},
},
});
実装したhover
メソッドでは2つの引数point
とevent
を受け取り、これらにはそれぞれMouseEvent
とChartElement
が渡されます。
ChartElement
にはlabelやvalueをはじめとするChart情報が含まれており、今回はその中のindex
情報を利用することとしました。
this.$emit
にてカスタムイベントを発行することが可能なため、hoverイベントを発行しindex
を返却しております。
<template>
<v-container fluid>
<doughnut-chart :chart-data="chartData" :options="chartOptions" @hover="hover"/>
// ・・・省略
</v-container>
</template>
<script>
// ・・・省略
methods: {
// ・・・省略
hover: function(index) {
console.log(index);
},
},
};
</script>
doughnut-chart
にてhoverイベントを発行するよう実装したため、呼び出し側からは上記のようにevent handlerをメソッドにて実装し、@hover="event handler名"
にてイベントを受け取ることが可能となります。
renderedイベントを発行
次にレンダリングが完了した際にイベントを発行するようdoughnut-chart
を改修します。
Chart.jsのDoughnut Chart
では、options.animation.onComplete
にコールバック関数を渡すことでレンダリング完了時に処理を実行することが可能です。
https://www.chartjs.org/docs/latest/configuration/animations.html
そこでhoverイベントの発行時と同様にoptions
プロパティにコールバック関数をdefault値として渡すことで実装しようと試みたのですが、onComplete
はanimation
オブジェクトのプロパティであり一つネストした階層に定義する必要があるため、新たに算出プロパティoptionsMergedDefaultEvents
を実装し、そこでdefaultのイベントをpropsで渡されたoptions
にmergeするようにしました。
// ・・・省略
computed: {
optionsMergedDefaultEvents: function() {
let options = this.options;
const animation = this.options.animation || {};
options.animation = {
onComplete: this.rendered,
...animation,
};
options = {
onHover: this.hover,
...options,
};
return options;
},
},
mounted() {
this.renderChart(this.chartData, this.optionsMergedDefaultEvents);
},
methods: {
// ・・・省略
rendered: function() {
this.$emit('rendered');
},
},
// ・・・省略
上記により、レンダリング完了時もhoverイベントと同様に呼び出し側から@rendered="event handler名"
にてイベントを受け取ることが可能となりました。
<template>
<v-container fluid>
<doughnut-chart :chart-data="chartData" :options="chartOptions" @hover="hover" @rendered="rendered"/>
// ・・・省略
</v-container>
</template>
<script>
// ・・・省略
methods: {
// ・・・省略
rendered: function() {
console.log('rendered');
},
},
};
</script>