From 2f8eb7b2bcac92a8eeb1dad11dc104a75baef4fe Mon Sep 17 00:00:00 2001 From: hustcc Date: Wed, 11 Oct 2023 14:54:53 +0800 Subject: [PATCH 1/5] fix: tooltip enterable --- .../alphabet-interval-enterable/step0.html | 46 +++++++++++++++++++ .../tooltip/alphabet-interval-enterable.ts | 34 ++++++++++++++ __tests__/plots/tooltip/index.ts | 1 + src/interaction/tooltip.ts | 37 +++++++++------ src/spec/interaction.ts | 2 +- 5 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 __tests__/integration/snapshots/tooltip/alphabet-interval-enterable/step0.html create mode 100644 __tests__/plots/tooltip/alphabet-interval-enterable.ts diff --git a/__tests__/integration/snapshots/tooltip/alphabet-interval-enterable/step0.html b/__tests__/integration/snapshots/tooltip/alphabet-interval-enterable/step0.html new file mode 100644 index 0000000000..354c77e062 --- /dev/null +++ b/__tests__/integration/snapshots/tooltip/alphabet-interval-enterable/step0.html @@ -0,0 +1,46 @@ +
+
+ A +
+ +
\ No newline at end of file diff --git a/__tests__/plots/tooltip/alphabet-interval-enterable.ts b/__tests__/plots/tooltip/alphabet-interval-enterable.ts new file mode 100644 index 0000000000..997966dfd9 --- /dev/null +++ b/__tests__/plots/tooltip/alphabet-interval-enterable.ts @@ -0,0 +1,34 @@ +import { CustomEvent } from '@antv/g'; +import { G2Spec, PLOT_CLASS_NAME } from '../../../src'; +import { tooltipSteps } from './utils'; + +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, + }, + }, + }, + ], + }; +} + +// TOOD: this test case does not test the `enterable` feature. +alphabetIntervalEnterable.steps = tooltipSteps(0); diff --git a/__tests__/plots/tooltip/index.ts b/__tests__/plots/tooltip/index.ts index 4c9416964b..61f87a81ec 100644 --- a/__tests__/plots/tooltip/index.ts +++ b/__tests__/plots/tooltip/index.ts @@ -4,6 +4,7 @@ export { bodyPoint2d } from './body-point-2d'; export { cars3LineXd } from './cars3-line-xd'; export { alphabetIntervalMulti } from './alphabet-interval-multi'; export { alphabetIntervalTitle } from './alphabet-interval-title'; +export { alphabetIntervalEnterable } from './alphabet-interval-enterable'; export { aaplLine } from './aapl-line'; export { indicesLine } from './indices-line'; export { temperaturesLineDiscrete } from './temperatures-line-discrete'; diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index 04013b97e4..365a8be8e8 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -146,7 +146,13 @@ function showTooltip({ parent.tooltipElement = tooltipElement; } -function hideTooltip({ root, single, emitter, nativeEvent = true }) { +function hideTooltip({ + root, + single, + emitter, + nativeEvent = true, + event = null, +}) { if (nativeEvent) { emitter.emit('tooltip:hide', { nativeEvent }); } @@ -154,7 +160,8 @@ function hideTooltip({ root, single, emitter, nativeEvent = true }) { const parent = single ? container : root; const { tooltipElement } = parent; if (tooltipElement) { - tooltipElement.hide(); + // Must be clientX, clientY. + tooltipElement.hide(event?.clientX, event?.clientY); } } @@ -431,7 +438,7 @@ export function seriesTooltip( groupName, emitter, wait = 50, - leading = true, + leading = false, trailing = false, startX = 0, startY = 0, @@ -622,7 +629,7 @@ export function seriesTooltip( // Hide tooltip with no selected tooltip. if (selectedElements.length === 0 || isEmptyTooltipData(tooltipData)) { - hide(); + hide(event); return; } @@ -680,8 +687,9 @@ export function seriesTooltip( { leading, trailing }, ) as (...args: any[]) => void; - const hide = () => { - hideTooltip({ root, single, emitter }); + const hide = (event: MouseEvent) => { + console.log(111, 'hide'); + hideTooltip({ root, single, emitter, event }); if (crosshairs) hideRuleY(root); if (marker) hideMarker(root); }; @@ -794,7 +802,7 @@ export function tooltip( (event) => { const { target: element } = event; if (!elementSet.has(element)) { - hideTooltip({ root, single, emitter }); + hideTooltip({ root, single, emitter, event }); return; } const k = groupKey(element); @@ -813,7 +821,7 @@ export function tooltip( } if (isEmptyTooltipData(data)) { - hideTooltip({ root, single, emitter }); + hideTooltip({ root, single, emitter, event }); return; } @@ -847,17 +855,18 @@ export function tooltip( { leading, trailing }, ) as (...args: any[]) => void; - const pointerout = (event) => { - const { target: element } = event; - if (!elementSet.has(element)) return; - hideTooltip({ root, single, emitter }); + const pointerleave = (event) => { + // const { target: element } = event; + console.log(1112, 'leave'); + // if (!elementSet.has(element)) return; + hideTooltip({ root, single, emitter, event }); }; const addEventListeners = () => { if (!disableNative) { root.addEventListener('pointerover', pointerover); root.addEventListener('pointermove', pointerover); - root.addEventListener('pointerout', pointerout); + root.addEventListener('pointerleave', pointerleave); } }; @@ -865,7 +874,7 @@ export function tooltip( if (!disableNative) { root.removeEventListener('pointerover', pointerover); root.removeEventListener('pointermove', pointerover); - root.removeEventListener('pointerout', pointerout); + root.removeEventListener('pointerleave', pointerleave); } }; diff --git a/src/spec/interaction.ts b/src/spec/interaction.ts index f73991c4b6..3b2e95bd5c 100644 --- a/src/spec/interaction.ts +++ b/src/spec/interaction.ts @@ -181,7 +181,7 @@ export type TooltipInteraction = { bounding?: BBox; mount?: string | HTMLElement; css?: Record; // @todo - // enterable?: boolean; + enterable?: boolean; sort?: (d: TooltipItemValue) => any; filter?: (d: TooltipItemValue) => any; render?: ( From ce9a7afbe25a008121a178ed225a34d2e97185a6 Mon Sep 17 00:00:00 2001 From: hustcc Date: Mon, 11 Dec 2023 16:30:56 +0800 Subject: [PATCH 2/5] chore: remove unused pointer event --- src/interaction/tooltip.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index 365a8be8e8..18c1dcc816 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -688,7 +688,6 @@ export function seriesTooltip( ) as (...args: any[]) => void; const hide = (event: MouseEvent) => { - console.log(111, 'hide'); hideTooltip({ root, single, emitter, event }); if (crosshairs) hideRuleY(root); if (marker) hideMarker(root); @@ -856,23 +855,21 @@ export function tooltip( ) as (...args: any[]) => void; const pointerleave = (event) => { - // const { target: element } = event; - console.log(1112, 'leave'); - // if (!elementSet.has(element)) return; hideTooltip({ root, single, emitter, event }); }; const addEventListeners = () => { if (!disableNative) { - root.addEventListener('pointerover', pointerover); + console.log(111, 'addEventListeners'); root.addEventListener('pointermove', pointerover); + // Only emit pointerleave event when the pointer is not in the root area. + // !! !DO NOT USE pointerout event, it will emit when the pointer is in the child area. root.addEventListener('pointerleave', pointerleave); } }; const removeEventListeners = () => { if (!disableNative) { - root.removeEventListener('pointerover', pointerover); root.removeEventListener('pointermove', pointerover); root.removeEventListener('pointerleave', pointerleave); } From 7f32405d0f182e9b347682e49a2aff6523e1272b Mon Sep 17 00:00:00 2001 From: hustcc Date: Mon, 11 Dec 2023 17:18:09 +0800 Subject: [PATCH 3/5] chore: fix ci --- .../api-chart-emit-enable-disable-tooltip.spec.ts | 4 ++-- .../api-chart-emit-item-tooltip-hide-content.spec.ts | 2 +- __tests__/integration/api-chart-emit-item-tooltip.spec.ts | 4 ++-- __tests__/integration/api-chart-tooltip-multi-chart.spec.ts | 4 ++-- .../stateages-interval-highlight-group-background.ts | 2 +- .../plots/tooltip/alphabet-interval-tooltip-render-update.ts | 4 ++-- __tests__/plots/tooltip/flare-treemap-poptip.ts | 2 +- .../plots/tooltip/profit-interval-legend-filter-ordinal.ts | 2 +- __tests__/plots/tooltip/utils.ts | 4 ++-- src/interaction/tooltip.ts | 5 +++-- 10 files changed, 17 insertions(+), 16 deletions(-) diff --git a/__tests__/integration/api-chart-emit-enable-disable-tooltip.spec.ts b/__tests__/integration/api-chart-emit-enable-disable-tooltip.spec.ts index bda4b47abf..f78abaad03 100644 --- a/__tests__/integration/api-chart-emit-enable-disable-tooltip.spec.ts +++ b/__tests__/integration/api-chart-emit-enable-disable-tooltip.spec.ts @@ -57,7 +57,7 @@ describe('chart.emit', () => { chart.emit('tooltip:disable'); await sleep(20); - dispatchFirstElementEvent(barCanvas, 'pointerover'); + dispatchFirstElementEvent(barCanvas, 'pointermove'); await expect(barCanvas).toMatchDOMSnapshot(dir, 'step0', { fileFormat: 'html', selector: '.g2-tooltip', @@ -65,7 +65,7 @@ describe('chart.emit', () => { chart.emit('tooltip:enable'); - dispatchFirstElementEvent(barCanvas, 'pointerover'); + dispatchFirstElementEvent(barCanvas, 'pointermove'); await expect(barCanvas).toMatchDOMSnapshot(dir, 'step1', { fileFormat: 'html', selector: '.g2-tooltip', diff --git a/__tests__/integration/api-chart-emit-item-tooltip-hide-content.spec.ts b/__tests__/integration/api-chart-emit-item-tooltip-hide-content.spec.ts index 601933db31..04d5deea81 100644 --- a/__tests__/integration/api-chart-emit-item-tooltip-hide-content.spec.ts +++ b/__tests__/integration/api-chart-emit-item-tooltip-hide-content.spec.ts @@ -21,7 +21,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)); - dispatchFirstElementEvent(canvas, 'pointerout'); + dispatchFirstElementEvent(canvas, 'pointerleave'); await tooltipHided; }); diff --git a/__tests__/integration/api-chart-emit-item-tooltip.spec.ts b/__tests__/integration/api-chart-emit-item-tooltip.spec.ts index 21e2d4196c..2ccef4f334 100644 --- a/__tests__/integration/api-chart-emit-item-tooltip.spec.ts +++ b/__tests__/integration/api-chart-emit-item-tooltip.spec.ts @@ -37,13 +37,13 @@ describe('chart.emit', () => { // chart.on("tooltip:show", callback) should revive selected data. const [tooltipShowed, resolveShow] = createPromise(); chart.on('tooltip:show', receiveExpectData(resolveShow)); - dispatchFirstElementEvent(canvas, 'pointerover'); + dispatchFirstElementEvent(canvas, 'pointermove'); await tooltipShowed; // chart.on("tooltip:hide") should be called when hiding tooltip. const [tooltipHided, resolveHide] = createPromise(); chart.on('tooltip:hide', receiveExpectData(resolveHide, null)); - dispatchFirstElementEvent(canvas, 'pointerout'); + dispatchFirstElementEvent(canvas, 'pointerleave'); await tooltipHided; }); diff --git a/__tests__/integration/api-chart-tooltip-multi-chart.spec.ts b/__tests__/integration/api-chart-tooltip-multi-chart.spec.ts index 3c91d1a6eb..7c0d7b651b 100644 --- a/__tests__/integration/api-chart-tooltip-multi-chart.spec.ts +++ b/__tests__/integration/api-chart-tooltip-multi-chart.spec.ts @@ -15,8 +15,8 @@ describe('chart.interaction.tooltip', () => { }); await Promise.all([finished0, finished1]); - dispatchFirstElementEvent(canvas1, 'pointerover'); - dispatchFirstElementEvent(canvas2, 'pointerover'); + dispatchFirstElementEvent(canvas1, 'pointermove'); + dispatchFirstElementEvent(canvas2, 'pointermove'); expect( Array.from(document.body.getElementsByClassName('g2-tooltip')).length, ).toBe(2); diff --git a/__tests__/plots/interaction/stateages-interval-highlight-group-background.ts b/__tests__/plots/interaction/stateages-interval-highlight-group-background.ts index 9d1b94e339..606c2fe1b3 100644 --- a/__tests__/plots/interaction/stateages-interval-highlight-group-background.ts +++ b/__tests__/plots/interaction/stateages-interval-highlight-group-background.ts @@ -44,7 +44,7 @@ stateAgesIntervalHighlightGroupBackground.steps = ({ canvas }) => { { skip: true, changeState: () => { - e1.background.dispatchEvent(new CustomEvent('pointerover')); + e1.background.dispatchEvent(new CustomEvent('pointermove')); }, }, step(e2, 'pointerover'), diff --git a/__tests__/plots/tooltip/alphabet-interval-tooltip-render-update.ts b/__tests__/plots/tooltip/alphabet-interval-tooltip-render-update.ts index f92f3df452..3a508673d4 100644 --- a/__tests__/plots/tooltip/alphabet-interval-tooltip-render-update.ts +++ b/__tests__/plots/tooltip/alphabet-interval-tooltip-render-update.ts @@ -41,14 +41,14 @@ alphabetIntervalTooltipRenderUpdate.steps = ({ canvas }) => { await sleep(100); const elements = document.getElementsByClassName(ELEMENT_CLASS_NAME); const [e0] = elements; - e0.dispatchEvent(new CustomEvent('pointerover')); + e0.dispatchEvent(new CustomEvent('pointermove')); }, }, { changeState: async () => { const elements = document.getElementsByClassName(ELEMENT_CLASS_NAME); const [e0] = elements; - e0.dispatchEvent(new CustomEvent('pointerover')); + e0.dispatchEvent(new CustomEvent('pointermove')); }, }, ]; diff --git a/__tests__/plots/tooltip/flare-treemap-poptip.ts b/__tests__/plots/tooltip/flare-treemap-poptip.ts index 7dce6d5b8f..c5ce5487cd 100644 --- a/__tests__/plots/tooltip/flare-treemap-poptip.ts +++ b/__tests__/plots/tooltip/flare-treemap-poptip.ts @@ -69,7 +69,7 @@ flareTreemapPoptip.steps = ({ canvas }) => { }, { changeState: async () => { - rectangle?.dispatchEvent(new CustomEvent('pointerout')); + rectangle?.dispatchEvent(new CustomEvent('pointerleave')); }, skip: true, }, diff --git a/__tests__/plots/tooltip/profit-interval-legend-filter-ordinal.ts b/__tests__/plots/tooltip/profit-interval-legend-filter-ordinal.ts index c413c6c6c1..ddc35debdf 100644 --- a/__tests__/plots/tooltip/profit-interval-legend-filter-ordinal.ts +++ b/__tests__/plots/tooltip/profit-interval-legend-filter-ordinal.ts @@ -37,7 +37,7 @@ profitIntervalLegendFilterOrdinal.steps = ({ canvas }) => { changeState: async () => { const elements = document.getElementsByClassName(ELEMENT_CLASS_NAME); const [e0] = elements; - e0.dispatchEvent(new CustomEvent('pointerover')); + e0.dispatchEvent(new CustomEvent('pointermove')); }, }, ]; diff --git a/__tests__/plots/tooltip/utils.ts b/__tests__/plots/tooltip/utils.ts index df3d05899d..f95245de50 100644 --- a/__tests__/plots/tooltip/utils.ts +++ b/__tests__/plots/tooltip/utils.ts @@ -25,7 +25,7 @@ export function tooltipSteps(...index) { const elements = document.getElementsByClassName(ELEMENT_CLASS_NAME); const steps = index.map((i) => ({ changeState: async () => { - elements[i].dispatchEvent(new CustomEvent('pointerover')); + elements[i].dispatchEvent(new CustomEvent('pointermove')); }, })); return steps; @@ -40,7 +40,7 @@ export function tooltipStepsByMarkType(markType, ...index) { ); const steps = index.map((i) => ({ changeState: async () => { - elements[i].dispatchEvent(new CustomEvent('pointerover')); + elements[i].dispatchEvent(new CustomEvent('pointermove')); }, })); return steps; diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index 18c1dcc816..5bc4fcee50 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -438,7 +438,7 @@ export function seriesTooltip( groupName, emitter, wait = 50, - leading = false, + leading = true, trailing = false, startX = 0, startY = 0, @@ -860,7 +860,7 @@ export function tooltip( const addEventListeners = () => { if (!disableNative) { - console.log(111, 'addEventListeners'); + // root.addEventListener('pointerover', pointerover); root.addEventListener('pointermove', pointerover); // Only emit pointerleave event when the pointer is not in the root area. // !! !DO NOT USE pointerout event, it will emit when the pointer is in the child area. @@ -870,6 +870,7 @@ export function tooltip( const removeEventListeners = () => { if (!disableNative) { + // root.removeEventListener('pointerover', pointerover); root.removeEventListener('pointermove', pointerover); root.removeEventListener('pointerleave', pointerleave); } From 8ec7eec9ab824ad07d8e53a512c5e23b3d01d8ae Mon Sep 17 00:00:00 2001 From: hustcc Date: Mon, 11 Dec 2023 17:48:06 +0800 Subject: [PATCH 4/5] chroe: update component version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 79780dfab0..7e2c9d4600 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "animation" ], "dependencies": { - "@antv/component": "^1.0.0", + "@antv/component": "^1.0.1-beta.0", "@antv/coord": "^0.4.6", "@antv/event-emitter": "^0.1.3", "@antv/g": "^5.18.19", From cbe1013172124199ee42a31ea849f46655bd0225 Mon Sep 17 00:00:00 2001 From: hustcc Date: Tue, 12 Dec 2023 09:37:04 +0800 Subject: [PATCH 5/5] fix: code review and renmae pointover to pointmove --- src/interaction/tooltip.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index 5bc4fcee50..be47d96f33 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -797,7 +797,7 @@ export function tooltip( const elementSet = new Set(elements); const keyGroup = group(elements, groupKey); - const pointerover = throttle( + const pointermove = throttle( (event) => { const { target: element } = event; if (!elementSet.has(element)) { @@ -860,18 +860,16 @@ export function tooltip( const addEventListeners = () => { if (!disableNative) { - // root.addEventListener('pointerover', pointerover); - root.addEventListener('pointermove', pointerover); + root.addEventListener('pointermove', pointermove); // Only emit pointerleave event when the pointer is not in the root area. - // !! !DO NOT USE pointerout event, it will emit when the pointer is in the child area. + // !!!DO NOT USE pointerout event, it will emit when the pointer is in the child area. root.addEventListener('pointerleave', pointerleave); } }; const removeEventListeners = () => { if (!disableNative) { - // root.removeEventListener('pointerover', pointerover); - root.removeEventListener('pointermove', pointerover); + root.removeEventListener('pointermove', pointermove); root.removeEventListener('pointerleave', pointerleave); } }; @@ -882,7 +880,7 @@ export function tooltip( if (!element) return; const bbox = element.getBBox(); const { x, y, width, height } = bbox; - pointerover({ + pointermove({ target: element, offsetX: x + width / 2, offsetY: y + height / 2,