UNPKG

2.83 kBMarkdownView Raw
1# useSupercluster
2
3A hook for using [Supercluster](https://github.com/mapbox/supercluster) with React.
4
5```js
6const { clusters, supercluster } = useSupercluster({
7 points: [],
8 bounds: [
9 -1.2411810957931664,
10 52.61208435908725,
11 -1.0083656811012531,
12 52.64495957533833,
13 ],
14 zoom: 12,
15 options: { radius: 75, maxZoom: 20 },
16});
17```
18
19## Installation
20
21You will need to install `supercluster` as a peer dependency of this package.
22
23```txt
24yarn add supercluster use-supercluster
25```
26
27## Examples
28
29This package contains an example along with tests, but full examples with instructions in the most popular mapping libraries for React can be found below.
30
31### Mapbox
32
33Full instructions and an [example can be found here](https://www.leighhalliday.com/mapbox-clustering).
34
35### Google Maps
36
37Full instructions and an [example can be found here](https://www.leighhalliday.com/google-maps-clustering).
38
39### Leaflet
40
41Full instructions and an [example can be found here](https://www.leighhalliday.com/leaflet-clustering).
42
43## Configuration
44
45The last (fourth) argument passed to the `useSupercluster` hook are options that are passed directly to the instance of Supercluster. You can use any of [Supercluster's options](https://github.com/mapbox/supercluster#options).
46
47### Map & Reduce Options
48
49As an example, you can use `map` and `reduce` to keep track of a total value summed up from across the points. In this case we have the total `cost`, the max `severity`, plus another `count` (which is redundant because Supercluster gives us the `point_count` property).
50
51```js
52const options = {
53 radius: 75,
54 maxZoom: 20,
55 map: (props) => ({
56 cost: props.cost,
57 severity: props.severity,
58 count: 1,
59 }),
60 reduce: (acc, props) => {
61 acc.count += 1;
62 acc.cost += props.cost;
63 acc.severity = Math.max(acc.severity, props.severity);
64 return acc;
65 },
66};
67```
68
69I found `map` and `reduce` a little confusing! The value returned from `map` of the first point is used as the initial value passed as the accumulator to the `reduce` function. The only `props` you have available in `reduce` are the ones returned from `map`. You technically don't need to return a value from `reduce` (it's not used), but instead need to mutate the accumulator object.
70
71Then these accumulated properties can be used and are available on each cluster:
72
73```jsx
74<ul>
75 {clusters.map((point) => {
76 const properties = point.properties || {};
77 if (properties.cluster) {
78 return (
79 <li key={point.id}>
80 <h2>Points: {properties.point_count}</h2>
81 <p>Cost: {properties.cost.toFixed(2)}</p>
82 <p>Severity: {properties.severity}</p>
83 <p>Count: {properties.count}</p>
84 </li>
85 );
86 } else {
87 return <li key={properties.crimeId}>{properties.category}</li>;
88 }
89 })}
90</ul>
91```