blog

Vue で BaseChart コンポーネントをラップし、自動ハイライトを追加する

Vue2 と Echarts 4.x に基づいて基本的な Chart コンポーネントをラップし、タイマーとムーブイン/ムーブアウト・イベントの相互作用の問題を解決するためにオートハイライトを追加します...

Sep 27, 2020 · 4 min. read
シェア

問題:

1.タイマーの保存と制御

autoHoverメソッドを呼び出し、チャート・オブジェクト(echarts.init(dom)でインスタンス化されたオブジェクト)を渡し、チャート・オブジェクトに_timerプロパティをバインドします。変数に格納し、タイマーがトリガーされる度にchart._timerを保存し、チャートが破棄された後にタイマーが破棄されるようにします。

2、マウスイベント処理

ここでは主に、マウスオーバーとマウスアウトのイベントを扱います。マウスがマウス内に移動するとタイマーはオフになり、マウスがマウス外に移動するとオートローテーションが再開されます。

マウスオーバーが機能するのは、円グラフと棒グラフのデータ上に移動した場合のみです。 最後の解決策は、チャート全体に直接マウスオーバーイベントを追加し、chart.getZr().onを介してマウスオーバーイベントを登録します。

コード BaseChart.vue

BaseChart.vue

<template>
 <div ref="chart" :style="{ width, height }" @mouseover="clearTimer" />
</template>
<script>
import echarts from 'echarts'
// import { debounce } from 'lodash-es'
import { autoHover } from './auto-chart'
export default {
 name: 'BaseChart',
 props: {
 width: {
 type: String,
 default: '100%'
 },
 height: {
 type: String,
 default: '100%'
 }
 },
 data () {
 return {
 chart: null
 }
 },
 mounted () {
 window.addEventListener('resize', this.handleResize)
 },
 methods: {
 /** ウィンドウ変更イベント */
 handleResize () {
 this.chart && this.chart.resize()
 },
 /** ハイライト・インデックスのトグル */
 handleHoverIndexChange (index) {
 this.$emit('curDataIndex', index)
 },
 setChart ({ options = {}, isAutoHover = false, isClear = false, seriesIndex = 0 }) {
 this.$nextTick(() => {
 if (!this.chart) {
 this.chart = echarts.init(this.$refs.chart)
 }
 this.clearTimer()
 if (isAutoHover) {
 autoHover({
 chart: this.chart,
 seriesIndex,
 length: options.series[seriesIndex].data.length,
 cb: this.handleHoverIndexChange
 })
 }
 isClear && this.chart.clear()
 this.chart.setOption(options)
 this.chart.resize()
 })
 },
 /** auto-chartメソッドは外部から呼び出される */
 autoHover (params) {
 this.$nextTick(() => {
 autoHover({ chart: this.chart, ...params })
 })
 },
 /** タイマーをクリアする */
 clearTimer () {
 if (this.chart && this.chart._timer) {
 clearInterval(this.chart._timer)
 // clearTimeout(this.chart._timer)
 this.chart._timer = null
 }
 }
 },
 beforeDestroy () {
 this.clearTimer()
 /** イベントを削除する */
 window.removeEventListener('resize', this.handleResize)
 }
}
</script>

オートチャート.js

/**
* タイマーをクリアする
* @param {Echart} chart
*/
const clearTimer = chart => {
 if (!chart && !chart._timer) return
 clearInterval(chart._timer)
 chart._timer = null
}
const sendChartDataIndex = (n, cb) => { cb(n) }
/**
* チャートのハイライトとチップの表示を設定する
* @param {Echart} chart
* @param {number/array} seriesIndex series 
* @param {number} index データ・インデックス
*/
export const setChartLightAndTip = (chart, seriesIndex = 0, index = 0) => {
 if (!chart) return false
 // 指定したデータグラフのハイライトを解除する
 chart.dispatchAction({
 type: 'downplay',
 seriesIndex
 })
 //  
 chart.dispatchAction({
 type: 'highlight',
 seriesIndex,
 dataIndex: index
 })
 // チップを表示する
 chart.dispatchAction({
 type: 'showTip',
 seriesIndex,
 dataIndex: index
 })
}
/**
* chartオートチャートのハイライト
* @param {Echart} chart
* @param {number} length データの長さ
* @param {number} interval 切り替え間隔
* @param {number/array} seriesIndex series 
* @param {number} defaultIndex デフォルトのハイライト
* https://..com/liuwei54/p/.html
*/
export const autoHover = ({
 chart,
 length = 0,
 interval = 2000,
 seriesIndex = 0,
 defaultIndex = 0,
 cb }) => {
 let _index = defaultIndex
 let _timer = null
 /** チャートが存在しない場合 */
 if (!chart) {
 return void 0
 }
 /** 最初にイベントをクリアする */
 chart.off('mouseout')
 /** タイマーが存在する */
 if (chart._timer) {
 clearTimer(chart)
 }
 /** タイマー・コールバック関数 */
 const timerCB = () => {
 if (chart) {
 _timer = chart._timer
 }
 // チャートが存在しない場合は、タイマーをクリアする。
 if (!chart) {
 // clearTimer(chart)
 clearInterval(_timer)
 _timer = null
 }
 // ハイライトを切り替える
 setChartLightAndTip(chart, seriesIndex, _index)
 // 切り替え後のハイライト・イベントを送信する
 sendChartDataIndex(_index, cb)
 _index++
 //  
 if (_index >= length) _index = 0
 }
 // タイマーを設定する
 chart._timer = setInterval(() => {
 timerCB()
 }, interval)
 // マウスオーバーイベントを処理する
 // chart.getZr().on('mouseover', params => {
 // console.log('ムーブイン')
 // clearTimer(chart)
 // _index = params.dataIndex
 // sendChartDataIndex(_index, cb)
 // setChartLightAndTip(chart, seriesIndex, _index)
 // })
 // マウスオーバーイベントを処理する
 chart.getZr().on('mouseout', () => {
 clearTimer(chart)
 chart._timer = setInterval(() => {
 timerCB()
 }, interval)
 })
}
Read next

HTML5新機能のフロントエンド学習

HTML5の新機能は主にこれまでの欠点を補うもので、新しいタグ、新しいフォーム、新しいフォーム属性などが追加されています。 これらの新機能には互換性の問題があり、基本的にIE9以上のバージョンのブラウザをサポートしていますが、互換性の問題を考慮しなければ、これらの新機能の多くを使用することができます。 以前は、基本的なdivのレイアウトを行うには、検索エンジンのdivは、されていません...

Sep 27, 2020 · 4 min read