From d4c9a28f161d6bf2efb49282fa9925d9c1914561 Mon Sep 17 00:00:00 2001 From: Bairui Su Date: Tue, 18 Jun 2024 14:47:04 +0800 Subject: [PATCH] fix(tooltip): series enterable (#6296) * fix(tooltip): series enterable * fix: test --- .../api-chart-emit-series-tooltip.spec.ts | 6 +-- .../tooltip/alphabet-interval-enterable.ts | 46 ++++++++----------- .../plots/tooltip/alphabet-line-enterable.ts | 26 +++++++++++ __tests__/plots/tooltip/index.ts | 1 + src/interaction/tooltip.ts | 22 ++++----- 5 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 __tests__/plots/tooltip/alphabet-line-enterable.ts diff --git a/__tests__/integration/api-chart-emit-series-tooltip.spec.ts b/__tests__/integration/api-chart-emit-series-tooltip.spec.ts index 2637954ab3..ca416a85ba 100644 --- a/__tests__/integration/api-chart-emit-series-tooltip.spec.ts +++ b/__tests__/integration/api-chart-emit-series-tooltip.spec.ts @@ -22,14 +22,14 @@ describe('chart.emit', () => { clear(); // chart.emit("tooltip:show", options) should show tooltip. - await expect(canvas).toMatchDOMSnapshot(dir, 'step0', { + expect(canvas).toMatchDOMSnapshot(dir, 'step0', { fileFormat: 'html', selector: '.g2-tooltip', }); // chart.emit("tooltip:hide") should hide tooltip. chart.emit('tooltip:hide'); - await expect(canvas).toMatchDOMSnapshot(dir, 'step1', { + expect(canvas).toMatchDOMSnapshot(dir, 'step1', { fileFormat: 'html', selector: '.g2-tooltip', }); @@ -51,7 +51,7 @@ describe('chart.emit', () => { // chart.on("tooltip:hide") should be called when hiding tooltip. const [tooltipHided, resolveHide] = createPromise(); chart.on('tooltip:hide', receiveExpectData(resolveHide, null)); - dispatchPlotEvent(canvas, 'pointerleave'); + dispatchPlotEvent(canvas, 'pointerleave', { offsetX: -20, offsetY: -20 }); await tooltipHided; }); diff --git a/__tests__/plots/tooltip/alphabet-interval-enterable.ts b/__tests__/plots/tooltip/alphabet-interval-enterable.ts index 997966dfd9..3b3afb9453 100644 --- a/__tests__/plots/tooltip/alphabet-interval-enterable.ts +++ b/__tests__/plots/tooltip/alphabet-interval-enterable.ts @@ -1,34 +1,26 @@ -import { CustomEvent } from '@antv/g'; -import { G2Spec, PLOT_CLASS_NAME } from '../../../src'; -import { tooltipSteps } from './utils'; +import { G2Spec } from '../../../src'; export function alphabetIntervalEnterable(): G2Spec { return { - type: 'view', - children: [ - { - type: 'interval', - padding: 0, - data: { - type: 'fetch', - value: 'data/alphabet.csv', - }, - axis: false, - legend: false, - encode: { - x: 'letter', - y: 'frequency', - color: 'steelblue', - }, - interaction: { - tooltip: { - enterable: true, - }, - }, + type: 'interval', + padding: 0, + data: { + type: 'fetch', + value: 'data/alphabet.csv', + }, + axis: false, + legend: false, + encode: { + x: 'letter', + y: 'frequency', + color: 'steelblue', + }, + interaction: { + tooltip: { + enterable: true, }, - ], + }, }; } -// TOOD: this test case does not test the `enterable` feature. -alphabetIntervalEnterable.steps = tooltipSteps(0); +alphabetIntervalEnterable.skip = true; diff --git a/__tests__/plots/tooltip/alphabet-line-enterable.ts b/__tests__/plots/tooltip/alphabet-line-enterable.ts new file mode 100644 index 0000000000..14d99ab02f --- /dev/null +++ b/__tests__/plots/tooltip/alphabet-line-enterable.ts @@ -0,0 +1,26 @@ +import { G2Spec } from '../../../src'; + +export function alphabetLineEnterable(): G2Spec { + return { + type: 'line', + padding: 0, + data: { + type: 'fetch', + value: 'data/alphabet.csv', + }, + axis: false, + legend: false, + encode: { + x: 'letter', + y: 'frequency', + color: 'steelblue', + }, + interaction: { + tooltip: { + enterable: true, + }, + }, + }; +} + +alphabetLineEnterable.skip = true; diff --git a/__tests__/plots/tooltip/index.ts b/__tests__/plots/tooltip/index.ts index b9a38312c4..caafd1ee00 100644 --- a/__tests__/plots/tooltip/index.ts +++ b/__tests__/plots/tooltip/index.ts @@ -77,3 +77,4 @@ export { alphabetText } from './alphabet-text'; export { mockLineFlex } from './mock-line-flex'; export { mockTooltipClosestTransposed } from './mock-tooltip-closest-transposed'; export { mockDualBarShareTooltip } from './mock-dual-bar-share-tooltip'; +export { alphabetLineEnterable } from './alphabet-line-enterable'; diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index f1dcbd921f..4373bcf934 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -164,6 +164,9 @@ function hideTooltip({ // Must be clientX, clientY. tooltipElement.hide(event?.clientX, event?.clientY); } + hideRuleY(root); + hideRuleX(root); + hideMarker(root); } function destroyTooltip({ root, single }) { @@ -175,6 +178,9 @@ function destroyTooltip({ root, single }) { tooltipElement.destroy(); parent.tooltipElement = undefined; } + hideRuleY(root); + hideRuleX(root); + hideMarker(root); } function showUndefined(item) { @@ -860,20 +866,10 @@ export function seriesTooltip( const hide = (event: MouseEvent) => { hideTooltip({ root, single, emitter, event }); - if (crosshairs) { - hideRuleY(root); - hideRuleX(root); - } - if (marker) hideMarker(root); }; const destroy = () => { destroyTooltip({ root, single }); - if (crosshairs) { - hideRuleY(root); - hideRuleX(root); - } - if (marker) hideMarker(root); }; const onTooltipShow = ({ nativeEvent, data }) => { @@ -905,7 +901,11 @@ export function seriesTooltip( if (!disableNative) { root.addEventListener('pointerenter', update); root.addEventListener('pointermove', update); - root.addEventListener('pointerleave', hide); + // Only emit pointerleave event when the pointer is not in the root area. + root.addEventListener('pointerleave', (e) => { + if (mousePosition(root, e)) return; + hide(e); + }); } };