diff --git a/__tests__/charts/event-spec.tsx b/__tests__/charts/event-spec.tsx new file mode 100644 index 0000000..80a4e57 --- /dev/null +++ b/__tests__/charts/event-spec.tsx @@ -0,0 +1,89 @@ +import React, { useState, useEffect } from 'react'; +import { act } from 'react-dom/test-utils'; +import ReactECharts from '../../src'; +import { render, destroy, createDiv, removeDom } from '../utils'; + +describe('chart', () => { + it('event change', async () => { + let echartsInstance; + const div = createDiv(); + let eventParam = null; + const ChartEventChange: React.FC = (props) => { + const option = { + title : { + text: '某站点用户访问来源', + subtext: '纯属虚构', + x:'center' + }, + tooltip : { + trigger: 'item', + formatter: "{a}
{b} : {c} ({d}%)" + }, + legend: { + orient: 'vertical', + left: 'left', + data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎'] + }, + series : [ + { + name: '访问来源', + type: 'pie', + radius : '55%', + center: ['50%', '60%'], + data:[ + {value:335, name:'直接访问'}, + {value:310, name:'邮件营销'}, + {value:234, name:'联盟广告'}, + {value:135, name:'视频广告'}, + {value:1548, name:'搜索引擎'} + ], + itemStyle: { + emphasis: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + } + } + ] + }; + + const [onEvents, setOnEvents] = useState(null); + + useEffect(() => { + setTimeout(() => { + setOnEvents({ + mousedown: param => eventParam = param + }); + }, 500) + }, []); + + return ( + + ); + }; + const Comp = (echartsInstance = echarts)} />; + render(Comp, div); + + expect(echartsInstance).toBeDefined(); + + let e = new MouseEvent('mousedown', { + clientX: div.offsetLeft + div.offsetWidth / 2, + clientY: div.offsetTop + div.offsetHeight / 2, + bubbles: true, + cancelable: false + }); + div.querySelector('canvas').dispatchEvent(e); + expect(eventParam).toBe(null); + + await act(async () => { + await new Promise(resolve => setTimeout(resolve, 600)); + div.querySelector('canvas').dispatchEvent(e); + expect(eventParam).toBeDefined(); + expect(eventParam.type).toEqual('mousedown'); + }); + + destroy(div); + removeDom(div); + }); +}); diff --git a/src/core.tsx b/src/core.tsx index 9cb79d9..77dbd71 100644 --- a/src/core.tsx +++ b/src/core.tsx @@ -52,11 +52,9 @@ export default class EChartsReactCore extends PureComponent { // 以下属性修改的时候,需要 dispose 之后再新建 // 1. 切换 theme 的时候 // 2. 修改 opts 的时候 - // 3. 修改 onEvents 的时候,这样可以取消所有之前绑定的事件 issue #151 if ( !isEqual(prevProps.theme, this.props.theme) || - !isEqual(prevProps.opts, this.props.opts) || - !isEqual(prevProps.onEvents, this.props.onEvents) + !isEqual(prevProps.opts, this.props.opts) ) { this.dispose(); @@ -64,6 +62,13 @@ export default class EChartsReactCore extends PureComponent { return; } + // 修改 onEvent 的时候先移除历史事件再添加 + const echartsInstance = this.getEchartsInstance(); + if (!isEqual(prevProps.onEvents, this.props.onEvents)) { + this.offEvents(echartsInstance, prevProps.onEvents); + this.bindEvents(echartsInstance, this.props.onEvents); + } + // when these props are not isEqual, update echarts const pickKeys = ['option', 'notMerge', 'lazyUpdate', 'showLoading', 'loadingOption']; if (!isEqual(pick(this.props, pickKeys), pick(prevProps, pickKeys))) { @@ -149,6 +154,17 @@ export default class EChartsReactCore extends PureComponent { } } + // off the events + private offEvents(instance, events: EChartsReactProps['onEvents']) { + if (!events) return; + // loop and off + for (const eventName in events) { + if (isString(eventName)) { + instance.off(eventName); + } + } + } + /** * render the echarts */