Skip to content

Commit bab5d30

Browse files
Merge pull request #10 from MartinSahlen/master
Support layers as in react-leaflet 1.0.0
2 parents 5e83184 + 31475b2 commit bab5d30

File tree

5 files changed

+201
-101
lines changed

5 files changed

+201
-101
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# 0.2.4 Release
1+
# 1.0.0 Release
2+
- Leaflet 1.0.0 support
3+
- React-Leaflet 1.0.0 support
24
- List eslint as an explicit devDependency
35
- upgrade the eslint related packages
46
- fix linting errors using current config

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
## Usage
88

9+
Use directly as a fixed layer:
10+
911
```js
1012
import React from 'react';
1113
import { render } from 'react-dom';
@@ -40,6 +42,65 @@ class MapExample extends React.Component {
4042
render(<MapExample />, document.getElementById('app'));
4143
```
4244

45+
Or use it inside a layer control to toggle it:
46+
47+
```js
48+
import React from 'react';
49+
import { render } from 'react-dom';
50+
import { Map, Marker, Popup, TileLayer } from 'react-leaflet';
51+
import HeatmapLayer from '../src/HeatmapLayer';
52+
import { addressPoints } from './realworld.10000.js';
53+
54+
class MapExample extends React.Component {
55+
56+
render() {
57+
return (
58+
<div>
59+
<Map center={position} zoom={13} style={{ height: '100%' }} >
60+
<LayersControl>
61+
<LayersControl.BaseLayer name="Base" checked>
62+
<TileLayer
63+
url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
64+
attribution="&copy; <a href=http://osm.org/copyright>OpenStreetMap</a> contributors"
65+
/>
66+
</LayersControl.BaseLayer>
67+
<LayersControl.Overlay name="Heatmap" checked>
68+
<FeatureGroup color="purple">
69+
<Marker position={[50.05, -0.09]} >
70+
<Popup>
71+
<span>A pretty CSS3 popup.<br /> Easily customizable. </span>
72+
</Popup>
73+
</Marker>
74+
<HeatmapLayer
75+
fitBoundsOnLoad
76+
fitBoundsOnUpdate
77+
points={addressPoints}
78+
longitudeExtractor={m => m[1]}
79+
latitudeExtractor={m => m[0]}
80+
intensityExtractor={m => parseFloat(m[2])}
81+
/>
82+
</FeatureGroup>
83+
</LayersControl.Overlay>
84+
<LayersControl.Overlay name="Marker">
85+
<FeatureGroup color="purple">
86+
<Marker position={position} >
87+
<Popup>
88+
<span>A pretty CSS3 popup.<br /> Easily customizable. </span>
89+
</Popup>
90+
</Marker>
91+
</FeatureGroup>
92+
</LayersControl.Overlay>
93+
</LayersControl>
94+
</Map>
95+
</div>
96+
);
97+
}
98+
}
99+
100+
render(<MapExample />, document.getElementById('app'));
101+
```
102+
103+
43104
## API
44105

45106
The `HeatmapLayer` component takes the following props:

lib/HeatmapLayer.js

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@
22

33
exports.__esModule = true;
44

5-
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
6-
75
var _react = require('react');
86

97
var _react2 = _interopRequireDefault(_react);
108

11-
var _reactDom = require('react-dom');
12-
13-
var _reactDom2 = _interopRequireDefault(_reactDom);
14-
159
var _lodash = require('lodash.map');
1610

1711
var _lodash2 = _interopRequireDefault(_lodash);
@@ -70,6 +64,15 @@ function isInvalidLatLngArray(arr) {
7064
return !isValidLatLngArray(arr);
7165
}
7266

