UNPKG

di-echarts

Version:

Apache ECharts is a powerful, interactive charting and data visualization library for browser

182 lines (156 loc) 5.14 kB
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import * as zrUtil from 'zrender/src/core/util'; import env from 'zrender/src/core/env'; import {makeInner} from '../../util/model'; import ExtensionAPI from '../../core/ExtensionAPI'; import { ZRenderType } from 'zrender/src/zrender'; import { ZRElementEvent } from '../../util/types'; import { Dictionary } from 'zrender/src/core/types'; type DispatchActionMethod = ExtensionAPI['dispatchAction']; type Handler = ( currTrigger: 'click' | 'mousemove' | 'leave', event: ZRElementEvent, dispatchAction: DispatchActionMethod ) => void; interface Record { handler: Handler } interface InnerStore { initialized: boolean records: Dictionary<Record> } interface ShowTipPayload { type: 'showTip' dispatchAction: DispatchActionMethod } interface HideTipPayload { type: 'hideTip' dispatchAction: DispatchActionMethod } interface Pendings { showTip: ShowTipPayload[] hideTip: HideTipPayload[] } const inner = makeInner<InnerStore, ZRenderType>(); const each = zrUtil.each; /** * @param {string} key * @param {module:echarts/ExtensionAPI} api * @param {Function} handler * param: {string} currTrigger * param: {Array.<number>} point */ export function register(key: string, api: ExtensionAPI, handler?: Handler) { if (env.node) { return; } const zr = api.getZr(); inner(zr).records || (inner(zr).records = {}); initGlobalListeners(zr, api); const record = inner(zr).records[key] || (inner(zr).records[key] = {} as Record); record.handler = handler; } function initGlobalListeners(zr: ZRenderType, api?: ExtensionAPI) { if (inner(zr).initialized) { return; } inner(zr).initialized = true; useHandler('click', zrUtil.curry(doEnter, 'click')); useHandler('mousemove', zrUtil.curry(doEnter, 'mousemove')); // useHandler('mouseout', onLeave); useHandler('globalout', onLeave); function useHandler( eventType: string, cb: (record: Record, e: ZRElementEvent, dispatchAction: DispatchActionMethod) => void ) { zr.on(eventType, function (e: ZRElementEvent) { const dis = makeDispatchAction(api); each(inner(zr).records, function (record) { record && cb(record, e, dis.dispatchAction); }); dispatchTooltipFinally(dis.pendings, api); }); } } function dispatchTooltipFinally(pendings: Pendings, api: ExtensionAPI) { const showLen = pendings.showTip.length; const hideLen = pendings.hideTip.length; let actuallyPayload; if (showLen) { actuallyPayload = pendings.showTip[showLen - 1]; } else if (hideLen) { actuallyPayload = pendings.hideTip[hideLen - 1]; } if (actuallyPayload) { actuallyPayload.dispatchAction = null; api.dispatchAction(actuallyPayload); } } function onLeave( record: Record, e: ZRElementEvent, dispatchAction: DispatchActionMethod ) { record.handler('leave', null, dispatchAction); } function doEnter( currTrigger: 'click' | 'mousemove' | 'leave', record: Record, e: ZRElementEvent, dispatchAction: DispatchActionMethod ) { record.handler(currTrigger, e, dispatchAction); } function makeDispatchAction(api: ExtensionAPI) { const pendings: Pendings = { showTip: [], hideTip: [] }; // FIXME // better approach? // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip, // which may be conflict, (axisPointer call showTip but tooltip call hideTip); // So we have to add "final stage" to merge those dispatched actions. const dispatchAction = function (payload: ShowTipPayload | HideTipPayload) { const pendingList = pendings[payload.type]; if (pendingList) { (pendingList as ShowTipPayload[]).push(payload as ShowTipPayload); } else { payload.dispatchAction = dispatchAction; api.dispatchAction(payload); } }; return { dispatchAction: dispatchAction, pendings: pendings }; } export function unregister(key: string, api: ExtensionAPI) { if (env.node) { return; } const zr = api.getZr(); const record = (inner(zr).records || {})[key]; if (record) { inner(zr).records[key] = null; } }