{"id":19843186,"url":"https://github.com/khmm12/react-map-gl-supercluster","last_synced_at":"2025-05-01T20:32:10.874Z","repository":{"id":70027597,"uuid":"466997128","full_name":"khmm12/react-map-gl-supercluster","owner":"khmm12","description":null,"archived":false,"fork":false,"pushed_at":"2023-08-30T16:18:52.000Z","size":2088,"stargazers_count":23,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T17:23:35.145Z","etag":null,"topics":["clustering","react","react-map-gl","supercluster"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/khmm12.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-07T08:00:18.000Z","updated_at":"2024-12-25T08:50:01.000Z","dependencies_parsed_at":"2024-11-12T12:45:56.330Z","dependency_job_id":"7150c7ae-fc8f-43df-b3d5-d595216dfec9","html_url":"https://github.com/khmm12/react-map-gl-supercluster","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khmm12%2Freact-map-gl-supercluster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khmm12%2Freact-map-gl-supercluster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khmm12%2Freact-map-gl-supercluster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khmm12%2Freact-map-gl-supercluster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/khmm12","download_url":"https://codeload.github.com/khmm12/react-map-gl-supercluster/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251940998,"owners_count":21668650,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clustering","react","react-map-gl","supercluster"],"created_at":"2024-11-12T12:37:49.178Z","updated_at":"2025-05-01T20:32:10.868Z","avatar_url":"https://github.com/khmm12.png","language":"TypeScript","readme":"# react-map-gl-supercluster\n\n\u003e The easiest way to get `react-map-gl` and `supercluster` to work together\n\n# Highlights\n\n- TypeScript support.\n- ESM support.\n- Ready for tree shaking.\n- No unnecessary re-renders.\n\n# Install\n\n```bash\n$ yarn add react-map-gl-supercluster\n# or\n$ npm install react-map-gl-supercluster\n```\n\n# Usage\n\n```tsx\nimport Map, { useMap } from 'react-map-gl' // react-map-gl/maplibre if you use maplibre instead\nimport {\n  useSupercluster,\n  PointFeature,\n  PointFeatureProperties,\n  PointClusterProperties\n} from 'react-map-gl-supercluster' // or react-map-gl-supercluster/maplibre if you use maplibre instead\n\ntype Item = {}\ntype ItemPointFeatureProperties = PointFeatureProperties\u003c{ item: Item }\u003e\ntype ItemPointClusterProperties = PointClusterProperties\u003c{ items: Item[] }\u003e\n\nfunction MyAwesomeMap(): ReactElement {\n  const mapRef = useRef()\n\n  // Points should be memoized\n  const points = useMemo(() =\u003e createPoints(items), [])\n\n  const { supercluster, clusters } = useSupercluster(points, {\n    mapRef,\n    map: mapFeature,\n    reduce: reduceCluster\n  })\n\n  const expandCluster = (clusterId, coordinates) =\u003e {\n    const zoom = supercluster.getClusterExpansionZoom(clusterId)\n    mapRef.current?.easeTo({\n      center: [coordinates.longitude, coordinates.latitude],\n      zoom,\n    })\n  }\n\n  return (\n    \u003cMap ref={mapRef}\u003e\n      {clusters.map((cluster) =\u003e {\n        const [longitude, latitude] = cluster.geometry.coordinates\n\n        return cluster.properties.cluster ? (\n          \u003cClusterMarker\n            key={`cluster-${cluster.properties.cluster_id}`}\n            longitude={longitude}\n            latitude={latitude}\n            onClick={() =\u003e expandCluster(cluster.properties.cluster_id, { longitude, latitude })}\n          /\u003e\n        ) : (\n          \u003cMarker key={`item-${cluster.properties.item.id}`} longitude={longitude} latitude={longitude} /\u003e\n        )\n      })}\n    \u003c/Map\u003e\n  )\n}\n\nfunction createPoints(items: Item[]): Array\u003cPointFeature\u003cItemPointFeatureProperties\u003e\u003e {\n  return items.map(createPoint)\n}\n\nfunction createPoint(item: Item): PointFeature\u003cItemPointFeatureProperties\u003e {\n  const { longitude, latitude } = item\n\n  return {\n    type: 'Feature',\n    properties: { cluster: false, item },\n    geometry: {\n      type: 'Point',\n      coordinates: [longitude, latitude],\n    },\n  }\n}\n\n// It creates cluster properties from feature properties.\nfunction mapFeature(props: ItemPointFeatureProperties): ItemPointClusterProperties {\n  return { items: [props.item] }\n}\n\n// It merges clusters properties. Yes, it's simply mutates.\nfunction reduceCluster(memo: ItemPointClusterProperties, props: ItemPointClusterProperties): void {\n  memo.items = memo.items.concat(props.items)\n}\n```\n\nAlternatively you can use the hook inside `Map`.\n\n```tsx\nimport Map, { useMap } from 'react-map-gl'// react-map-gl/maplibre if you use maplibre instead\nimport { useSupercluster } from 'react-map-gl-supercluster' // or react-map-gl-supercluster/maplibre if you use maplibre instead\n\nfunction MyAwesomeMap(): ReactElement {\n  return (\n    \u003cMap\u003e\n      \u003cMarkers items={items} /\u003e\n    \u003c/Map\u003e\n  )\n}\n\ntype MarkersProps = {\n  items: Item[]\n}\n\nfunction Markers(props: MarkersProps): ReactElement {\n  const { items } = props\n\n  const map = useMap().current\n\n  // Points should be memoized\n  const points = useMemo(() =\u003e createPoints(items), [items])\n\n  const { supercluster, clusters } = useSupercluster(points, {\n    map: mapFeature,\n    reduce: reduceCluster\n  })\n\n  const expandCluster = (clusterId, coordinates) =\u003e {\n    const zoom = supercluster.getClusterExpansionZoom(clusterId)\n    map?.easeTo({\n      center: [coordinates.longitude, coordinates.latitude],\n      zoom,\n    })\n  }\n\n  return (\n    \u003c\u003e\n      {clusters.map((cluster) =\u003e {\n        const [longitude, latitude] = cluster.geometry.coordinates\n\n        return cluster.properties.cluster ? (\n          \u003cClusterMarker\n            key={`cluster-${cluster.properties.cluster_id}`}\n            longitude={longitude}\n            latitude={latitude}\n            onClick={() =\u003e expandCluster(cluster.properties.cluster_id, { longitude, latitude })}\n          /\u003e\n        ) : (\n          \u003cMarker key={`item-${cluster.properties.item.id}`} longitude={longitude} latitude={longitude} /\u003e\n        )\n      })}\n    \u003c/\u003e\n  )\n}\n```\n\n# API\n\n## `useSupercluster`\n\nThe hook can be used in a component which renders `Map` component or inside `Map` children.\n\n### Arguments\n\n1. `points` - GeoJSON points array. The value should be memoized.\n2. `options` – various options, see bellow.\n\n### Return value\n\nObject which contains 2 fields:\n- `clusters` – clusters list\n- `supercluster` – supercluster instance.\n\n## Options\n\n| Option    | Default  | Description                                                                                                                                                                                   |\n| --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| mapRef    | Optional | Reference to `react-map-gl` instance.                                                                                                                                                         |\n| minZoom   | 0        | Minimum zoom level at which clusters are generated.                                                                                                                                           |\n| maxZoom   | 16       | Maximum zoom level at which clusters are generated.                                                                                                                                           |\n| minPoints | 2        | Minimum number of points to form a cluster.                                                                                                                                                   |\n| radius    | 40       | Cluster radius, in pixels.                                                                                                                                                                    |\n| map       | Optional | A function that returns cluster properties corresponding to a single point. Should be memoized. [See](https://github.com/mapbox/supercluster/blob/main/README.md#property-mapreduce-options). |\n| reduce    | Optional | A reduce function that merges properties of two clusters into one. Should be memoized. [See](https://github.com/mapbox/supercluster/blob/main/README.md#property-mapreduce-options).          |\n\n`react-map-gl-supercluster` supports all `supercluster` options, you can find more information about them [there](https://github.com/mapbox/supercluster#options).\n\n# FAQ\n\n## Does it support react-map-gl v5/v6?\n\nNo, it doesn't.\n\n## Why does it cause component re-rendering or why do I get infinite component update loop?\n\nPlease be careful with `points` and `map`/`reduce` functions. They always should be memoized.\n\n## Does it support WebWorker?\n\nNo, the hook is running in the main thread. But probably WebWorker support will come in the future.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhmm12%2Freact-map-gl-supercluster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhmm12%2Freact-map-gl-supercluster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhmm12%2Freact-map-gl-supercluster/lists"}