From ab5bd248f07c63174788ad1642b0752a439f68cc Mon Sep 17 00:00:00 2001 From: dangreen Date: Fri, 5 Nov 2021 04:09:24 +0700 Subject: [PATCH] refactor: getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed, utils with the same names can used instead BREAKING CHANGE: getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed, utils with the same names can used instead --- src/chart.tsx | 61 ++------------------------------------------- src/index.tsx | 5 ++++ src/types.ts | 20 +-------------- src/utils.ts | 56 ++++++++++++++++++++++++++++++++++++++++- stories/Chart.tsx | 42 ++++++++++++++++++++++++------- test/chart.test.tsx | 46 +++------------------------------- 6 files changed, 100 insertions(+), 130 deletions(-) diff --git a/src/chart.tsx b/src/chart.tsx index 6b8391b43..87fbabd87 100644 --- a/src/chart.tsx +++ b/src/chart.tsx @@ -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'; @@ -25,11 +25,7 @@ function ChartComponent< data, options, plugins = [], - getDatasetAtEvent, - getElementAtEvent, - getElementsAtEvent, fallbackContent, - onClick: onClickProp, ...props }: ChartProps, ref: ForwardedRef> @@ -61,52 +57,6 @@ function ChartComponent< } }; - const onClick = (event: MouseEvent) => { - 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); @@ -143,14 +93,7 @@ function ChartComponent< }, []); return ( - + {fallbackContent} ); diff --git a/src/index.tsx b/src/index.tsx index 39427b6e8..e9e422538 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,3 +1,8 @@ export type { ChartProps } from './types'; export * from './chart'; export * from './typedCharts'; +export { + getDatasetAtEvent, + getElementAtEvent, + getElementsAtEvent, +} from './utils'; diff --git a/src/types.ts b/src/types.ts index b6badbc37..8bf01c9b2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,9 +1,4 @@ -import type { - CanvasHTMLAttributes, - ForwardedRef, - ReactNode, - MouseEvent, -} from 'react'; +import type { CanvasHTMLAttributes, ForwardedRef, ReactNode } from 'react'; import type { Chart, ChartType, @@ -11,7 +6,6 @@ import type { ChartOptions, DefaultDataPoint, Plugin, - InteractionItem, } from 'chart.js'; export interface ChartProps< @@ -28,18 +22,6 @@ export interface ChartProps< * @todo Replace with `children` prop. */ fallbackContent?: ReactNode; - getDatasetAtEvent?: ( - dataset: InteractionItem[], - event: MouseEvent - ) => void; - getElementAtEvent?: ( - element: InteractionItem[], - event: MouseEvent - ) => void; - getElementsAtEvent?: ( - elements: InteractionItem[], - event: MouseEvent - ) => void; } /** diff --git a/src/utils.ts b/src/utils.ts index dd0303120..e4a30eae2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import type { ForwardedRef } from 'react'; +import type { ForwardedRef, MouseEvent } from 'react'; import type { ChartType, ChartData, @@ -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 +) { + 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 +) { + 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 +) { + return chart.getElementsAtEventForMode( + event.nativeEvent, + 'index', + { intersect: true }, + false + ); +} diff --git a/stories/Chart.tsx b/stories/Chart.tsx index 475a6ce33..3bb237d17 100644 --- a/stories/Chart.tsx +++ b/stories/Chart.tsx @@ -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'; @@ -52,7 +63,7 @@ export const ClickEvents = ({ data, ...args }) => { - const getDatasetAtEvent = (dataset: InteractionItem[]) => { + const datasetAtEvent = (dataset: InteractionItem[]) => { if (!dataset.length) return; const datasetIndex = dataset[0].datasetIndex; @@ -60,7 +71,7 @@ export const ClickEvents = ({ onDatasetClick(data.datasets[datasetIndex].label); }; - const getElementAtEvent = (element: InteractionItem[]) => { + const elementAtEvent = (element: InteractionItem[]) => { if (!element.length) return; const { datasetIndex, index } = element[0]; @@ -68,21 +79,34 @@ export const ClickEvents = ({ 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(null); + + const onClick = (event: MouseEvent) => { + const { current: chart } = chartRef; + + if (!chart) { + return; + } + + datasetAtEvent(getDatasetAtEvent(chart, event)); + elementAtEvent(getElementAtEvent(chart, event)); + elementsAtEvent(getElementsAtEvent(chart, event)); + }; + return ( ); }; diff --git a/test/chart.test.tsx b/test/chart.test.tsx index 7fb8254ae..61495840b 100644 --- a/test/chart.test.tsx +++ b/test/chart.test.tsx @@ -274,8 +274,8 @@ describe('', () => { 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( ', () => { 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( - - ); - - fireEvent.click(getByTestId('canvas')); - - expect(getElementAtEvent).toHaveBeenCalled(); - }); - - it('should call getElementsAtEvent', () => { - const getElementsAtEvent = jest.fn(); - - const { getByTestId } = render( - - ); - - fireEvent.click(getByTestId('canvas')); - - expect(getElementsAtEvent).toHaveBeenCalled(); + expect(onClick).toHaveBeenCalled(); }); it('should show fallback content if given', () => {