From ee62215571283efd0747fb341b0793daafa74e3b Mon Sep 17 00:00:00 2001 From: MiniPear Date: Mon, 15 May 2023 09:55:12 +0800 Subject: [PATCH] fix(animation): update non-transform attribute (close: #4953) --- .../api-chart-render-update-attribute.spec.ts | 31 +++++++++ .../api/chart-render-update-attributes.ts | 67 +++++++++++++++++++ __tests__/plots/api/index.ts | 1 + src/animation/morphing.ts | 5 ++ src/utils/helper.ts | 2 +- 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 __tests__/integration/api-chart-render-update-attribute.spec.ts create mode 100644 __tests__/plots/api/chart-render-update-attributes.ts diff --git a/__tests__/integration/api-chart-render-update-attribute.spec.ts b/__tests__/integration/api-chart-render-update-attribute.spec.ts new file mode 100644 index 0000000000..e7cc479f22 --- /dev/null +++ b/__tests__/integration/api-chart-render-update-attribute.spec.ts @@ -0,0 +1,31 @@ +import { chartRenderUpdateAttributes as render } from '../plots/api/chart-render-update-attributes'; +import { createNodeGCanvas } from './utils/createNodeGCanvas'; +import { kebabCase } from './utils/kebabCase'; +import './utils/useSnapshotMatchers'; + +describe('chart.options.autoFit', () => { + const dir = `${__dirname}/snapshots/api/${kebabCase(render.name)}`; + const canvas = createNodeGCanvas(800, 500); + + it('chart({ autoFit: true }) should fit parent container', async () => { + const { finished, chart, refreshed, refreshed1, button, ...rest } = render({ + canvas, + container: document.createElement('div'), + }); + await finished; + + // To lineDash + button.dispatchEvent(new CustomEvent('click')); + await refreshed; + await expect(canvas).toMatchCanvasSnapshot(dir, 'step0'); + + // Reset + button.dispatchEvent(new CustomEvent('click')); + await refreshed1; + await expect(canvas).toMatchCanvasSnapshot(dir, 'step1'); + }); + + afterAll(() => { + canvas?.destroy(); + }); +}); diff --git a/__tests__/plots/api/chart-render-update-attributes.ts b/__tests__/plots/api/chart-render-update-attributes.ts new file mode 100644 index 0000000000..35e2f03608 --- /dev/null +++ b/__tests__/plots/api/chart-render-update-attributes.ts @@ -0,0 +1,67 @@ +import { Chart } from '../../../src'; + +export function chartRenderUpdateAttributes(context) { + const { container, canvas } = context; + + // button + const button = document.createElement('button'); + button.innerText = 'Rerender'; + container.appendChild(button); + + // wrapperDiv + const wrapperDiv = document.createElement('div'); + container.appendChild(wrapperDiv); + + const chart = new Chart({ + theme: 'classic', + container: wrapperDiv, + canvas, + }); + + const options = { + type: 'line', + data: { + type: 'fetch', + value: 'data/aapl.csv', + transform: [{ type: 'slice', start: 0, end: 10 }], + }, + encode: { + x: 'date', + y: 'close', + }, + }; + + chart.options(options); + + const finished = chart.render(); + + let resolve; + let resolve1; + const refreshed = new Promise((r) => (resolve = r)); + const refreshed1 = new Promise((r) => (resolve1 = r)); + + let lineDash = false; + button.onclick = () => { + if (lineDash) { + chart.options({ + ...options, + style: { + lineDash: null, + }, + }); + lineDash = false; + chart.render().then(resolve1); + } else { + chart.options({ + ...options, + style: { + lineDash: [5, 4], + }, + }); + lineDash = true; + chart.render().then(resolve); + } + }; + + return { chart, button, finished, refreshed, refreshed1 }; +} diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts index cdff32ca93..3a7fad70f0 100644 --- a/__tests__/plots/api/index.ts +++ b/__tests__/plots/api/index.ts @@ -20,3 +20,4 @@ export { chartOnFocusContext } from './chart-on-focus-context'; export { chartEmitItemTooltip } from './chart-emit-item-tooltip'; export { chartEmitSeriesTooltip } from './chart-emit-series-tooltip'; export { chartEmitPieTooltip } from './chart-emit-pie-tooltip'; +export { chartRenderUpdateAttributes } from './chart-render-update-attributes'; diff --git a/src/animation/morphing.ts b/src/animation/morphing.ts index 66a8a84ffd..9cbf34a595 100644 --- a/src/animation/morphing.ts +++ b/src/animation/morphing.ts @@ -5,6 +5,7 @@ import { Path, } from '@antv/g'; import { AnimationComponent as AC } from '../runtime'; +import { copyAttributes } from '../utils/helper'; import { Animation } from './types'; import { attributeKeys, attributeOf, effectTiming } from './utils'; @@ -181,6 +182,10 @@ function oneToOne( ]; const animation = pathShape.animate(keyframes, timeEffect); + animation.onfinish = () => { + copyAttributes(pathShape, to); + }; + // Remove transform because it already applied in path // converted by convertToPath. // @todo Remove this scale(1, 1) diff --git a/src/utils/helper.ts b/src/utils/helper.ts index 3a71ed4d48..b2036477a2 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -1,5 +1,5 @@ import { DisplayObject } from '@antv/g'; -import { lowerFirst, startsWith, upperFirst } from '@antv/util'; +import { lowerFirst, upperFirst } from '@antv/util'; export function identity(x: T): T { return x;