Skip to content

Commit

Permalink
refactor: getDatasetAtEvent, getElementAtEvent and getElementsAtEvent…
Browse files Browse the repository at this point in the history
… props are removed (#845)

BREAKING CHANGE: getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed,
utils with the same names can used instead
  • Loading branch information
dangreen committed Nov 4, 2021
1 parent f7a81e6 commit 6a9b2a7
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 130 deletions.
61 changes: 2 additions & 59 deletions src/chart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useRef, forwardRef } from 'react';
import type { ForwardedRef, MouseEvent } from 'react';
import type { ForwardedRef } from 'react';
import { Chart as ChartJS } from 'chart.js';
import type { ChartType, DefaultDataPoint } from 'chart.js';

Expand All @@ -25,11 +25,7 @@ function ChartComponent<
data,
options,
plugins = [],
getDatasetAtEvent,
getElementAtEvent,
getElementsAtEvent,
fallbackContent,
onClick: onClickProp,
...props
}: ChartProps<TType, TData, TLabel>,
ref: ForwardedRef<ChartJS<TType, TData, TLabel>>
Expand Down Expand Up @@ -61,52 +57,6 @@ function ChartComponent<
}
};

const onClick = (event: MouseEvent<HTMLCanvasElement>) => {
if (onClickProp) {
onClickProp(event);
}

const { current: chart } = chartRef;

if (!chart) return;

if (getDatasetAtEvent) {
getDatasetAtEvent(
chart.getElementsAtEventForMode(
event.nativeEvent,
'dataset',
{ intersect: true },
false
),
event
);
}

if (getElementAtEvent) {
getElementAtEvent(
chart.getElementsAtEventForMode(
event.nativeEvent,
'nearest',
{ intersect: true },
false
),
event
);
}

if (getElementsAtEvent) {
getElementsAtEvent(
chart.getElementsAtEventForMode(
event.nativeEvent,
'index',
{ intersect: true },
false
),
event
);
}
};

useEffect(() => {
if (!redraw && chartRef.current && options) {
setOptions(chartRef.current, options);
Expand Down Expand Up @@ -143,14 +93,7 @@ function ChartComponent<
}, []);

return (
<canvas
ref={canvasRef}
role='img'
height={height}
width={width}
onClick={onClick}
{...props}
>
<canvas ref={canvasRef} role='img' height={height} width={width} {...props}>
{fallbackContent}
</canvas>
);
Expand Down
5 changes: 5 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export type { ChartProps } from './types';
export * from './chart';
export * from './typedCharts';
export {
getDatasetAtEvent,
getElementAtEvent,
getElementsAtEvent,
} from './utils';
20 changes: 1 addition & 19 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import type {
CanvasHTMLAttributes,
ForwardedRef,
ReactNode,
MouseEvent,
} from 'react';
import type { CanvasHTMLAttributes, ForwardedRef, ReactNode } from 'react';
import type {
Chart,
ChartType,
ChartData,
ChartOptions,
DefaultDataPoint,
Plugin,
InteractionItem,
} from 'chart.js';

export interface ChartProps<
Expand All @@ -28,18 +22,6 @@ export interface ChartProps<
* @todo Replace with `children` prop.
*/
fallbackContent?: ReactNode;
getDatasetAtEvent?: (
dataset: InteractionItem[],
event: MouseEvent<HTMLCanvasElement>
) => void;
getElementAtEvent?: (
element: InteractionItem[],
event: MouseEvent<HTMLCanvasElement>
) => void;
getElementsAtEvent?: (
elements: InteractionItem[],
event: MouseEvent<HTMLCanvasElement>
) => void;
}

/**
Expand Down
56 changes: 55 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ForwardedRef } from 'react';
import type { ForwardedRef, MouseEvent } from 'react';
import type {
ChartType,
ChartData,
Expand Down Expand Up @@ -74,3 +74,57 @@ export function cloneData<

return nextData;
}

/**
* Get dataset from mouse click event
* @param chart - Chart.js instance
* @param event - Mouse click event
* @returns Dataset
*/
export function getDatasetAtEvent(
chart: Chart,
event: MouseEvent<HTMLCanvasElement>
) {
return chart.getElementsAtEventForMode(
event.nativeEvent,
'dataset',
{ intersect: true },
false
);
}

