Skip to content

Commit

Permalink
feat: add chart.events.pointermove property (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
korvin89 authored Nov 12, 2024
1 parent aa9d7ec commit 6e2822a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
30 changes: 20 additions & 10 deletions src/components/ChartInner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,25 @@ export const ChartInner = (props: Props) => {
});

const clickHandler = data.chart?.events?.click;
const pointerMoveHandler = data.chart?.events?.pointermove;

React.useEffect(() => {
if (clickHandler) {
dispatcher.on('click-chart', clickHandler);
}

if (pointerMoveHandler) {
dispatcher.on('hover-shape.chart', (...args) => {
const [hoverData, _position, event] = args;
pointerMoveHandler(hoverData, event);
});
}

return () => {
dispatcher.on('click-chart', null);
dispatcher.on('hover-shape.chart', null);
};
}, [dispatcher, clickHandler]);
}, [dispatcher, clickHandler, pointerMoveHandler]);

const boundsOffsetTop = chart.margin.top;
// We only need to consider the width of the first left axis
Expand All @@ -128,26 +138,26 @@ export const ChartInner = (props: Props) => {
[boundsHeight, boundsWidth],
);

const handleMouseMove: React.MouseEventHandler<SVGSVGElement> = (event) => {
const handlePointerMove: React.MouseEventHandler<SVGSVGElement> = (event) => {
const [pointerX, pointerY] = pointer(event, svgRef.current);
const x = pointerX - boundsOffsetLeft;
const y = pointerY - boundsOffsetTop;
if (isOutsideBounds(x, y)) {
dispatcher.call('hover-shape', {}, undefined);
dispatcher.call('hover-shape', {}, undefined, undefined, event);
return;
}

const closest = getClosestPoints({
position: [x, y],
shapesData,
});
dispatcher.call('hover-shape', event.target, closest, [pointerX, pointerY]);
dispatcher.call('hover-shape', event.target, closest, [pointerX, pointerY], event);
};
const throttledHandleMouseMove = throttle(handleMouseMove, THROTTLE_DELAY);
const throttledHandlePointerMove = throttle(handlePointerMove, THROTTLE_DELAY);

const handleMouseLeave = () => {
throttledHandleMouseMove.cancel();
dispatcher.call('hover-shape', {}, undefined);
const handlePointerLeave: React.MouseEventHandler<SVGSVGElement> = (event) => {
throttledHandlePointerMove.cancel();
dispatcher.call('hover-shape', {}, undefined, undefined, event);
};

const handleChartClick = React.useCallback(
Expand Down Expand Up @@ -185,8 +195,8 @@ export const ChartInner = (props: Props) => {
className={b()}
width={width}
height={height}
onMouseMove={throttledHandleMouseMove}
onMouseLeave={handleMouseLeave}
onPointerMove={throttledHandlePointerMove}
onPointerLeave={handlePointerLeave}
onClick={handleChartClick}
>
{title && <Title {...title} chartWidth={width} />}
Expand Down
7 changes: 6 additions & 1 deletion src/types/chart/chart.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import type {MeaningfulAny} from '../misc';

export type ChartMargin = {
top: number;
right: number;
bottom: number;
left: number;
};

type ChartEventData = {point: MeaningfulAny; series: MeaningfulAny};

export type ChartOptions = {
margin?: Partial<ChartMargin>;
events?: {
click?: (data: {point: unknown; series: unknown}, event: PointerEvent) => void;
click?: (data: ChartEventData, event: PointerEvent) => void;
pointermove?: (data: ChartEventData | undefined, event: PointerEvent) => void;
};
};

0 comments on commit 6e2822a

Please sign in to comment.