67+
function safeRemoveLayer(leafletMap, el) {
68+
var _leafletMap$getPanes = leafletMap.getPanes(),
69+
overlayPane = _leafletMap$getPanes.overlayPane;
70+
71+
if (overlayPane.contains(el)) {
72+
overlayPane.removeChild(el);
73+
}
74+
}
75+
7376
function shouldIgnoreLocation(loc) {
7477
return isInvalid(loc.lng) || isInvalid(loc.lat);
7578
}
@@ -83,18 +86,49 @@ var HeatmapLayer = function (_MapLayer) {
8386
return _possibleConstructorReturn(this, _MapLayer.apply(this, arguments));
8487
}
8588

89+
HeatmapLayer.prototype.createLeafletElement = function createLeafletElement() {
90+
return null;
91+
};
92+
8693
HeatmapLayer.prototype.componentDidMount = function componentDidMount() {
87-
this.leafletElement = _reactDom2.default.findDOMNode(this.refs.container);
88-
this.props.map.getPanes().overlayPane.appendChild(this.leafletElement);
89-
this._heatmap = (0, _simpleheat2.default)(this.leafletElement);
94+
var _this2 = this;
95+
96+
var canAnimate = this.context.map.options.zoomAnimation && _leaflet2.default.Browser.any3d;
97+
var zoomClass = 'leaflet-zoom-' + (canAnimate ? 'animated' : 'hide');
98+
var mapSize = this.context.map.getSize();
99+
var transformProp = _leaflet2.default.DomUtil.testProp(['transformOrigin', 'WebkitTransformOrigin', 'msTransformOrigin']);
100+
101+
this._el = _leaflet2.default.DomUtil.create('canvas', zoomClass);
102+
this._el.style[transformProp] = '50% 50%';
103+
this._el.width = mapSize.x;
104+
this._el.height = mapSize.y;
105+
106+
var el = this._el;
107+
108+
var Heatmap = _leaflet2.default.Layer.extend({
109+
onAdd: function onAdd(leafletMap) {
110+
return leafletMap.getPanes().overlayPane.appendChild(el);
111+
},
112+
addTo: function addTo(leafletMap) {
113+
leafletMap.addLayer(_this2);
114+
return _this2;
115+
},
116+
onRemove: function onRemove(leafletMap) {
117+
return safeRemoveLayer(leafletMap, el);
118+
}
119+
});
120+
121+
this.leafletElement = new Heatmap();
122+
_MapLayer.prototype.componentDidMount.call(this);
123+
this._heatmap = (0, _simpleheat2.default)(this._el);
124+
this.reset();
90125

91126
if (this.props.fitBoundsOnLoad) {
92127
this.fitBounds();
93128
}
94129

95130
this.attachEvents();
96131
this.updateHeatmapProps(this.getHeatmapProps(this.props));
97-
this.reset();
98132
};
99133

