Skip to content

Commit

Permalink
update component click event (#5440)
Browse files Browse the repository at this point in the history
  • Loading branch information
BinghuiXie authored Aug 23, 2023
1 parent 67ee516 commit 01ab11a
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 9 deletions.
72 changes: 72 additions & 0 deletions __tests__/integration/api-chart-on-component-click.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { chartOnComponentClick as render } from '../plots/api/chart-on-component-click';
import { createDOMGCanvas } from './utils/createDOMGCanvas';
import { dispatchFirstShapeEvent, createPromise } from './utils/event';
import './utils/useSnapshotMatchers';
import { ChartEvent } from '../../src';

describe('chart.on', () => {
const canvas = createDOMGCanvas(640, 480);
const { finished, chart } = render({ canvas });

chart.off();

it('chart.on("component:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`component:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'component', 'click', { detail: 1 });
await fired;
});

it('chart.on("legend-category:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`legend-category:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'legend-category', 'click', { detail: 1 });
await fired;
});

it('chart.on("legend-category-item-marker:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`legend-category-item-marker:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'legend-category-item-marker', 'click', { detail: 1 });
await fired;
});

it('chart.on("legend-category-item-label:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`legend-category-item-label:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'legend-category-item-label', 'click', { detail: 1 });
await fired;
});

it('chart.on("grid-line:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`grid-line:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'grid-line', 'click', { detail: 1 });
await fired;
});

it('chart.on("axis-tick-item:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`axis-tick-item:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'axis-tick-item', 'click', { detail: 1 });
await fired;
});

it('chart.on("axis-label-item:click", callback) should emit events', async () => {
await finished;
const [fired, resolve] = createPromise();
chart.on(`axis-label-item:${ChartEvent.CLICK}`, resolve);
dispatchFirstShapeEvent(canvas, 'axis-label-item', 'click', { detail: 1 });
await fired;
});

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

const componentNames = [
// legend group
'legend-category',
// legend item marker
'legend-category-item-marker',
// legend item label
'legend-category-item-label',
// axis
'grid-line',
// tick
'axis-tick-item',
// axis label
'axis-label-item'
]

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

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

chart
.interval()
.data([
{ month: 'Jan.', profit: 387264, start: 0, end: 387264 },
{ month: 'Feb.', profit: 772096, start: 387264, end: 1159360 },
{ month: 'Mar.', profit: 638075, start: 1159360, end: 1797435 },
{ month: 'Apr.', profit: -211386, start: 1797435, end: 1586049 },
{ month: 'May', profit: -138135, start: 1586049, end: 1447914 },
{ month: 'Jun', profit: -267238, start: 1447914, end: 1180676 },
{ month: 'Jul.', profit: 431406, start: 1180676, end: 1612082 },
{ month: 'Aug.', profit: 363018, start: 1612082, end: 1975100 },
{ month: 'Sep.', profit: -224638, start: 1975100, end: 1750462 },
{ month: 'Oct.', profit: -299867, start: 1750462, end: 1450595 },
{ month: 'Nov.', profit: 607365, start: 1450595, end: 2057960 },
{ month: 'Dec.', profit: 1106986, start: 2057960, end: 3164946 },
{ month: 'Total', start: 0, end: 3164946 },
])
.encode('x', 'month')
.encode('y', ['end', 'start'])
.encode('color', (d) =>
d.month === 'Total' ? 'Total' : d.profit > 0 ? 'Increase' : 'Decrease',
)
.axis('y', { labelFormatter: '~s' })
.tooltip(['start', 'end']);

chart.on('component:click', () => console.log('click component'));

componentNames.forEach(name => {
chart.on(`${name}:click`, () => console.log(`click ${name}`));
})

const finished = chart.render();

return { chart, finished };
}
1 change: 1 addition & 0 deletions __tests__/plots/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export { chartEmitClickTooltip } from './chart-emit-click-tooltip';
export { chartChangeDataLegend } from './chart-change-data-legend';
export { chartTooltipMultiChart } from './chart-tooltip-multi-chart';
export { chartOnTextClick } from './chart-on-text-click';
export { chartOnComponentClick } from './chart-on-component-click';
export { chartRenderEvent } from './chart-render-event';
export { chartRender3dScatterPlot } from './chart-render-3d-scatter-plot';
export { chartRender3dScatterPlotPerspective } from './chart-render-3d-scatter-plot-perspective';
Expand Down
7 changes: 7 additions & 0 deletions site/docs/manual/extra-topics/event.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ chart.on(`interval:${ChartEvent.CLICK}`, (ev) => {
chart.on('plot:click', (event) => console.log(event));
```


- 监听全局 component 事件

```js
chart.on('component:click', (event) => console.log(event));
```

### 点击事件

| 事件名 | 说明 | 回调参数 |
Expand Down
31 changes: 22 additions & 9 deletions src/interaction/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ export function dataOf(element, view) {
return selectedMark.data[index];
}

// For extended shape.
function maybeElementRoot(node) {
if (node.className === 'element') return node;
function maybeRoot(node, rootOf) {
if (rootOf(node)) return node;
let root = node.parent;
while (root && root.className !== 'element') root = root.parent;
while (root && !rootOf(root)) root = root.parent;
return root;
}

// For extended component
function maybeComponentRoot(node) {
return maybeRoot(node, node => node.className === 'component');
}

// For extended shape.
function maybeElementRoot(node) {
return maybeRoot(node, node => node.className === 'element');
}

function bubblesEvent(eventType, view, emitter, predicate = (event) => true) {
return (e) => {
if (!predicate(e)) return;
Expand All @@ -41,19 +50,23 @@ function bubblesEvent(eventType, view, emitter, predicate = (event) => true) {

// If target is element or child of element.
const elementRoot = maybeElementRoot(target);
if (!elementRoot) return;
const { className: elementType, markType } = elementRoot;
// If target is component or child of component.
const componentRoot = maybeComponentRoot(target);
const root = elementRoot || componentRoot;
if (!root) return;
const { className: elementType, markType } = root;
if (elementType === 'element') {
const e1 = {
...e,
nativeEvent: true,
data: { data: dataOf(elementRoot, view) },
data: { data: dataOf(root, view) },
};
emitter.emit(`element:${eventType}`, e1);
emitter.emit(`${markType}:${eventType}`, e1);
} else {
// @todo Handle click axis and legend.
emitter.emit(`${elementType}:${eventType}`, e);
const e1 = {...e, nativeEvent: true };
emitter.emit(`component:${eventType}`, e1);
emitter.emit(`${className}:${eventType}`, e1);
}
};
}
Expand Down

0 comments on commit 01ab11a

Please sign in to comment.