Skip to content

Commit 6a9b2a7

Browse files
authored
refactor: getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed (#845)
BREAKING CHANGE: getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed, utils with the same names can used instead
1 parent f7a81e6 commit 6a9b2a7

File tree

6 files changed

+100
-130
lines changed

6 files changed

+100
-130
lines changed

src/chart.tsx

+2-59
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useRef, forwardRef } from 'react';
2-
import type { ForwardedRef, MouseEvent } from 'react';
2+
import type { ForwardedRef } from 'react';
33
import { Chart as ChartJS } from 'chart.js';
44
import type { ChartType, DefaultDataPoint } from 'chart.js';
55

@@ -25,11 +25,7 @@ function ChartComponent<
2525
data,
2626
options,
2727
plugins = [],
28-
getDatasetAtEvent,
29-
getElementAtEvent,
30-
getElementsAtEvent,
3128
fallbackContent,
32-
onClick: onClickProp,
3329
...props
3430
}: ChartProps<TType, TData, TLabel>,
3531
ref: ForwardedRef<ChartJS<TType, TData, TLabel>>
@@ -61,52 +57,6 @@ function ChartComponent<
6157
}
6258
};
6359

64-
const onClick = (event: MouseEvent<HTMLCanvasElement>) => {
65-
if (onClickProp) {
66-
onClickProp(event);
67-
}
68-
69-
const { current: chart } = chartRef;
70-
71-
if (!chart) return;
72-
73-
if (getDatasetAtEvent) {
74-
getDatasetAtEvent(
75-
chart.getElementsAtEventForMode(
76-
event.nativeEvent,
77-
'dataset',
78-
{ intersect: true },
79-
false
80-
),
81-
event
82-
);
83-
}
84-
85-
if (getElementAtEvent) {
86-
getElementAtEvent(
87-
chart.getElementsAtEventForMode(
88-
event.nativeEvent,
89-
'nearest',
90-
{ intersect: true },
91-
false
92-
),
93-
event
94-
);
95-
}
96-
97-
if (getElementsAtEvent) {
98-
getElementsAtEvent(
99-
chart.getElementsAtEventForMode(
100-
event.nativeEvent,
101-
'index',
102-
{ intersect: true },
103-
false
104-
),
105-
event
106-
);
107-
}
108-
};
109-
11060
useEffect(() => {
11161
if (!redraw && chartRef.current && options) {
11262
setOptions(chartRef.current, options);
@@ -143,14 +93,7 @@ function ChartComponent<
14393
}, []);
14494

14595
return (
146-
<canvas
147-
ref={canvasRef}
148-
role='img'
149-
height={height}
150-
width={width}
151-
onClick={onClick}
152-
{...props}
153-
>
96+
<canvas ref={canvasRef} role='img' height={height} width={width} {...props}>
15497
{fallbackContent}
15598
</canvas>
15699
);

src/index.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
export type { ChartProps } from './types';
22
export * from './chart';
33
export * from './typedCharts';
4+
export {
5+
getDatasetAtEvent,
6+
getElementAtEvent,
7+
getElementsAtEvent,
8+
} from './utils';

src/types.ts

+1-19
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
import type {
2-
CanvasHTMLAttributes,
3-
ForwardedRef,
4-
ReactNode,
5-
MouseEvent,
6-
} from 'react';
1+
import type { CanvasHTMLAttributes, ForwardedRef, ReactNode } from 'react';
72
import type {
83
Chart,
94
ChartType,
105
ChartData,
116
ChartOptions,
127
DefaultDataPoint,
138
Plugin,
14-
InteractionItem,
159
} from 'chart.js';
1610

1711
export interface ChartProps<
@@ -28,18 +22,6 @@ export interface ChartProps<
2822
* @todo Replace with `children` prop.
2923
*/
3024
fallbackContent?: ReactNode;
31-
getDatasetAtEvent?: (
32-
dataset: InteractionItem[],
33-
event: MouseEvent<HTMLCanvasElement>
34-
) => void;
35-
getElementAtEvent?: (
36-
element: InteractionItem[],
37-
event: MouseEvent<HTMLCanvasElement>
38-
) => void;
39-
getElementsAtEvent?: (
40-
elements: InteractionItem[],
41-
event: MouseEvent<HTMLCanvasElement>
42-
) => void;
4325
}
4426

4527
/**

src/utils.ts

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ForwardedRef } from 'react';
1+
import type { ForwardedRef, MouseEvent } from 'react';
22
import type {
33
ChartType,
44
ChartData,
@@ -74,3 +74,57 @@ export function cloneData<
7474

7575
return nextData;
7676
}
77+
78+
/**
79+
* Get dataset from mouse click event
80+
* @param chart - Chart.js instance
81+
* @param event - Mouse click event
82+
* @returns Dataset
83+
*/
84+
export function getDatasetAtEvent(
85+
chart: Chart,
86+
event: MouseEvent<HTMLCanvasElement>
87+
) {
88+
return chart.getElementsAtEventForMode(
89+
event.nativeEvent,
90+
'dataset',
91+
{ intersect: true },
92+
false
93+
);
94+
}
95+
96+
/**
97+
* Get single dataset element from mouse click event
98+
* @param chart - Chart.js instance
99+
* @param event - Mouse click event
100+
* @returns Dataset
101+
*/
102+
export function getElementAtEvent(
103+
chart: Chart,
104+
event: MouseEvent<HTMLCanvasElement>
105+
) {
106+
return chart.getElementsAtEventForMode(
107+
event.nativeEvent,
108+
'nearest',
109+
{ intersect: true },
110+
false
111+
);
112+
}
113+
114+
/**
115+
* Get dataset element with dataset from mouse click event
116+
* @param chart - Chart.js instance
117+
* @param event - Mouse click event
118+
* @returns Dataset
119+
*/
120+
export function getElementsAtEvent(
121+
chart: Chart,
122+
event: MouseEvent<HTMLCanvasElement>
123+
) {
124+
return chart.getElementsAtEventForMode(
125+
event.nativeEvent,
126+
'index',
127+
{ intersect: true },
128+
false
129+
);
130+
}

