Skip to content

Commit 7e706c6

Browse files
Merge pull request #211 from yuzhva/feat_polygon_docs
[release] 4.1.0: region/bulk support
2 parents 55ccf0d + c5d90ad commit 7e706c6

File tree

8 files changed

+791
-2583
lines changed

8 files changed

+791
-2583
lines changed

.storybook/doc.mdx

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
1+
import { Meta, Story, Preview } from "@storybook/addon-docs/blocks";
22

33
import {
44
BasicExample,
@@ -7,7 +7,8 @@ import {
77
MarkerOptions,
88
MarkerPopup,
99
MarkerTooltip,
10-
} from './examples';
10+
RegionExample,
11+
} from "./examples";
1112

1213
<Meta title="React Leaflet MarkerCluster" />
1314

@@ -16,8 +17,8 @@ import {
1617
Just grab your markers inside `<MarkerClusterGroup />` component, right after `<TileLayer />`:
1718

1819
```javascript
19-
import { MapContainer, TileLayer, Marker } from 'react-leaflet';
20-
import MarkerClusterGroup from 'react-leaflet-markercluster';
20+
import { MapContainer, TileLayer, Marker } from "react-leaflet";
21+
import MarkerClusterGroup from "react-leaflet-markercluster";
2122

2223
<MapContainer
2324
className="markercluster-map"
@@ -45,7 +46,7 @@ If you would like to pass some props to the Marker, please use [react-leaflet Ma
4546
<Story name="Basic example">{BasicExample}</Story>
4647
</Preview>
4748

48-
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/basic.js)
49+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/basic.jsx)
4950

5051
---
5152

@@ -54,8 +55,8 @@ If you would like to pass some props to the Marker, please use [react-leaflet Ma
5455
Just pass event handler into appropriate component, like:
5556

5657
```javascript
57-
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
58-
import MarkerClusterGroup from 'react-leaflet-markercluster';
58+
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
59+
import MarkerClusterGroup from "react-leaflet-markercluster";
5960

6061
<MapContainer
6162
className="markercluster-map"
@@ -69,28 +70,28 @@ import MarkerClusterGroup from 'react-leaflet-markercluster';
6970
/>
7071

7172
<MarkerClusterGroup
72-
onClusterClick={cluster =>
73-
console.warn('cluster-click', cluster, cluster.layer.getAllChildMarkers())
73+
onClusterClick={(cluster) =>
74+
console.warn("cluster-click", cluster, cluster.layer.getAllChildMarkers())
7475
}
7576
>
7677
<Marker
7778
position={[49.8397, 24.0297]}
78-
onClick={marker =>
79-
console.warn('marker-click', marker, marker.target.getLatLng())
79+
onClick={(marker) =>
80+
console.warn("marker-click", marker, marker.target.getLatLng())
8081
}
8182
/>
8283
<Marker
8384
position={[52.2297, 21.0122]}
84-
onClick={marker =>
85-
console.warn('marker-click', marker, marker.target.getLatLng())
85+
onClick={(marker) =>
86+
console.warn("marker-click", marker, marker.target.getLatLng())
8687
}
8788
/>
8889

8990
<Marker position={[51.5074, -0.0901]}>
9091
<Popup
9192
minWidth={200}
9293
closeButton={false}
93-
onClose={popup => console.warn('popup-close', popup)}
94+
onClose={(popup) => console.warn("popup-close", popup)}
9495
>
9596
<div>
9697
<b>Hello world!</b>
@@ -106,7 +107,7 @@ import MarkerClusterGroup from 'react-leaflet-markercluster';
106107
<Story name="Event listeners">{EventListeners}</Story>
107108
</Preview>
108109

109-
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/event-listeners.js)
110+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/event-listeners.jsx)
110111

111112
---
112113

@@ -181,7 +182,7 @@ If you would like to pass some props to the Cluster, please check [List of all L
181182
<Story name="Cluster custom icon">{MarkerClusterOptions}</Story>
182183
</Preview>
183184

184-
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-cluster-options.js)
185+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-cluster-options.jsx)
185186

186187
---
187188

@@ -191,11 +192,11 @@ Base on: [react-leaflet example](https://github.com/PaulLeCam/react-leaflet/blob
191192
For setting Marker options, please use [react-leaflet Marker API](https://react-leaflet.js.org/docs/en/components.html#marker)
192193

193194
```javascript
194-
import L from 'leaflet';
195-
import { MapContainer, TileLayer, Marker } from 'react-leaflet';
196-
import MarkerClusterGroup from 'react-leaflet-markercluster';
195+
import L from "leaflet";
196+
import { MapContainer, TileLayer, Marker } from "react-leaflet";
197+
import MarkerClusterGroup from "react-leaflet-markercluster";
197198
198-
import redFilledMarker from './icons/red-filled-marker.svg';
199+
import redFilledMarker from "./icons/red-filled-marker.svg";
199200
200201
// Create marker icon according to the official leaflet documentation
201202
const redMarker = L.icon({
@@ -240,7 +241,7 @@ If you would like to pass some props to the Cluster, please check [List of all L
240241
<Story name="Marker icon and title">{MarkerOptions}</Story>
241242
</Preview>
242243

243-
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-options.js)
244+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-options.jsx)
244245

245246
---
246247

@@ -251,11 +252,11 @@ Create Popup for Marker as easy, as to cluster all markers. <br />
251252
Just pass **react-leaflet Popup** component to the **Marker** as a child: <br />
252253

253254
```javascript
254-
import L from 'leaflet';
255-
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
256-
import MarkerClusterGroup from 'react-leaflet-markercluster';
255+
import L from "leaflet";
256+
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
257+
import MarkerClusterGroup from "react-leaflet-markercluster";
257258
258-
import redFilledMarker from './icons/red-filled-marker.svg';
259+
import redFilledMarker from "./icons/red-filled-marker.svg";
259260
260261
// Create marker icon according to the official leaflet documentation
261262
const redMarker = L.icon({
@@ -309,7 +310,7 @@ If you would like to pass some props to the Cluster, please check [List of all L
309310
<Story name="Marker popup">{MarkerPopup}</Story>
310311
</Preview>
311312

312-
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-popup.js)
313+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-popup.jsx)
313314

314315
---
315316

@@ -320,8 +321,8 @@ Creation of Tooltip for Marker as easy, as a creation of Popup. <br />
320321
Just pass **react-leaflet Tooltip** component to the **Marker** as a child: <br />
321322

322323
```javascript
323-
import { MapContainer, TileLayer, Marker, Tooltip } from 'react-leaflet';
324-
import MarkerClusterGroup from 'react-leaflet-markercluster';
324+
import { MapContainer, TileLayer, Marker, Tooltip } from "react-leaflet";
325+
import MarkerClusterGroup from "react-leaflet-markercluster";
325326
326327
// Setup Tooltip according to react-leaflet documentation
327328
// https://react-leaflet.js.org/docs/en/examples.html
@@ -365,4 +366,83 @@ If you would like to pass some props to the Cluster, please check [List of all L
365366
<Story name="Marker tooltip">{MarkerTooltip}</Story>
366367
</Preview>
367368

368-
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-tooltip.js)
369+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/marker-tooltip.jsx)
370+
371+
# Region example
372+
373+
Use a custom `<ClusterableRegion />` inside `<MarkerClusterGroup />` component:
374+
375+
```javascript
376+
import { MapContainer, TileLayer, Marker } from "react-leaflet";
377+
import MarkerClusterGroup from "react-leaflet-markercluster";
378+
379+
const ClusterableRegion = createPathComponent(function createClusterableRegion(
380+
{ coordinates, color = "blue", fillOpacity = 0.3, onClick },
381+
ctx,
382+
) {
383+
// Define a clusterable region with a getLatLng method for clustering compatibility
384+
// Credits to https://github.com/Leaflet/Leaflet.markercluster/issues/612#issuecomment-242929562
385+
const ClusterableRegion = Polygon.extend({
386+
initialize: function (latlngs, options) {
387+
Polygon.prototype.initialize.call(this, latlngs, options);
388+
this._latlng = this.getBounds().getCenter();
389+
},
390+
getLatLng: function () {
391+
return this._latlng;
392+
},
393+
setLatLng: function () {}, // Dummy method to satisfy marker clustering requirements
394+
});
395+
396+
// Instantiate the ClusterablePolygon with provided positions and options
397+
const region = new ClusterableRegion(coordinates, {
398+
color,
399+
fillOpacity,
400+
onclick: onClick,
401+
});
402+
403+
return {
404+
instance: region,
405+
context: {
406+
...ctx,
407+
overlayContainer: region,
408+
},
409+
};
410+
});
411+
412+
<MapContainer
413+
className="markercluster-map"
414+
center={MAP_CENTER_COORDINATES}
415+
zoom={MAP_ZOOM}
416+
maxZoom={MAP_MAX_ZOOM}
417+
>
418+
<TileLayer
419+
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
420+
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
421+
/>
422+
423+
<MarkerClusterGroup animate={true}>
424+
{Array.from({ length: 42069 }, (_, i) => {
425+
const centerCoords = randomCoords();
426+
return (
427+
<ClusterableRegion
428+
key={i}
429+
coordinates={[
430+
centerCoords,
431+
[centerCoords[0] - Math.random(), centerCoords[1] - Math.random()],
432+
[centerCoords[0] - Math.random(), centerCoords[1] + Math.random()],
433+
[centerCoords[0] + Math.random(), centerCoords[1] + Math.random()],
434+
]}
435+
/>
436+
);
437+
})}
438+
</MarkerClusterGroup>
439+
</MapContainer>;
440+
```
441+
442+
<Preview>
443+
<Story name="Region example">{RegionExample}</Story>
444+
</Preview>
445+
446+
[GitHub source code](https://github.com/YUzhva/react-leaflet-markercluster/blob/master/.storybook/examples/region.jsx)
447+
448+
---

.storybook/doc.stories.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
MarkerOptions,
66
MarkerPopup,
77
MarkerTooltip,
8+
RegionExample,
89
} from "./examples";
910

1011
export default {
@@ -40,3 +41,8 @@ export const MarkerTooltipStory = {
4041
render: MarkerTooltip,
4142
name: "Marker tooltip",
4243
};
44+
45+
export const RegionExampleStory = {
46+
render: RegionExample,
47+
name: "Region example",
48+
};

.storybook/examples/index.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
export { default as BasicExample } from './basic';
2-
export { default as EventListeners } from './event-listeners';
3-
export { default as MarkerClusterOptions } from './marker-cluster-options';
4-
export { default as MarkerOptions } from './marker-options';
5-
export { default as MarkerPopup } from './marker-popup';
6-
export { default as MarkerTooltip } from './marker-tooltip';
1+
export { default as BasicExample } from "./basic";
2+
export { default as EventListeners } from "./event-listeners";
3+
export { default as MarkerClusterOptions } from "./marker-cluster-options";
4+
export { default as MarkerOptions } from "./marker-options";
5+
export { default as MarkerPopup } from "./marker-popup";
6+
export { default as MarkerTooltip } from "./marker-tooltip";
7+
export { default as RegionExample } from "./region.jsx";

.storybook/examples/region.jsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React from "react";
2+
import { Polygon } from "leaflet";
3+
import { createPathComponent } from "@react-leaflet/core";
4+
import { MapContainer, TileLayer } from "react-leaflet";
5+
import MarkerClusterGroup from "../../src/react-leaflet-markercluster";
6+
import { MAP_ZOOM, MAP_MAX_ZOOM, MAP_CENTER_COORDINATES } from "./constants";
7+
import "./styles.scss";
8+
9+
function randomCoords() {
10+
return [160 * Math.random() - 80, 360 * Math.random() - 180];
11+
}
12+
13+
const ClusterableRegion = createPathComponent(function createClusterableRegion(
14+
{ coordinates, color = "blue", fillOpacity = 0.3, onClick },
15+
ctx,
16+
) {
17+
// Define a clusterable region with a getLatLng method for clustering compatibility
18+
// Credits to https://github.com/Leaflet/Leaflet.markercluster/issues/612#issuecomment-242929562
19+
const ClusterableRegion = Polygon.extend({
20+
initialize: function (latlngs, options) {
21+
Polygon.prototype.initialize.call(this, latlngs, options);
22+
this._latlng = this.getBounds().getCenter();
23+
},
24+
getLatLng: function () {
25+
return this._latlng;
26+
},
27+
setLatLng: function () {}, // Dummy method to satisfy marker clustering requirements
28+
});
29+
30+
// Instantiate the ClusterablePolygon with provided positions and options
31+
const region = new ClusterableRegion(coordinates, {
32+
color,
33+
fillOpacity,
34+
onclick: onClick,
35+
});
36+
37+
return {
38+
instance: region,
39+
context: {
40+
...ctx,
41+
overlayContainer: region,
42+
},
43+
};
44+
});
45+
46+
const RegionExample = () => (
47+
<MapContainer
48+
className="markercluster-map"
49+
center={MAP_CENTER_COORDINATES}
50+
zoom={MAP_ZOOM}
51+
maxZoom={MAP_MAX_ZOOM}
52+
>
53+
<TileLayer
54+
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
55+
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
56+
/>
57+
58+
<MarkerClusterGroup animate={true}>
59+
{Array.from({ length: 42069 }, (_, i) => {
60+
const centerCoords = randomCoords();
61+
return (
62+
<ClusterableRegion
63+
key={i}
64+
coordinates={[
65+
centerCoords,
66+
[
67+
centerCoords[0] - Math.random(),
68+
centerCoords[1] - Math.random(),
69+
],
70+
[
71+
centerCoords[0] - Math.random(),
72+
centerCoords[1] + Math.random(),
73+
],
74+
[
75+
centerCoords[0] + Math.random(),
76+
centerCoords[1] + Math.random(),
77+
],
78+
]}
79+
/>
80+
);
81+
})}
82+
</MarkerClusterGroup>
83+
</MapContainer>
84+
);
85+
86+
export default RegionExample;

dist/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,21 @@ function _objectWithoutPropertiesLoose(r, e) {
176176
}
177177
return t;
178178
}
179+
_leaflet.default.MarkerClusterGroup.include({
180+
_flushLayerBuffer: function _flushLayerBuffer() {
181+
this.addLayers(this._layerBuffer);
182+
this._layerBuffer = [];
183+
},
184+
addLayer: function addLayer(layer) {
185+
if (this._layerBuffer.length === 0) {
186+
setTimeout(this._flushLayerBuffer.bind(this), 50);
187+
}
188+
this._layerBuffer.push(layer);
189+
},
190+
});
191+
_leaflet.default.MarkerClusterGroup.addInitHook(function () {
192+
this._layerBuffer = [];
193+
});
179194
function createMarkerCluster(_ref, context) {
180195
var _c = _ref.children,
181196
props = _objectWithoutProperties(_ref, _excluded);

0 commit comments

Comments
 (0)