Skip to content

Commit

Permalink
feat: support moving touch events (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
korvin89 authored Nov 14, 2024
1 parent 88ec105 commit b898f4e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
39 changes: 32 additions & 7 deletions src/components/ChartInner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import {pointer} from 'd3';
import throttle from 'lodash/throttle';

import {IS_TOUCH_ENABLED} from '../../constants';
import {
useAxisScales,
useChartDimensions,
Expand Down Expand Up @@ -35,6 +36,8 @@ type Props = {
data: ChartData;
};

type PointPosition = [number, number];

export const ChartInner = (props: Props) => {
const {width, height, data} = props;
const svgRef = React.useRef<SVGSVGElement | null>(null);
Expand Down Expand Up @@ -138,8 +141,10 @@ export const ChartInner = (props: Props) => {
[boundsHeight, boundsWidth],
);

const handlePointerMove: React.MouseEventHandler<SVGSVGElement> = (event) => {
const [pointerX, pointerY] = pointer(event, svgRef.current);
const handleMove = (
[pointerX, pointerY]: PointPosition,
event: React.MouseEvent | React.TouchEvent,
) => {
const x = pointerX - boundsOffsetLeft;
const y = pointerY - boundsOffsetTop;
if (isOutsideBounds(x, y)) {
Expand All @@ -153,13 +158,31 @@ export const ChartInner = (props: Props) => {
});
dispatcher.call('hover-shape', event.target, closest, [pointerX, pointerY], event);
};
const throttledHandlePointerMove = throttle(handlePointerMove, THROTTLE_DELAY);

const handlePointerLeave: React.MouseEventHandler<SVGSVGElement> = (event) => {
throttledHandlePointerMove.cancel();
const handleMouseMove: React.MouseEventHandler<SVGSVGElement> = (event) => {
const [pointerX, pointerY] = pointer(event, svgRef.current);
handleMove([pointerX, pointerY], event);
};

const throttledHandleMouseMove = IS_TOUCH_ENABLED
? undefined
: throttle(handleMouseMove, THROTTLE_DELAY);

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

const handleTouchMove: React.TouchEventHandler<SVGSVGElement> = (event) => {
const touch = event.touches[0];
const [pointerX, pointerY] = pointer(touch, svgRef.current);
handleMove([pointerX, pointerY], event);
};

const throttledHandleTouchMove = IS_TOUCH_ENABLED
? throttle(handleTouchMove, THROTTLE_DELAY)
: undefined;

const handleChartClick = React.useCallback(
(event: React.MouseEvent<SVGSVGElement>) => {
const [pointerX, pointerY] = pointer(event, svgRef.current);
Expand Down Expand Up @@ -195,8 +218,10 @@ export const ChartInner = (props: Props) => {
className={b()}
width={width}
height={height}
onPointerMove={throttledHandlePointerMove}
onPointerLeave={handlePointerLeave}
onMouseMove={throttledHandleMouseMove}
onMouseLeave={handleMouseLeave}
onTouchStart={throttledHandleTouchMove}
onTouchMove={throttledHandleTouchMove}
onClick={handleChartClick}
>
{title && <Title {...title} chartWidth={width} />}
Expand Down
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './defaults';
export * from './misc';

export const SeriesType = {
Area: 'area',
Expand Down
9 changes: 9 additions & 0 deletions src/constants/misc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function isTouchEnabled() {
if (typeof window !== 'object') {
return false;
}

return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
}

export const IS_TOUCH_ENABLED = isTouchEnabled();

0 comments on commit b898f4e

Please sign in to comment.