/**
* Get single dataset element from mouse click event
* @param chart - Chart.js instance
* @param event - Mouse click event
* @returns Dataset
*/
export function getElementAtEvent(
chart: Chart,
event: MouseEvent<HTMLCanvasElement>
) {
return chart.getElementsAtEventForMode(
event.nativeEvent,
'nearest',
{ intersect: true },
false
);
}

/**
* Get dataset element with dataset from mouse click event
* @param chart - Chart.js instance
* @param event - Mouse click event
* @returns Dataset
*/
export function getElementsAtEvent(
chart: Chart,
event: MouseEvent<HTMLCanvasElement>
) {
return chart.getElementsAtEventForMode(
event.nativeEvent,
'index',
{ intersect: true },
false
);
}
42 changes: 33 additions & 9 deletions stories/Chart.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import React, { useState, useEffect, useReducer } from 'react';
import React, {
MouseEvent,
useRef,
useState,
useEffect,
useReducer,
} from 'react';
import 'chart.js/auto';
import { InteractionItem } from 'chart.js';
import type { Chart as ChartJS, InteractionItem } from 'chart.js';
import 'chartjs-adapter-date-fns';
import { Chart } from '../src';
import {
Chart,
getDatasetAtEvent,
getElementAtEvent,
getElementsAtEvent,
} from '../src';
import * as multitypeChart from '../sandboxes/chart/multitype/App';
import * as eventsChart from '../sandboxes/chart/events/App';
import * as data from './Chart.data';
Expand Down Expand Up @@ -52,37 +63,50 @@ export const ClickEvents = ({
data,
...args
}) => {
const getDatasetAtEvent = (dataset: InteractionItem[]) => {
const datasetAtEvent = (dataset: InteractionItem[]) => {
if (!dataset.length) return;

const datasetIndex = dataset[0].datasetIndex;

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

const getElementAtEvent = (element: InteractionItem[]) => {
const elementAtEvent = (element: InteractionItem[]) => {
if (!element.length) return;

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

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

const getElementsAtEvent = (elements: InteractionItem[]) => {
const elementsAtEvent = (elements: InteractionItem[]) => {
if (!elements.length) return;

onElementsClick(elements);
};

const chartRef = useRef<ChartJS>(null);

const onClick = (event: MouseEvent<HTMLCanvasElement>) => {
const { current: chart } = chartRef;

if (!chart) {
return;
}

datasetAtEvent(getDatasetAtEvent(chart, event));
elementAtEvent(getElementAtEvent(chart, event));
elementsAtEvent(getElementsAtEvent(chart, event));
};

return (
<Chart
{...args}
ref={chartRef}
type='bar'
options={options}
data={data}
getDatasetAtEvent={getDatasetAtEvent}
getElementAtEvent={getElementAtEvent}
getElementsAtEvent={getElementsAtEvent}
onClick={onClick}
/>
);
};
Expand Down
46 changes: 4 additions & 42 deletions test/chart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ describe('<Chart />', () => {
expect(chart.canvas).toHaveClass('chart-example');
});

it('should call getDatasetAtEvent', () => {
const getDatasetAtEvent = jest.fn();
it('should call onClick', () => {
const onClick = jest.fn();

const { getByTestId } = render(
<Chart
Expand All @@ -284,51 +284,13 @@ describe('<Chart />', () => {
options={options}
type='bar'
ref={ref}
getDatasetAtEvent={getDatasetAtEvent}
onClick={onClick}
/>
);

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

expect(getDatasetAtEvent).toHaveBeenCalled();
});

it('should call getElementAtEvent', () => {
const getElementAtEvent = jest.fn();

const { getByTestId } = render(
<Chart
data-testid='canvas'
data={data}
options={options}
type='bar'
ref={ref}
getElementAtEvent={getElementAtEvent}
/>
);

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

expect(getElementAtEvent).toHaveBeenCalled();
});

it('should call getElementsAtEvent', () => {
const getElementsAtEvent = jest.fn();

const { getByTestId } = render(
<Chart
data-testid='canvas'
data={data}
options={options}
type='bar'
ref={ref}
getElementsAtEvent={getElementsAtEvent}
/>
);

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

expect(getElementsAtEvent).toHaveBeenCalled();
expect(onClick).toHaveBeenCalled();
});

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

0 comments on commit 6a9b2a7

Please sign in to comment.