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 new file mode 100644 index 0000000000..cfe90c1551 --- /dev/null +++ b/__tests__/integration/api-chart-emit-item-tooltip-hide-content.spec.ts @@ -0,0 +1,31 @@ +import { chartEmitItemTooltipHideContent as render } from '../plots/api/chart-emit-item-tooltip-hide-content'; +import './utils/useSnapshotMatchers'; +import { + dispatchFirstElementEvent, + createPromise, + receiveExpectData, +} from './utils/event'; +import { createDOMGCanvas } from './utils/createDOMGCanvas'; + +describe('chart.emit', () => { + const canvas = createDOMGCanvas(800, 500); + + it('chart.tooltip hide body should emit events.', async () => { + const { finished, chart, clear } = render({ + canvas, + container: document.createElement('div'), + }); + await finished; + clear(); + + // chart.on("tooltip:hide") should be called when hiding tooltip. + const [tooltipHided, resolveHide] = createPromise(); + chart.on('tooltip:hide', receiveExpectData(resolveHide, null)); + dispatchFirstElementEvent(canvas, 'pointerout'); + await tooltipHided; + }); + + afterAll(() => { + canvas?.destroy(); + }); +}); diff --git a/__tests__/plots/api/chart-emit-item-tooltip-hide-content.ts b/__tests__/plots/api/chart-emit-item-tooltip-hide-content.ts new file mode 100644 index 0000000000..54fd43b161 --- /dev/null +++ b/__tests__/plots/api/chart-emit-item-tooltip-hide-content.ts @@ -0,0 +1,70 @@ +import { Chart } from '../../../src'; + +export function chartEmitItemTooltipHideContent(context) { + const { container, canvas } = context; + + // wrapperDiv + const wrapperDiv = document.createElement('div'); + container.appendChild(wrapperDiv); + + // button + const button = document.createElement('button'); + button.innerText = 'Hide tooltip'; + container.appendChild(button); + + // p + const p = document.createElement('p'); + p.innerText = ''; + container.appendChild(p); + + const chart = new Chart({ + theme: 'classic', + container: wrapperDiv, + canvas, + }); + + chart + .interval() + .data([ + { genre: 'Sports', sold: 275 }, + { genre: 'Strategy', sold: 115 }, + { genre: 'Action', sold: 120 }, + { genre: 'Shooter', sold: 350 }, + { genre: 'Other', sold: 150 }, + ]) + .encode('x', 'genre') + .encode('y', 'sold') + .encode('color', 'genre') + .interaction('tooltip', { + body: false, + }); + + const finished = chart.render(); + + finished.then((chart) => + chart.emit('tooltip:show', { + data: { data: { sold: 115 } }, + }), + ); + + chart.on('tooltip:show', ({ data }) => { + p.innerText = JSON.stringify(data); + }); + + const hide = () => (p.innerText = 'null'); + + chart.on('tooltip:hide', hide); + + button.onclick = () => { + chart.emit('tooltip:hide'); + }; + + return { + chart, + button, + finished, + clear: () => { + chart.off('tooltip:hide', hide); + }, + }; +} diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts index e0306a6267..b89203f4cf 100644 --- a/__tests__/plots/api/index.ts +++ b/__tests__/plots/api/index.ts @@ -35,3 +35,4 @@ export { chartEmitBrushHighlightAxisHorizontal } from './chart-emit-brush-highli export { chartEmitBrushHighlightAxisCross } from './chart-emit-brush-highlight-axis-cross'; export { chartEmitScrollbarFilter } from './chart-emit-scrollbar-filter'; export { chartOptionsCompositeMark } from './chart-options-composite-mark'; +export { chartEmitItemTooltipHideContent } from './chart-emit-item-tooltip-hide-content'; diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index ea034b41ee..6f526ccde9 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -138,13 +138,13 @@ function showTooltip({ } function hideTooltip({ root, single, emitter, nativeEvent = true, mount }) { + if (nativeEvent) { + emitter.emit('tooltip:hide', { nativeEvent }); + } const container = single ? getContainer(root, mount) : root; const { tooltipElement } = container; if (tooltipElement) { tooltipElement.hide(); - if (nativeEvent) { - emitter.emit('tooltip:hide', { nativeEvent }); - } } } @@ -640,6 +640,7 @@ export function tooltip( view, mount, bounding, + body = true, }: Record, ) { const elements = elementsof(root); @@ -674,19 +675,21 @@ export function tooltip( } const { offsetX, offsetY } = event; - showTooltip({ - root, - data, - x: offsetX, - y: offsetY, - render, - event, - single, - position, - enterable, - mount, - bounding, - }); + if (body) { + showTooltip({ + root, + data, + x: offsetX, + y: offsetY, + render, + event, + single, + position, + enterable, + mount, + bounding, + }); + } emitter.emit('tooltip:show', { ...event,