Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(animation): update non-transform attribute and replace node without animation #5019

Merged
merged 3 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions __tests__/integration/api-chart-render-update-attribute.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { chartRenderUpdateAttributes as render } from '../plots/api/chart-render-update-attributes';
import { createNodeGCanvas } from './utils/createNodeGCanvas';
import { kebabCase } from './utils/kebabCase';
import './utils/useCustomFetch';
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();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { chartRenderUpdateNonAnimation as render } from '../plots/api/chart-render-update-non-animation';
import { createNodeGCanvas } from './utils/createNodeGCanvas';
import { kebabCase } from './utils/kebabCase';
import './utils/useCustomFetch';
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, button, ...rest } = render({
canvas,
container: document.createElement('div'),
});
await finished;

button.dispatchEvent(new CustomEvent('click'));
await refreshed;
await expect(canvas).toMatchCanvasSnapshot(dir, 'step0');
});

afterAll(() => {
canvas?.destroy();
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions __tests__/plots/api/chart-render-update-attributes.ts
Original file line number Diff line number Diff line change
@@ -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 };
}
53 changes: 53 additions & 0 deletions __tests__/plots/api/chart-render-update-non-animation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Chart } from '../../../src';

export function chartRenderUpdateNonAnimation(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: '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',
y: 'sold',
},
animate: false,
};

chart.options(options);

const finished = chart.render();

let resolve;
const refreshed = new Promise((r) => (resolve = r));

button.onclick = () => {
chart.options({
...options,
type: 'point',
});
chart.render().then(resolve);
};

return { chart, button, finished, refreshed };
}
2 changes: 2 additions & 0 deletions __tests__/plots/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ 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';
export { chartRenderUpdateNonAnimation } from './chart-render-update-non-animation';
5 changes: 5 additions & 0 deletions src/animation/morphing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/plot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,10 @@ async function plotView(
maybeFacetElement(this, parent, origin);
const node = shapeFunction(data, index);
const animation = updateFunction(data, [this], [node]);
if (animation === null) copyAttributes(this, node);
if (animation === null) {
if (this.nodeName === node.nodeName) copyAttributes(this, node);
else this.parentNode.replaceChild(node, this);
}
return animation;
});
}),
Expand Down
2 changes: 1 addition & 1 deletion src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -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<T>(x: T): T {
return x;
Expand Down