stories/Chart.tsx

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
import React, { useState, useEffect, useReducer } from 'react';
1+
import React, {
2+
MouseEvent,
3+
useRef,
4+
useState,
5+
useEffect,
6+
useReducer,
7+
} from 'react';
28
import 'chart.js/auto';
3-
import { InteractionItem } from 'chart.js';
9+
import type { Chart as ChartJS, InteractionItem } from 'chart.js';
410
import 'chartjs-adapter-date-fns';
5-
import { Chart } from '../src';
11+
import {
12+
Chart,
13+
getDatasetAtEvent,
14+
getElementAtEvent,
15+
getElementsAtEvent,
16+
} from '../src';
617
import * as multitypeChart from '../sandboxes/chart/multitype/App';
718
import * as eventsChart from '../sandboxes/chart/events/App';
819
import * as data from './Chart.data';
@@ -52,37 +63,50 @@ export const ClickEvents = ({
5263
data,
5364
...args
5465
}) => {
55-
const getDatasetAtEvent = (dataset: InteractionItem[]) => {
66+
const datasetAtEvent = (dataset: InteractionItem[]) => {
5667
if (!dataset.length) return;
5768

5869
const datasetIndex = dataset[0].datasetIndex;
5970

6071
onDatasetClick(data.datasets[datasetIndex].label);
6172
};
6273

63-
const getElementAtEvent = (element: InteractionItem[]) => {
74+
const elementAtEvent = (element: InteractionItem[]) => {
6475
if (!element.length) return;
6576

6677
const { datasetIndex, index } = element[0];
6778

6879
onElementClick(data.labels[index], data.datasets[datasetIndex].data[index]);
6980
};
7081

71-
const getElementsAtEvent = (elements: InteractionItem[]) => {
82+
const elementsAtEvent = (elements: InteractionItem[]) => {
7283
if (!elements.length) return;
7384

7485
onElementsClick(elements);
7586
};
7687

88+
const chartRef = useRef<ChartJS>(null);
89+
90+
const onClick = (event: MouseEvent<HTMLCanvasElement>) => {
91+
const { current: chart } = chartRef;
92+
93+
if (!chart) {
94+
return;
95+
}
96+
97+
datasetAtEvent(getDatasetAtEvent(chart, event));
98+
elementAtEvent(getElementAtEvent(chart, event));
99+
elementsAtEvent(getElementsAtEvent(chart, event));
100+
};
101+
77102
return (
78103
<Chart
79104
{...args}
105+
ref={chartRef}
80106
type='bar'
81107
options={options}
82108
data={data}
83-
getDatasetAtEvent={getDatasetAtEvent}
84-
getElementAtEvent={getElementAtEvent}
85-
getElementsAtEvent={getElementsAtEvent}
109+
onClick={onClick}
86110
/>
87111
);
88112
};

test/chart.test.tsx

+4-42
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ describe('<Chart />', () => {
274274
expect(chart.canvas).toHaveClass('chart-example');
275275
});
276276

277-
it('should call getDatasetAtEvent', () => {
278-
const getDatasetAtEvent = jest.fn();
277+
it('should call onClick', () => {
278+
const onClick = jest.fn();
279279

280280
const { getByTestId } = render(
281281
<Chart
@@ -284,51 +284,13 @@ describe('<Chart />', () => {
284284
options={options}
285285
type='bar'
286286
ref={ref}
287-
getDatasetAtEvent={getDatasetAtEvent}
287+
onClick={onClick}
288288
/>
289289
);
290290

291291
fireEvent.click(getByTestId('canvas'));
292292

293-
expect(getDatasetAtEvent).toHaveBeenCalled();
294-
});
295-
296-
it('should call getElementAtEvent', () => {
297-
const getElementAtEvent = jest.fn();
298-
299-
const { getByTestId } = render(
300-
<Chart
301-
data-testid='canvas'
302-
data={data}
303-
options={options}
304-
type='bar'
305-
ref={ref}
306-
getElementAtEvent={getElementAtEvent}
307-
/>
308-
);
309-
310-
fireEvent.click(getByTestId('canvas'));
311-
312-
expect(getElementAtEvent).toHaveBeenCalled();
313-
});
314-
315-
it('should call getElementsAtEvent', () => {
316-
const getElementsAtEvent = jest.fn();
317-
318-
const { getByTestId } = render(
319-
<Chart
320-
data-testid='canvas'
321-
data={data}
322-
options={options}
323-
type='bar'
324-
ref={ref}
325-
getElementsAtEvent={getElementsAtEvent}
326-
/>
327-
);
328-
329-
fireEvent.click(getByTestId('canvas'));
330-
331-
expect(getElementsAtEvent).toHaveBeenCalled();
293+
expect(onClick).toHaveBeenCalled();
332294
});
333295

334296
it('should show fallback content if given', () => {

0 commit comments

Comments
 (0)