From 40ef07590ae808625985aaaebb7d6946154ab03f Mon Sep 17 00:00:00 2001 From: MiniPear Date: Thu, 18 May 2023 17:15:10 +0800 Subject: [PATCH] fix(brush): rerender don't emit brush:end --- .../api-chart-render-brush-end.spec.ts | 30 ++++++++ __tests__/plots/api/chart-render-brush-end.ts | 71 +++++++++++++++++++ __tests__/plots/api/index.ts | 1 + src/interaction/brushHighlight.ts | 7 +- 4 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 __tests__/integration/api-chart-render-brush-end.spec.ts create mode 100644 __tests__/plots/api/chart-render-brush-end.ts diff --git a/__tests__/integration/api-chart-render-brush-end.spec.ts b/__tests__/integration/api-chart-render-brush-end.spec.ts new file mode 100644 index 0000000000..df858ef3e2 --- /dev/null +++ b/__tests__/integration/api-chart-render-brush-end.spec.ts @@ -0,0 +1,30 @@ +import { chartRenderBrushEnd as render } from '../plots/api/chart-render-brush-end'; +import { createNodeGCanvas } from './utils/createNodeGCanvas'; +import { sleep } from './utils/sleep'; + +describe('chart.render', () => { + const canvas = createNodeGCanvas(800, 500); + + it('chart.render() should not emit brush:end', async () => { + const { rerendered, finished, button, chart } = render({ + canvas, + container: document.createElement('div'), + }); + await finished; + await sleep(20); + + chart.off(); + const fn = jest.fn(); + chart.on('brush:end', () => { + fn(); + }); + button.dispatchEvent(new CustomEvent('click')); + await rerendered; + await sleep(20); + expect(fn).toBeCalledTimes(0); + }); + + afterAll(() => { + canvas?.destroy(); + }); +}); diff --git a/__tests__/plots/api/chart-render-brush-end.ts b/__tests__/plots/api/chart-render-brush-end.ts new file mode 100644 index 0000000000..41ec2d20bb --- /dev/null +++ b/__tests__/plots/api/chart-render-brush-end.ts @@ -0,0 +1,71 @@ +import { Chart } from '../../../src'; + +export function chartRenderBrushEnd(context) { + const { container, canvas } = context; + + // button + const button = document.createElement('button'); + button.innerText = 'Render'; + container.appendChild(button); + + // wrapperDiv + const wrapperDiv = document.createElement('div'); + container.appendChild(wrapperDiv); + + const chart = new Chart({ + theme: 'classic', + container: wrapperDiv, + paddingBottom: 120, + width: 1000, + canvas, + }); + + chart.data([ + { date: '2001-01', value: 100 }, + { date: '2001-02', value: 400 }, + { date: '2001-03', value: 500 }, + { date: '2001-04', value: 600 }, + { date: '2001-05', value: 300 }, + { date: '2001-06', value: 600 }, + { date: '2001-07', value: 300 }, + { date: '2001-08', value: 600 }, + { date: '2001-09', value: 109 }, + { date: '2001-10', value: 100 }, + { date: '2001-11', value: 102 }, + { date: '2001-12', value: 103 }, + { date: '2002-01', value: 102 }, + { date: '2002-02', value: 101 }, + { date: '2002-03', value: 200 }, + { date: '2002-04', value: 500 }, + { date: '2002-05', value: 100 }, + { date: '2002-06', value: 100 }, + { date: '2002-07', value: 102 }, + { date: '2002-08', value: 109 }, + ]); + + chart + .interval() + .encode('x', 'date') + .encode('y', 'value') + .axis('x', { style: { labelTransform: 'rotate(90deg)' } }) + .interaction('brushXHighlight', true); + + const X = ['2001-01', '2001-03']; + + chart.on('brush:end', () => console.log('brush:end')); + + const finished = chart.render().then(() => { + chart.emit('brush:highlight', { + data: { selection: [X, [-Infinity, Infinity]] }, + }); + }); + + let resolve; + const rerendered = new Promise((r) => (resolve = r)); + + button.onclick = () => { + chart.render().then(resolve); + }; + + return { chart, button, finished, rerendered }; +} diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts index 47ec02d5f4..d73a20a58b 100644 --- a/__tests__/plots/api/index.ts +++ b/__tests__/plots/api/index.ts @@ -23,3 +23,4 @@ export { chartEmitPieTooltip } from './chart-emit-pie-tooltip'; export { chartRenderUpdateAttributes } from './chart-render-update-attributes'; export { chartRenderUpdateNonAnimation } from './chart-render-update-non-animation'; export { chartEmitBrushHighlightX } from './chart-emit-brush-highlight-x'; +export { chartRenderBrushEnd } from './chart-render-brush-end'; diff --git a/src/interaction/brushHighlight.ts b/src/interaction/brushHighlight.ts index 12b2ccf92d..1f673370d0 100644 --- a/src/interaction/brushHighlight.ts +++ b/src/interaction/brushHighlight.ts @@ -302,7 +302,7 @@ export function brush( }; // Remove mask and reset states. - const removeMask = () => { + const removeMask = (emit = true) => { if (mask) mask.remove(); if (background) background.remove(); start = null; @@ -311,7 +311,7 @@ export function brush( creating = false; mask = null; background = null; - brushended(); + if (emit) brushended(); }; // Update mask and invoke brushended callback. @@ -480,7 +480,8 @@ export function brush( if (mask) removeMask(); }, destroy() { - removeMask(); + // Do not emit brush:end event. + if (mask) removeMask(false); setCursor(root, 'default'); root.removeEventListener('dragstart', dragstart); root.removeEventListener('drag', drag);