Skip to content

Commit

Permalink
feat: replace lodash-es debounce
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxingkang committed Mar 20, 2024
1 parent 3e6d56a commit a42d42b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 85 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"authors": [
"wangxingkang <[email protected]> (https://github.com/wangxingkang)"
],
"type": "module",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
Expand Down
159 changes: 74 additions & 85 deletions src/components/MarkerCluster/MarkerCluster.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
import React, {
useState,
useMemo,
useEffect,
useCallback,
useImperativeHandle,
forwardRef,
} from 'react';
import { isFunction, uuid } from '@rcuse/core';
import { LngLatBounds } from 'mapbox-gl';
import Supercluster from 'supercluster';
import { debounce } from 'lodash-es';
import bbox from '@turf/bbox';
import { featureCollection } from '@turf/helpers';
import { defaultSuperclusterOptions } from './config';
import { Marker } from '../Marker';
import { useMap } from '../../hooks/useMap';

import type { MarkerClusterProps, AnyObject, RefMarkerCluster, Feature, LngLatLike } from './types';

const InternalMarkerCluster = <D extends AnyObject = AnyObject>(
props: MarkerClusterProps<D>,
ref: React.Ref<Supercluster>,
) => {
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useState } from 'react'
import { debounce, isFunction, uuid } from '@rcuse/core'
import { LngLatBounds } from 'mapbox-gl'
import Supercluster from 'supercluster'
import bbox from '@turf/bbox'
import { featureCollection } from '@turf/helpers'
import { Marker } from '../Marker'
import { useMap } from '../../hooks/useMap'
import { defaultSuperclusterOptions } from './config'

import type { AnyObject, Feature, LngLatLike, MarkerClusterProps, RefMarkerCluster } from './types'

function InternalMarkerCluster<D extends AnyObject = AnyObject>(props: MarkerClusterProps<D>, ref: React.Ref<Supercluster>) {
const {
cluster,
render,
Expand All @@ -31,120 +20,120 @@ const InternalMarkerCluster = <D extends AnyObject = AnyObject>(
zoomOnClickPadding = 20,
onClick,
onClusterClick,
} = props;
const { map } = useMap();
const [list, setList] = useState<Feature<D>[]>([]);
} = props
const { map } = useMap()
const [list, setList] = useState<Feature<D>[]>([])

const supercluster = useMemo(() => {
return new Supercluster({
...defaultSuperclusterOptions,
...cluster,
});
}, []);
})
}, [])

useEffect(() => {
if (map) {
map.on('zoom', handleChangeBoundary);
map.on('move', handleChangeBoundary);
map.on('resize', handleChangeBoundary);

return () => {
map.off('zoom', handleChangeBoundary);
map.off('move', handleChangeBoundary);
map.off('resize', handleChangeBoundary);
};
}

return undefined;
}, [map]);

useEffect(() => {
if (data) {
supercluster.load(data);
handleChangeBoundary();
}
}, [data]);
const getMapBoundary = (): [[number, number, number, number], number] => {
const bounds = map.getBounds()
const zoom = map.getZoom()

useImperativeHandle(ref, () => supercluster, []);
return [
[bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()],
Math.round(zoom),
]
}

const handleChangeBoundary = useCallback(
debounce(() => {
const mapBoundary = getMapBoundary();
debounce({ delay: 500 }, () => {
const mapBoundary = getMapBoundary()

const result = supercluster.getClusters(...mapBoundary);
const result = supercluster.getClusters(...mapBoundary)

setList(
result.map((item) => {
return {
...item,
id: item.id || uuid(),
};
}
}),
);
}, 500),
)
}),
[],
);
)

const getMapBoundary = (): [[number, number, number, number], number] => {
const bounds = map.getBounds();
const zoom = map.getZoom();
useEffect(() => {
if (map) {
map.on('zoom', handleChangeBoundary)
map.on('move', handleChangeBoundary)
map.on('resize', handleChangeBoundary)

return [
[bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()],
Math.round(zoom),
];
};
return () => {
map.off('zoom', handleChangeBoundary)
map.off('move', handleChangeBoundary)
map.off('resize', handleChangeBoundary)
}
}

return undefined
}, [map])

useEffect(() => {
if (data) {
supercluster.load(data)
handleChangeBoundary()
}
}, [data])

useImperativeHandle(ref, () => supercluster, [])

const handleClusterMarkerClick = (data: any) => {
const { properties } = data;
const { properties } = data

if (!properties?.cluster) return;
if (!properties?.cluster)
return

const children = supercluster.getLeaves(properties.cluster_id, Infinity);
const childrenBbox = bbox(featureCollection(children)) as [number, number, number, number];
const children = supercluster.getLeaves(properties.cluster_id, Number.POSITIVE_INFINITY)
const childrenBbox = bbox(featureCollection(children)) as [number, number, number, number]

map.fitBounds(LngLatBounds.convert(childrenBbox), {
padding: zoomOnClickPadding,
});
};
})
}

return (
<>
{list.map((item) => {
const { geometry, properties } = item;
const { point_count, cluster, cluster_id } = properties;
const { geometry, properties } = item
const { point_count, cluster, cluster_id } = properties

if (cluster) {
return (
<Marker
key={item.id}
lngLat={geometry.coordinates as LngLatLike}
onClick={() => {
onClusterClick?.(point_count, cluster_id);
if (zoomOnClick) {
handleClusterMarkerClick(item);
}
onClusterClick?.(point_count, cluster_id)
if (zoomOnClick)
handleClusterMarkerClick(item)
}}
>
{isFunction(renderCluster) ? renderCluster(point_count, cluster_id) : renderCluster}
</Marker>
);
)
}

return (
<Marker
key={item.id}
lngLat={geometry.coordinates as LngLatLike}
onClick={() => {
onClick?.(item);
onClick?.(item)
}}
>
{isFunction(render) ? render(item) : render}
</Marker>
);
)
})}
</>
);
};
)
}

export const MarkerCluster = forwardRef(InternalMarkerCluster) as RefMarkerCluster;
export const MarkerCluster = forwardRef(InternalMarkerCluster) as RefMarkerCluster

0 comments on commit a42d42b

Please sign in to comment.