You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2021/03/15 08:17:07 UTC

[echarts] 01/01: feature: [tooltip] (1) Make component tooltip inherit cascade correct: itemOption.tooltip -> componentOption.tooltip -> globalOption.tooltip (previous incorrect cascade: itemOption.tooltip -> globalOption.tooltip (2) Enable trigger component tooltip by chart.dispatchAction({ type: 'showTip', legendIndex: 0, name: 'some' });

This is an automated email from the ASF dual-hosted git repository.

sushuang pushed a commit to branch fix/component-tooltip
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit b9c7e9e50d7584a14ccc2b8d0829fd56499806b8
Author: 100pah <su...@gmail.com>
AuthorDate: Mon Mar 15 16:16:36 2021 +0800

    feature: [tooltip]
    (1) Make component tooltip inherit cascade correct: itemOption.tooltip -> componentOption.tooltip -> globalOption.tooltip
    (previous incorrect cascade: itemOption.tooltip -> globalOption.tooltip
    (2) Enable trigger component tooltip by chart.dispatchAction({ type: 'showTip', legendIndex: 0, name: 'some' });
    
    To make (2) happen, this commit migrate `ECElement['tooltip']` to ECData['tooltipConfig']['option'],
    and add other info in ECData['tooltipConfig']:
    {
          componentMainType
          componentIndex
          name
    }
    to locate a tooltipable component element by a payload.
---
 src/component/axis/AxisBuilder.ts     |  17 ++--
 src/component/brush/BrushModel.ts     |   5 ++
 src/component/legend/LegendView.ts    |  27 ++++---
 src/component/toolbox/ToolboxModel.ts |   3 +-
 src/component/toolbox/ToolboxView.ts  |  22 +++--
 src/component/tooltip/TooltipView.ts  | 148 +++++++++++++++++++++++++++++-----
 src/util/innerStore.ts                |  16 +++-
 src/util/model.ts                     |  68 ++++++++++------
 src/util/types.ts                     |  16 ++--
 9 files changed, 235 insertions(+), 87 deletions(-)

diff --git a/src/component/axis/AxisBuilder.ts b/src/component/axis/AxisBuilder.ts
index 3fd04af..6d65df0 100644
--- a/src/component/axis/AxisBuilder.ts
+++ b/src/component/axis/AxisBuilder.ts
@@ -422,8 +422,6 @@ const builders: Record<'axisLine' | 'axisTickLabel' | 'axisName', AxisElementsBu
             opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth
         );
 
-        const tooltipOpt = axisModel.get('tooltip', true);
-
         const mainType = axisModel.mainType;
         const formatterParams: LabelFormatterParams = {
             componentType: mainType,
@@ -452,15 +450,16 @@ const builders: Record<'axisLine' | 'axisTickLabel' | 'axisName', AxisElementsBu
             }),
             z2: 1
         }) as AxisLabelText;
-        textEl.tooltip = (tooltipOpt && tooltipOpt.show)
-            ? extend({
+        getECData(textEl).tooltipConfig = {
+            componentMainType: axisModel.mainType,
+            componentIndex: axisModel.componentIndex,
+            name: name,
+            option: {
                 content: name,
-                formatter() {
-                    return name;
-                },
+                formatter: () => name,
                 formatterParams: formatterParams
-            }, tooltipOpt)
-            : null;
+            }
+        };
         textEl.__fullText = name;
         // Id for animation
         textEl.anid = 'name';
