Skip to content

Commit

Permalink
fix(interaction): interaction can be clear
Browse files Browse the repository at this point in the history
  • Loading branch information
pearmini committed May 25, 2023
1 parent bbfe665 commit 0b46a2b
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 19 deletions.
35 changes: 35 additions & 0 deletions __tests__/integration/api-chart-render-clear-interaction.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { CustomEvent as GCustomEvent } from '@antv/g';
import { chartRenderClearInteraction as render } from '../plots/api/chart-render-clear-interaction';
import { PLOT_CLASS_NAME } from '../../src';
import { createDOMGCanvas } from './utils/createDOMGCanvas';
import './utils/useSnapshotMatchers';
import './utils/useCustomFetch';

describe('chart.render', () => {
const dir = `${__dirname}/snapshots/api`;
const canvas = createDOMGCanvas(640, 480);

it('chart.interaction(name, false) should clear interaction.', async () => {
const { finished } = render({
canvas,
container: document.createElement('div'),
});
await finished;

// Trigger tooltip
const plot = canvas.document.getElementsByClassName(PLOT_CLASS_NAME)[0];
plot.dispatchEvent(
new GCustomEvent('pointermove', {
offsetX: 200,
offsetY: 300,
}),
);
await expect(canvas).toMatchDOMSnapshot(dir, render.name, {
selector: '.g2-tooltip',
});
});

afterAll(() => {
canvas?.destroy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
null
31 changes: 31 additions & 0 deletions __tests__/plots/api/chart-render-clear-interaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Chart } from '../../../src';

export function chartRenderClearInteraction(context) {
const { container, canvas } = context;

const chart = new Chart({
container,
canvas,
});

chart.options({
theme: 'classic',
type: 'line',
clip: true,
data: {
type: 'fetch',
value: 'data/aapl.csv',
},
encode: {
x: 'date',
y: 'close',
},
});

const finished = chart.render().then(() => {
chart.options({ interaction: { tooltip: false } });
return chart.render();
});

return { chart, finished };
}
61 changes: 42 additions & 19 deletions src/runtime/plot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,17 @@ export async function plot<T extends G2ViewTree>(
target.container['nameInteraction'] = nameInteraction;

// Apply interactions.
for (const option of inferInteraction(options)) {
const interaction = useInteraction(option);
const destroy = interaction(target, enterViewInstances, context.emitter);
nameInteraction.set(option.type, { destroy });
for (const typeOption of inferInteraction(options)) {
const [type, option] = typeOption;
if (option) {
const interaction = useInteraction({ type, ...(option as any) });
const destroy = interaction(
target,
enterViewInstances,
context.emitter,
);
nameInteraction.set(type, { destroy });
}
}
}

Expand All @@ -242,15 +249,23 @@ export async function plot<T extends G2ViewTree>(
for (const target of updateViewInstances) {
const { options, container } = target;
const nameInteraction = container['nameInteraction'];
for (const option of inferInteraction(options)) {
for (const typeOption of inferInteraction(options)) {
const [type, option] = typeOption;

// Remove interaction for existed views.
const prevInteraction = nameInteraction.get(option.type);
const prevInteraction = nameInteraction.get(type);
if (prevInteraction) prevInteraction.destroy?.();

// Apply new interaction.
const interaction = useInteraction(option);
const destroy = interaction(target, updateViewInstances, context.emitter);
nameInteraction.set(option.type, { destroy });
if (option) {
const interaction = useInteraction({ type, ...(option as any) });
const destroy = interaction(
target,
updateViewInstances,
context.emitter,
);
nameInteraction.set(type, { destroy });
}
}
}

Expand Down Expand Up @@ -314,7 +329,13 @@ function createUpdateView(
};
}

function updateTooltip(selection, options, view, library, context) {
function updateTooltip(
selection: Selection,
options: G2ViewTree,
view: G2ViewDescriptor,
library: G2Library,
context: G2Context,
) {
const [useInteraction] = useLibrary<
G2InteractionOptions,
InteractionComponent,
Expand All @@ -325,16 +346,21 @@ function updateTooltip(selection, options, view, library, context) {
const container = selection.node();
const nameInteraction = container['nameInteraction'];
const tooltipOptions = inferInteraction(options).find(
(d) => d.type === 'tooltip',
([d]) => d === 'tooltip',
);

// Destroy older tooltip.
const tooltip = nameInteraction.get('tooltip');
if (!tooltip) return;
tooltip.destroy?.();

if (!tooltipOptions[1]) return;

// Apply new tooltip interaction.
const applyTooltip = useInteraction(tooltipOptions);
const applyTooltip = useInteraction({
type: 'tooltip',
...(tooltipOptions[1] as any),
});
const target = {
options,
view,
Expand Down Expand Up @@ -1351,7 +1377,9 @@ function inferTheme(theme: G2ThemeOptions = {}): G2ThemeOptions {
/**
* @todo Infer builtin tooltips.
*/
function inferInteraction(view: G2View): G2InteractionOptions[] {
function inferInteraction(
view: G2View,
): [string, boolean | Omit<G2InteractionOptions, 'type'>][] {
const defaults = {
event: true,
tooltip: true,
Expand All @@ -1360,12 +1388,7 @@ function inferInteraction(view: G2View): G2InteractionOptions[] {
legendFilter: true,
};
const { interaction = {} } = view;
return Object.entries(deepMix(defaults, interaction))
.filter((d) => !!d[1])
.map(([key, value]) => ({
type: key,
...(value as Record<string, any>),
}));
return Object.entries(deepMix(defaults, interaction));
}

async function applyTransform<T extends G2ViewTree>(
Expand Down

0 comments on commit 0b46a2b

Please sign in to comment.