Skip to content

Commit

Permalink
feat(interaction): emit brush axis highlight (#5132)
Browse files Browse the repository at this point in the history
  • Loading branch information
pearmini authored Jun 1, 2023
1 parent 36b9b02 commit 534c1ef
Show file tree
Hide file tree
Showing 22 changed files with 714 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { chartEmitBrushHighlightAxisCross as render } from '../plots/api/chart-emit-brush-highlight-axis-cross';
import { dblclick, brush } from '../plots/interaction/penguins-point-brush';
import { AXIS_HOT_AREA_CLASS_NAME } from '../../src/interaction/brushAxisHighlight';
import { createNodeGCanvas } from './utils/createNodeGCanvas';
import { createPromise, getElementByClassName } from './utils/event';
import { sleep } from './utils/sleep';
import { kebabCase } from './utils/kebabCase';
import './utils/useCustomFetch';
import './utils/useSnapshotMatchers';

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

it('chart.emit("brushAxis:highlight", callback) should emit events.', async () => {
const { chart, finished } = render({
canvas,
container: document.createElement('div'),
});
await finished;
await sleep(20);

// chart.emit('brushAxis:highlight', options) should trigger slider.
chart.emit('brushAxis:highlight', {
data: {
selection: [
[40, 50],
[14, 18],
],
},
});
await sleep(20);
await expect(canvas).toMatchCanvasSnapshot(dir, 'step0');

// chart.emit('brushAxis:remove', options) should reset.
chart.emit('brushAxis:remove', {});
await sleep(20);
await expect(canvas).toMatchCanvasSnapshot(dir, 'step1');

chart.off();

const axis = getElementByClassName(canvas, AXIS_HOT_AREA_CLASS_NAME);

// chart.on("brushAxis:highlight") should receive expected data.
const [highlight, resolveHighlight] = createPromise();
chart.on('brushAxis:highlight', (event) => {
if (!event.nativeEvent) return;
expect(event.data.selection).toEqual([
[32.1, 59.6],
[13.1, 21.5],
]);
resolveHighlight();
});
brush(axis, -Infinity, 50, Infinity, 400);
await sleep(20);
await highlight;

// chart.on("brushAxis:remove") should be called.
const [remove, resolveRemove] = createPromise();
chart.on('brushAxis:remove', (event) => {
if (!event.nativeEvent) return;
resolveRemove();
});
dblclick(axis);
await sleep(20);
await remove;
});

afterAll(() => {
canvas?.destroy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { chartEmitBrushHighlightAxisHorizontal as render } from '../plots/api/chart-emit-brush-highlight-axis-horizontal';
import { dblclick, brush } from '../plots/interaction/penguins-point-brush';
import { AXIS_HOT_AREA_CLASS_NAME } from '../../src/interaction/brushAxisHighlight';
import { createNodeGCanvas } from './utils/createNodeGCanvas';
import { createPromise, getElementByClassName } from './utils/event';
import { sleep } from './utils/sleep';
import { kebabCase } from './utils/kebabCase';
import './utils/useCustomFetch';
import './utils/useSnapshotMatchers';

describe('chart.on', () => {
const dir = `${__dirname}/snapshots/api/${kebabCase(render.name)}`;
const canvas = createNodeGCanvas(640, 800);

it('chart.emit("brushAxis:highlight", callback) should emit events.', async () => {
const { chart, finished } = render({
canvas,
container: document.createElement('div'),
});
await finished;
await sleep(20);

// chart.emit('brushAxis:highlight', options) should trigger slider.
chart.emit('brushAxis:highlight', {
data: { selection: [[20, 30], undefined, [100, 300]] },
});
await sleep(20);
await expect(canvas).toMatchCanvasSnapshot(dir, 'step0');

// chart.emit('brushAxis:remove', options) should reset.
chart.emit('brushAxis:remove', {});
await sleep(20);
await expect(canvas).toMatchCanvasSnapshot(dir, 'step1');

chart.off();

const axis = getElementByClassName(canvas, AXIS_HOT_AREA_CLASS_NAME);

// chart.on("brushAxis:highlight") should receive expected data.
const [highlight, resolveHighlight] = createPromise();
chart.on('brushAxis:highlight', (event) => {
if (!event.nativeEvent) return;
expect(event.data.selection).toEqual([
[11, 33],
[3, 8],
[68, 455],
[46, 230],
[1613, 5140],
[8, 24.8],
[70, 82],
]);
resolveHighlight();
});
brush(axis, 50, -Infinity, 400, Infinity);
await sleep(20);
await highlight;

// chart.on("brushAxis:remove") should be called.
const [remove, resolveRemove] = createPromise();
chart.on('brushAxis:remove', (event) => {
if (!event.nativeEvent) return;
resolveRemove();
});
dblclick(axis);
await sleep(20);
await remove;
});

afterAll(() => {
canvas?.destroy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { chartEmitBrushHighlightAxisVertical as render } from '../plots/api/chart-emit-brush-highlight-axis-vertical';
import { dblclick, brush } from '../plots/interaction/penguins-point-brush';
import { AXIS_HOT_AREA_CLASS_NAME } from '../../src/interaction/brushAxisHighlight';
import { createNodeGCanvas } from './utils/createNodeGCanvas';
import { createPromise, getElementByClassName } from './utils/event';
import { sleep } from './utils/sleep';
import { kebabCase } from './utils/kebabCase';
import './utils/useCustomFetch';
import './utils/useSnapshotMatchers';

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

it('chart.emit("brushAxis:highlight", callback) should emit events.', async () => {
const { chart, finished } = render({
canvas,
container: document.createElement('div'),
});
await finished;
await sleep(20);

// chart.emit('brushAxis:highlight', options) should trigger slider.
chart.emit('brushAxis:highlight', {
data: { selection: [[20, 30], undefined, [100, 300]] },
});
await sleep(20);
await expect(canvas).toMatchCanvasSnapshot(dir, 'step0');

// chart.emit('brushAxis:remove', options) should reset.
chart.emit('brushAxis:remove', {});
await sleep(20);
await expect(canvas).toMatchCanvasSnapshot(dir, 'step1');

chart.off();

const axis = getElementByClassName(canvas, AXIS_HOT_AREA_CLASS_NAME);

// chart.on("brushAxis:highlight") should receive expected data.
const [highlight, resolveHighlight] = createPromise();
chart.on('brushAxis:highlight', (event) => {
if (!event.nativeEvent) return;
expect(event.data.selection).toEqual([
[14, 44.6],
[3, 8],
[68, 455],
[46, 230],
[1613, 5140],
[8, 24.8],
[70, 82],
]);
resolveHighlight();
});
brush(axis, -Infinity, 50, Infinity, 400);
await sleep(20);
await highlight;

// chart.on("brushAxis:remove") should be called.
const [remove, resolveRemove] = createPromise();
chart.on('brushAxis:remove', (event) => {
if (!event.nativeEvent) return;
resolveRemove();
});
dblclick(axis);
await sleep(20);
await remove;
});

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.
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.
4 changes: 4 additions & 0 deletions __tests__/integration/utils/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ export function dispatchFirstShapeEvent(canvas, className, event, params?) {
const [shape] = canvas.document.getElementsByClassName(className);
shape.dispatchEvent(new CustomEvent(event, params));
}

export function getElementByClassName(canvas, className) {
return canvas.document.getElementsByClassName(className)[0];
}
70 changes: 70 additions & 0 deletions __tests__/plots/api/chart-emit-brush-highlight-axis-cross.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Chart } from '../../../src';

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

// button
const button1 = document.createElement('button');
button1.innerText = 'Highlight';
container.appendChild(button1);

const button2 = document.createElement('button');
button2.innerText = 'Reset';
container.appendChild(button2);

// wrapperDiv
const wrapperDiv = document.createElement('div');
container.appendChild(wrapperDiv);

const chart = new Chart({
theme: 'classic',
container: wrapperDiv,
canvas,
});

chart.options({
type: 'point',
data: {
type: 'fetch',
value: 'data/penguins.csv',
},
encode: {
color: 'species',
x: 'culmen_length_mm',
y: 'culmen_depth_mm',
},
state: { inactive: { stroke: 'gray', opacity: 0.5 } },
interaction: {
brushAxisHighlight: true,
},
});

const finished = chart.render();

chart.on('brushAxis:highlight', (event) => {
const { data, nativeEvent } = event;
if (nativeEvent) console.log('brushAxis:highlight', data);
});

chart.on('brushAxis:remove', (event) => {
const { data, nativeEvent } = event;
if (nativeEvent) console.log('brushAxis:remove', data);
});

button1.onclick = () => {
chart.emit('brushAxis:highlight', {
data: {
selection: [
[40, 50],
[14, 18],
],
},
});
};

button2.onclick = () => {
chart.emit('brushAxis:remove', {});
};

return { chart, finished };
}
Loading

0 comments on commit 534c1ef

Please sign in to comment.