diff --git a/src/component/brush/BrushModel.ts b/src/component/brush/BrushModel.ts
index 8ee179a..e3721af 100644
--- a/src/component/brush/BrushModel.ts
+++ b/src/component/brush/BrushModel.ts
@@ -63,6 +63,11 @@ export interface BrushAreaParam extends ModelFinderObject {
     // coord ranges, used in multiple cartesian in one grid.
     // Only for output to users.
     coordRanges?: BrushAreaRange[];
+
+    __rangeOffset?: {
+        offset: BrushDimensionMinMax[] | BrushDimensionMinMax,
+        xyMinMax: BrushDimensionMinMax[]
+    }
 }
 
 /**
diff --git a/src/component/legend/LegendView.ts b/src/component/legend/LegendView.ts
index cabb0367..c9c3ef9 100644
--- a/src/component/legend/LegendView.ts
+++ b/src/component/legend/LegendView.ts
@@ -33,7 +33,6 @@ import {
     ZRColor,
     ItemStyleOption,
     ZRRectLike,
-    ECElement,
     CommonTooltipOption,
     ColorString
 } from '../../util/types';
@@ -42,6 +41,7 @@ import Displayable, { DisplayableState } from 'zrender/src/graphic/Displayable';
 import { PathStyleProps } from 'zrender/src/graphic/Path';
 import { parse, stringify } from 'zrender/src/tool/color';
 import {PatternObject} from 'zrender/src/graphic/Pattern';
+import { getECData } from '../../util/innerStore';
 
 const curry = zrUtil.curry;
 const each = zrUtil.each;
@@ -353,8 +353,6 @@ class LegendView extends ComponentView {
 
         const itemIcon = itemModel.get('icon');
 
-        const tooltipModel = itemModel.getModel('tooltip') as Model<CommonTooltipOption<LegendTooltipFormatterParams>>;
-        const legendGlobalTooltipModel = tooltipModel.parentModel;
 
         // Use user given icon first
         legendSymbolType = itemIcon || legendSymbolType;
@@ -432,22 +430,25 @@ class LegendView extends ComponentView {
             shape: itemGroup.getBoundingRect(),
             invisible: true
         });
+
+        const tooltipModel = itemModel.getModel('tooltip') as Model<CommonTooltipOption<LegendTooltipFormatterParams>>;
         if (tooltipModel.get('show')) {
+            const componentIndex = legendModel.componentIndex;
             const formatterParams: LegendTooltipFormatterParams = {
                 componentType: 'legend',
-                legendIndex: legendModel.componentIndex,
+                legendIndex: componentIndex,
                 name: name,
                 $vars: ['name']
             };
-            (hitRect as ECElement).tooltip = zrUtil.extend({
-                content: name,
-                // Defaul formatter
-                formatter: legendGlobalTooltipModel.get('formatter', true)
-                    || function (params: LegendTooltipFormatterParams) {
-                        return params.name;
-                    },
-                formatterParams: formatterParams
-            }, tooltipModel.option);
+            getECData(hitRect).tooltipConfig = {
+                componentMainType: legendModel.mainType,
+                componentIndex: componentIndex,
+                name: name,
+                option: zrUtil.defaults({
+                    content: name,
+                    formatterParams: formatterParams
+                }, tooltipModel.option)
+            };
         }
         itemGroup.add(hitRect);
 
diff --git a/src/component/toolbox/ToolboxModel.ts b/src/component/toolbox/ToolboxModel.ts
index c99cd18..fabad26 100644
--- a/src/component/toolbox/ToolboxModel.ts
+++ b/src/component/toolbox/ToolboxModel.ts
@@ -148,7 +148,8 @@ class ToolboxModel extends ComponentModel<ToolboxOption> {
         // feature
 
         tooltip: {
-            show: false
+            show: false,
+            position: 'bottom'
         }
     };
 }
diff --git a/src/component/toolbox/ToolboxView.ts b/src/component/toolbox/ToolboxView.ts
index 8dd7881..2effb45 100644
--- a/src/component/toolbox/ToolboxView.ts
+++ b/src/component/toolbox/ToolboxView.ts
@@ -28,7 +28,7 @@ import ComponentView from '../../view/Component';
 import ToolboxModel from './ToolboxModel';
 import GlobalModel from '../../model/Global';
 import ExtensionAPI from '../../core/ExtensionAPI';
-import { DisplayState, Dictionary, ECElement, Payload } from '../../util/types';
+import { DisplayState, Dictionary, Payload } from '../../util/types';
 import {
     ToolboxFeature,
     getFeature,
@@ -39,6 +39,7 @@ import {
 import { getUID } from '../../util/component';
 import Displayable from 'zrender/src/graphic/Displayable';
 import ZRText from 'zrender/src/graphic/Text';
+import { getECData } from '../../util/innerStore';
 
 type IconPath = ToolboxFeatureModel['iconPaths'][string];
 
@@ -224,23 +225,20 @@ class ToolboxView extends ComponentView {
                 });
                 path.setTextContent(textContent);
 
-                const tooltipModel = toolboxModel.getModel('tooltip');
-                if (tooltipModel && tooltipModel.get('show')) {
-                    (path as ECElement).tooltip = zrUtil.extend({
+                getECData(path).tooltipConfig = {
+                    componentMainType: toolboxModel.mainType,
+                    componentIndex: toolboxModel.componentIndex,
+                    name: iconName,
+                    option: {
                         content: titlesMap[iconName],
-                        formatter: tooltipModel.get('formatter', true)
-                            || function () {
-                                return titlesMap[iconName];
-                            },
                         formatterParams: {
                             componentType: 'toolbox',
                             name: iconName,
                             title: titlesMap[iconName],
                             $vars: ['name', 'title']
-                        },
-                        position: tooltipModel.get('position', true) || 'bottom'
-                    }, tooltipModel.option);
-                }
+                        }
+                    }
+                };
 
                 // graphic.enableHoverEmphasis(path);
 
diff --git a/src/component/tooltip/TooltipView.ts b/src/component/tooltip/TooltipView.ts
index cd52e2b..fe30d30 100644
--- a/src/component/tooltip/TooltipView.ts
+++ b/src/component/tooltip/TooltipView.ts
@@ -29,7 +29,7 @@ import Model from '../../model/Model';
 import * as globalListener from '../axisPointer/globalListener';
 import * as axisHelper from '../../coord/axisHelper';
 import * as axisPointerViewHelper from '../axisPointer/viewHelper';
-import { getTooltipRenderMode } from '../../util/model';
+import { getTooltipRenderMode, preParseFinder, queryReferringComponents } from '../../util/model';
 import ComponentView from '../../view/Component';
 import { format as timeFormat } from '../../util/time';
 import {
@@ -41,7 +41,9 @@ import {
     TooltipRenderMode,
     ECElement,
     CommonTooltipOption,
-    ZRColor
+    ZRColor,
+    ComponentMainType,
+    ComponentItemTooltipOption
 } from '../../util/types';
 import GlobalModel from '../../model/Global';
 import ExtensionAPI from '../../core/ExtensionAPI';
@@ -49,12 +51,13 @@ import TooltipModel, {TooltipOption} from './TooltipModel';
 import Element from 'zrender/src/Element';
 import { AxisBaseModel } from '../../coord/AxisBaseModel';
 // import { isDimensionStacked } from '../../data/helper/dataStackHelper';
-import { getECData } from '../../util/innerStore';
+import { ECData, getECData } from '../../util/innerStore';
 import { shouldTooltipConfine } from './helper';
 import { DataByCoordSys, DataByAxis } from '../axisPointer/axisTrigger';
 import { normalizeTooltipFormatResult } from '../../model/mixin/dataFormat';
 import { createTooltipMarkup, buildTooltipMarkup, TooltipMarkupStyleCreator } from './tooltipMarkup';
 import { findEventDispatcher } from '../../util/event';
+import ComponentModel from '../../model/Component';
 
 const bind = zrUtil.bind;
 const each = zrUtil.each;
@@ -76,7 +79,7 @@ interface ShowTipPayload {
     from?: string
 
     // Type 1
-    tooltip?: ECElement['tooltip']
+    tooltip?: ECData['tooltipConfig']['option']
 
     // Type 2
     dataByCoordSys?: DataByCoordSys[]
@@ -86,6 +89,11 @@ interface ShowTipPayload {
     seriesIndex?: number
     dataIndex?: number
 
+    // Type 4
+    name?: string // target item name that enable tooltip.
+    // legendIndex: 0,
+    // toolboxId: 'some_id',
+    // geoName: 'some_name',
 
     x?: number
     y?: number
@@ -112,7 +120,7 @@ interface TryShowParams {
      */
     dataByCoordSys?: DataByCoordSys[]
 