100134
HeatmapLayer.prototype.getMax = function getMax(props) {
@@ -147,7 +181,7 @@ var HeatmapLayer = function (_MapLayer) {
147181
};
148182

149183
HeatmapLayer.prototype.componentWillUnmount = function componentWillUnmount() {
150-
this.props.map.getPanes().overlayPane.removeChild(this.leafletElement);
184+
safeRemoveLayer(this.context.map, this._el);
151185
};
152186

153187
HeatmapLayer.prototype.fitBounds = function fitBounds() {
@@ -161,11 +195,11 @@ var HeatmapLayer = function (_MapLayer) {
161195
return;
162196
}
163197

164-
this.props.map.fitBounds(_leaflet2.default.latLngBounds(_leaflet2.default.latLng(sw), _leaflet2.default.latLng(ne)));
198+
this.context.map.fitBounds(_leaflet2.default.latLngBounds(_leaflet2.default.latLng(sw), _leaflet2.default.latLng(ne)));
165199
};
166200

167201
HeatmapLayer.prototype.componentDidUpdate = function componentDidUpdate() {
168-
this.props.map.invalidateSize();
202+
this.context.map.invalidateSize();
169203
if (this.props.fitBoundsOnUpdate) {
170204
this.fitBounds();
171205
}
@@ -177,45 +211,45 @@ var HeatmapLayer = function (_MapLayer) {
177211
};
178212

179213
HeatmapLayer.prototype.attachEvents = function attachEvents() {
180-
var _this2 = this;
214+
var _this3 = this;
181215

182-
var leafletMap = this.props.map;
216+
var leafletMap = this.context.map;
183217
leafletMap.on('viewreset', function () {
184-
return _this2.reset();
218+
return _this3.reset();
185219
});
186220
leafletMap.on('moveend', function () {
187-
return _this2.reset();
221+
return _this3.reset();
188222
});
189223
if (leafletMap.options.zoomAnimation && _leaflet2.default.Browser.any3d) {
190224
leafletMap.on('zoomanim', this._animateZoom, this);
191225
}
192226
};
193227

194228
HeatmapLayer.prototype._animateZoom = function _animateZoom(e) {
195-
var scale = this.props.map.getZoomScale(e.zoom);
196-
var offset = this.props.map._getCenterOffset(e.center)._multiplyBy(-scale).subtract(this.props.map._getMapPanePos());
229+
var scale = this.context.map.getZoomScale(e.zoom);
230+
var offset = this.context.map._getCenterOffset(e.center)._multiplyBy(-scale).subtract(this.context.map._getMapPanePos());
197231

198232
if (_leaflet2.default.DomUtil.setTransform) {
199-
_leaflet2.default.DomUtil.setTransform(this.refs.container, offset, scale);
233+
_leaflet2.default.DomUtil.setTransform(this._el, offset, scale);
200234
} else {
201-
this.refs.container.style[_leaflet2.default.DomUtil.TRANSFORM] = _leaflet2.default.DomUtil.getTranslateString(offset) + ' scale(' + scale + ')';
235+
this._el.style[_leaflet2.default.DomUtil.TRANSFORM] = _leaflet2.default.DomUtil.getTranslateString(offset) + ' scale(' + scale + ')';
202236
}
203237
};
204238

205239
HeatmapLayer.prototype.reset = function reset() {
206-
var topLeft = this.props.map.containerPointToLayerPoint([0, 0]);
207-
_leaflet2.default.DomUtil.setPosition(this.refs.container, topLeft);
240+
var topLeft = this.context.map.containerPointToLayerPoint([0, 0]);
241+
_leaflet2.default.DomUtil.setPosition(this._el, topLeft);
208242

209-
var size = this.props.map.getSize();
243+
var size = this.context.map.getSize();
210244

211245
if (this._heatmap._width !== size.x) {
212-
this.refs.container.width = this._heatmap._width = size.x;
246+
this._el.width = this._heatmap._width = size.x;
213247
}
214248
if (this._heatmap._height !== size.y) {
215-
this.refs.container.height = this._heatmap._height = size.y;
249+
this._el.height = this._heatmap._height = size.y;
216250
}
217251

218-
if (this._heatmap && !this._frame && !this.props.map._animating) {
252+
if (this._heatmap && !this._frame && !this.context.map._animating) {
219253
this._frame = _leaflet2.default.Util.requestAnimFrame(this.redraw, this);
220254
}
221255

@@ -224,16 +258,16 @@ var HeatmapLayer = function (_MapLayer) {
224258

225259
HeatmapLayer.prototype.redraw = function redraw() {
226260
var r = this._heatmap._r;
227-
var size = this.props.map.getSize();
261+
var size = this.context.map.getSize();
228262

229263
var maxIntensity = this.props.max === undefined ? 1 : this.getMax(this.props);
230264

231-
var maxZoom = this.props.maxZoom === undefined ? this.props.map.getMaxZoom() : this.getMaxZoom(this.props);
265+
var maxZoom = this.props.maxZoom === undefined ? this.context.map.getMaxZoom() : this.getMaxZoom(this.props);
232266

233-
var v = 1 / Math.pow(2, Math.max(0, Math.min(maxZoom - this.props.map.getZoom(), 12)));
267+
var v = 1 / Math.pow(2, Math.max(0, Math.min(maxZoom - this.context.map.getZoom(), 12)));
234268

235269
var cellSize = r / 2;
236-
var panePos = this.props.map._getMapPanePos();
270+
var panePos = this.context.map._getMapPanePos();
237271
var offsetX = panePos.x % cellSize;
238272
var offsetY = panePos.y % cellSize;
239273
var getLat = this.props.latitudeExtractor;
@@ -301,7 +335,8 @@ var HeatmapLayer = function (_MapLayer) {
301335
var getDataForHeatmap = function getDataForHeatmap(points, leafletMap) {
302336
return roundResults(accumulateInGrid(points, leafletMap, getBounds(leafletMap)));
303337
};
304-
var data = getDataForHeatmap(this.props.points, this.props.map);
338+
339+
var data = getDataForHeatmap(this.props.points, this.context.map);
305340

306341
this._heatmap.clear();
307342
this._heatmap.data(data).draw(this.getMinOpacity(this.props));
@@ -318,21 +353,7 @@ var HeatmapLayer = function (_MapLayer) {
318353
};
319354

320355
HeatmapLayer.prototype.render = function render() {
321-
var _style;
322-
323-
var mapSize = this.props.map.getSize();
324-
var transformProp = _leaflet2.default.DomUtil.testProp(['transformOrigin', 'WebkitTransformOrigin', 'msTransformOrigin']);
325-
var canAnimate = this.props.map.options.zoomAnimation && _leaflet2.default.Browser.any3d;
326-
var zoomClass = 'leaflet-zoom-' + (canAnimate ? 'animated' : 'hide');
327-
328-
var canvasProps = {
329-
className: 'leaflet-heatmap-layer leaflet-layer ' + zoomClass,
330-
style: (_style = {}, _style[transformProp] = '50% 50%', _style),
331-
width: mapSize.x,
332-
height: mapSize.y
333-
};
334-
335-
return _react2.default.createElement('canvas', _extends({ ref: 'container' }, canvasProps));
356+
return null;
336357
};
337358

338359
return HeatmapLayer;

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-leaflet-heatmap-layer",
3-
"version": "0.2.4",
3+
"version": "1.0.0",
44
"description": "A custom layer for heatmaps in react-leaflet",
55
"main": "lib/HeatmapLayer.js",
66
"scripts": {
@@ -29,10 +29,10 @@
2929
"author": "Jeremiah Hall <npm@jeremiahrhall.com>",
3030
"license": "MIT",
3131
"peerDependencies": {
32-
"leaflet": "^0.7.7",
33-
"react-leaflet": "^0.10.2",
34-
"react": "^0.14.7",
35-
"react-dom": "^0.14.7"
32+
"leaflet": "^1.0.0",
33+
"react-leaflet": "^1.0.0",
34+
"react": "^15.4.1",
35+
"react-dom": "^15.4.1"
3636
},
3737
"devDependencies": {
3838
"babel-cli": "^6.6.5",
@@ -51,11 +51,11 @@
5151
"eslint-plugin-arrow-function": "^2.0.0",
5252
"eslint-plugin-lean-imports": "^0.3.3",
5353
"eslint-plugin-react": "^4.2.3",
54-
"leaflet": "^0.7.7",
55-
"react": "^0.14.7",
54+
"leaflet": "^1.0.0",
55+
"react": "^15.4.1",
5656
"react-addons-test-utils": "^0.14.7",
57-
"react-dom": "^0.14.7",
58-
"react-leaflet": "^0.10.2",
57+
"react-dom": "^15.4.1",
58+
"react-leaflet": "^1.0.0",
5959
"react-transform-hmr": "^1.0.4",
6060
"webpack": "^1.12.14",
6161
"webpack-dev-server": "^1.14.1"

0 commit comments

Comments
 (0)