-    tooltipOption?: CommonTooltipOption<TooltipCallbackDataParams | TooltipCallbackDataParams[]>
+    tooltipOption?: ComponentItemTooltipOption<TooltipCallbackDataParams | TooltipCallbackDataParams[]>
 
     position?: TooltipOption['position']
 }
@@ -287,12 +295,29 @@ class TooltipView extends ComponentView {
         // When triggered from axisPointer.
         const dataByCoordSys = payload.dataByCoordSys;
 
-        if (payload.tooltip && payload.x != null && payload.y != null) {
+        const cmptRef = findComponentReference(payload, ecModel, api);
+
+        if (cmptRef) {
+            const rect = cmptRef.el.getBoundingRect().clone();
+            rect.applyTransform(cmptRef.el.transform);
+            this._tryShow({
+                offsetX: rect.x + rect.width / 2,
+                offsetY: rect.y + rect.height / 2,
+                target: cmptRef.el,
+                position: payload.position || 'bottom'
+            }, dispatchAction);
+        }
+        else if (payload.tooltip && payload.x != null && payload.y != null) {
             const el = proxyRect as unknown as ECElement;
             el.x = payload.x;
             el.y = payload.y;
             el.update();
-            el.tooltip = payload.tooltip;
+            getECData(el).tooltipConfig = {
+                componentMainType: null,
+                componentIndex: null,
+                name: null,
+                option: payload.tooltip
+            };
             // Manually show tooltip while view is not using zrender elements.
             this._tryShow({
                 offsetX: payload.x,
@@ -428,15 +453,33 @@ class TooltipView extends ComponentView {
         if (dataByCoordSys && dataByCoordSys.length) {
             this._showAxisTooltip(dataByCoordSys, e);
         }
-        // Always show item tooltip if mouse is on the element with dataIndex
-        else if (el && findEventDispatcher(el, (target) => getECData(target).dataIndex != null, true)) {
-            this._lastDataByCoordSys = null;
-            this._showSeriesItemTooltip(e, el, dispatchAction);
-        }
-        // Tooltip provided directly. Like legend.
-        else if (el && el.tooltip) {
+        else if (el) {
             this._lastDataByCoordSys = null;
-            this._showComponentItemTooltip(e, el, dispatchAction);
+
+            let seriesDispatcher: Element;
+            let cmptDispatcher: Element;
+            findEventDispatcher(el, (target) => {
+                // Always show item tooltip if mouse is on the element with dataIndex
+                if (getECData(target).dataIndex != null) {
+                    seriesDispatcher = target;
+                    return true;
+                }
+                // Tooltip provided directly. Like legend.
+                if (getECData(target).tooltipConfig != null) {
+                    cmptDispatcher = target;
+                    return true;
+                }
+            }, true);
+
+            if (seriesDispatcher) {
+                this._showSeriesItemTooltip(e, seriesDispatcher, dispatchAction);
+            }
+            else if (cmptDispatcher) {
+                this._showComponentItemTooltip(e, cmptDispatcher, dispatchAction);
+            }
+            else {
+                this._hide(dispatchAction);
+            }
         }
         else {
             this._lastDataByCoordSys = null;
@@ -573,10 +616,9 @@ class TooltipView extends ComponentView {
 
     private _showSeriesItemTooltip(
         e: TryShowParams,
-        el: ECElement,
+        dispatcher: ECElement,
         dispatchAction: ExtensionAPI['dispatchAction']
     ) {
-        const dispatcher = findEventDispatcher(el, (target) => getECData(target).dataIndex != null, true);
         const ecModel = this._ecModel;
         const ecData = getECData(dispatcher);
         // Use dataModel in element if possible
@@ -653,7 +695,8 @@ class TooltipView extends ComponentView {
         el: ECElement,
         dispatchAction: ExtensionAPI['dispatchAction']
     ) {
-        let tooltipOpt = el.tooltip;
+        const tooltipConfig = getECData(el).tooltipConfig;
+        let tooltipOpt = tooltipConfig.option;
         if (zrUtil.isString(tooltipOpt)) {
             const content = tooltipOpt;
             tooltipOpt = {
@@ -662,7 +705,14 @@ class TooltipView extends ComponentView {
                 formatter: content
             };
         }
-        const subTooltipModel = new Model(tooltipOpt, this._tooltipModel, this._ecModel);
+
+        const tooltipModelCascade = [tooltipOpt] as Parameters<typeof buildTooltipModel>[0];
+        const cmpt = this._ecModel.getComponent(tooltipConfig.componentMainType, tooltipConfig.componentIndex);
+        cmpt && tooltipModelCascade.push(cmpt);
+        tooltipModelCascade.push(this._tooltipModel);
+
+        const subTooltipModel = buildTooltipModel(tooltipModelCascade) as Model<ComponentItemTooltipOption<unknown>>;
+
         const defaultHtml = subTooltipModel.get('content');
         const asyncTicket = Math.random() + '';
         // PENDING: this case do not support richText style yet.
@@ -908,13 +958,13 @@ class TooltipView extends ComponentView {
 }
 
 type TooltipableOption = {
-    tooltip?: Omit<TooltipOption, 'mainType'> | string
+    tooltip?: CommonTooltipOption<unknown>;
 };
 /**
  * From top to bottom. (the last one should be globalTooltipModel);
  */
 function buildTooltipModel(modelCascade: (
-    TooltipModel | Model<TooltipableOption> | Omit<TooltipOption, 'mainType'> | string
+    TooltipModel | Model<TooltipableOption> | CommonTooltipOption<unknown> | ComponentModel | string
 )[]) {
     // Last is always tooltip model.
     let resultModel = modelCascade.pop() as Model<TooltipOption>;
@@ -1036,4 +1086,60 @@ function isCenterAlign(align: HorizontalAlign | VerticalAlign) {
     return align === 'center' || align === 'middle';
 }
 
+/**
+ * Find target component by payload like:
+ * ```js
+ * { legendId: 'some_id', name: 'xxx' }
+ * { toolboxIndex: 1, name: 'xxx' }
+ * { geoName: 'some_name', name: 'xxx' }
+ * ```
+ * PENDING: at present only
+ *
+ * If not found, return null/undefined.
+ */
+function findComponentReference(
+    payload: ShowTipPayload,
+    ecModel: GlobalModel,
+    api: ExtensionAPI
+): {
+    componentMainType: ComponentMainType;
+    componentIndex: number;
+    el: ECElement;
+} {
+    const { queryOptionMap } = preParseFinder(payload);
+    const componentMainType = queryOptionMap.keys()[0];
+    if (!componentMainType) {
+        return;
+    }
+
+    const queryResult = queryReferringComponents(
+        ecModel,
+        componentMainType,
+        queryOptionMap.get(componentMainType),
+        { useDefault: false, enableAll: false, enableNone: false }
+    );
+    const model = queryResult.models[0];
+    if (!model) {
+        return;
+    }
+
+    const view = api.getViewOfComponentModel(model);
+    let el: ECElement;
+    view.group.traverse((subEl: ECElement) => {
+        const tooltipConfig = getECData(subEl).tooltipConfig;
+        if (tooltipConfig && tooltipConfig.name === payload.name) {
+            el = subEl;
+            return true; // stop
+        }
+    });
+
+    if (el) {
+        return {
+            componentMainType,
+            componentIndex: model.componentIndex,
+            el
+        };
+    }
+}
+
 export default TooltipView;
diff --git a/src/util/innerStore.ts b/src/util/innerStore.ts
index fcd176d..7445856 100644
--- a/src/util/innerStore.ts
+++ b/src/util/innerStore.ts
@@ -18,7 +18,10 @@
 */
 
 import Element from 'zrender/src/Element';
-import { DataModel, ECEventData, BlurScope, InnerFocus, SeriesDataType } from './types';
+import {
+    DataModel, ECEventData, BlurScope, InnerFocus, SeriesDataType,
+    ComponentMainType, ComponentItemTooltipOption
+} from './types';
 import { makeInner } from './model';
 /**
  * ECData stored on graphic element
@@ -31,5 +34,16 @@ export interface ECData {
     dataType?: SeriesDataType;
     focus?: InnerFocus;
     blurScope?: BlurScope;
+    tooltipConfig?: {
+        // Used to find component tooltip option, which is used as
+        // the parent of tooltipConfig.option for cascading.
+        // If not provided, do not use component as its parent.
+        // (Set manatary to make developers not to forget them).
+        componentMainType: ComponentMainType;
+        componentIndex: number;
+        // Target item name to locate tooltip.
+        name: string;
+        option: ComponentItemTooltipOption<unknown>;
+    };
 }
 export const getECData = makeInner<ECData, Element>();
diff --git a/src/util/model.ts b/src/util/model.ts
index be3dd90..bf8f531 100644
--- a/src/util/model.ts
+++ b/src/util/model.ts
@@ -774,8 +774,8 @@ export type ModelFinderObject = {
     xAxisIndex?: ModelFinderIndexQuery, xAxisId?: ModelFinderIdQuery, xAxisName?: ModelFinderNameQuery
     yAxisIndex?: ModelFinderIndexQuery, yAxisId?: ModelFinderIdQuery, yAxisName?: ModelFinderNameQuery
     gridIndex?: ModelFinderIndexQuery, gridId?: ModelFinderIdQuery, gridName?: ModelFinderNameQuery
-       // ... (can be extended)
-    [key: string]: unknown
+    dataIndex?: number, dataIndexInside?: number
+    // ... (can be extended)
 };
 /**
  * {
@@ -819,6 +819,43 @@ export function parseFinder(
         enableNone?: boolean;
     }
 ): ParsedModelFinder {
+    const { mainTypeSpecified, queryOptionMap, others } = preParseFinder(finderInput, opt);
+    const result = others as ParsedModelFinderKnown;
+
+    const defaultMainType = opt ? opt.defaultMainType : null;
+    if (!mainTypeSpecified && defaultMainType) {
+        queryOptionMap.set(defaultMainType, {});
+    }
+
+    queryOptionMap.each(function (queryOption, mainType) {
+        const queryResult = queryReferringComponents(
+            ecModel,
+            mainType,
+            queryOption,
+            {
+                useDefault: defaultMainType === mainType,
+                enableAll: (opt && opt.enableAll != null) ? opt.enableAll : true,
+                enableNone: (opt && opt.enableNone != null) ? opt.enableNone : true
+            }
+        );
+        result[mainType + 'Models'] = queryResult.models;
+        result[mainType + 'Model'] = queryResult.models[0];
+    });
+
+    return result;
+}
+
+export function preParseFinder(
+    finderInput: ModelFinder,
+    opt?: {
+        // If pervided, types out of this list will be ignored.
+        includeMainTypes?: ComponentMainType[];
+    }
+): {
+    mainTypeSpecified: boolean;
+    queryOptionMap: HashMap<QueryReferringUserOption, ComponentMainType>;
+    others: Partial<Pick<ParsedModelFinderKnown, 'dataIndex' | 'dataIndexInside'>>
+} {
     let finder: ModelFinderObject;
     if (isString(finderInput)) {
         const obj = {};
@@ -830,13 +867,13 @@ export function parseFinder(
     }
 
     const queryOptionMap = createHashMap<QueryReferringUserOption, ComponentMainType>();
-    const result = {} as ParsedModelFinderKnown;
+    const others = {} as Partial<Pick<ParsedModelFinderKnown, 'dataIndex' | 'dataIndexInside'>>;
     let mainTypeSpecified = false;
 
     each(finder, function (value, key) {
         // Exclude 'dataIndex' and other illgal keys.
         if (key === 'dataIndex' || key === 'dataIndexInside') {
-            result[key] = value as number;
+            others[key] = value as number;
             return;
         }
 
@@ -858,29 +895,10 @@ export function parseFinder(
         queryOption[queryType] = value as any;
     });
 
-    const defaultMainType = opt ? opt.defaultMainType : null;
-    if (!mainTypeSpecified && defaultMainType) {
-        queryOptionMap.set(defaultMainType, {});
-    }
-
-    queryOptionMap.each(function (queryOption, mainType) {
-        const queryResult = queryReferringComponents(
-            ecModel,
-            mainType,
-            queryOption,
-            {
-                useDefault: defaultMainType === mainType,
-                enableAll: (opt && opt.enableAll != null) ? opt.enableAll : true,
-                enableNone: (opt && opt.enableNone != null) ? opt.enableNone : true
-            }
-        );
-        result[mainType + 'Models'] = queryResult.models;
-        result[mainType + 'Model'] = queryResult.models[0];
-    });
-
-    return result;
+    return { mainTypeSpecified, queryOptionMap, others };
 }
 
+
 export type QueryReferringUserOption = {
     index?: ModelFinderIndexQuery,
     id?: ModelFinderIdQuery,
diff --git a/src/util/types.ts b/src/util/types.ts
index 823310c..b537af9 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -46,6 +46,7 @@ import { PathStyleProps } from 'zrender/src/graphic/Path';
 import { ImageStyleProps } from 'zrender/src/graphic/Image';
 import ZRText, { TextStyleProps } from 'zrender/src/graphic/Text';
 import { Source } from '../data/Source';
+import Model from '../model/Model';
 
 
 
@@ -101,10 +102,6 @@ export interface ComponentTypeInfo {
 }
 
 export interface ECElement extends Element {
-    tooltip?: CommonTooltipOption<unknown> & {
-        content?: string;
-        formatterParams?: unknown;
-    };
     highDownSilentOnTouch?: boolean;
     onHoverStateChange?: (toState: DisplayState) => void;
 
@@ -130,7 +127,7 @@ export interface DataHost {
     getData(dataType?: SeriesDataType): List;
 }
 
-export interface DataModel extends DataHost, DataFormatMixin {}
+export interface DataModel extends Model<unknown>, DataHost, DataFormatMixin {}
     // Pick<DataHost, 'getData'>,
     // Pick<DataFormatMixin, 'getDataParams' | 'formatTooltip'> {}
 
@@ -1348,6 +1345,12 @@ export interface CommonTooltipOption<FormatterParams> {
     }
 }
 
+export type ComponentItemTooltipOption<T> = CommonTooltipOption<T> & {
+    // Default content HTML.
+    content?: string;
+    formatterParams?: unknown;
+};
+
 /**
  * Tooltip option configured on each series
  */
@@ -1355,6 +1358,9 @@ export type SeriesTooltipOption = CommonTooltipOption<CallbackDataParams> & {
     trigger?: 'item' | 'axis' | boolean | 'none'
 };
 
+
+
+
 type LabelFormatterParams = {
     value: ScaleDataValue
     axisDimension: string


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org