mirror of
https://github.com/google-map-react/google-map-react.git
synced 2025-12-08 18:26:32 +00:00
Fix: Update heatmap layer when heatmap positions prop changes (#728)
* improvement: switched from defining API key in multiple places to one place * now generating random readings * fix: a change in heatmap positions now updates the map accordingly * docs: added comment to explain that the developer should use their own key
This commit is contained in:
parent
59c0265b52
commit
3d78dd9cb4
@ -18,6 +18,7 @@ import GoogleMapReact from '../src';
|
||||
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import { GOOGLE_API_KEY } from './config/Google_API_key';
|
||||
|
||||
export const gMap = (
|
||||
{
|
||||
@ -34,7 +35,7 @@ export const gMap = (
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
bootstrapURLKeys={{
|
||||
key: 'AIzaSyBMqz4ueWMfGGqdXlvwE_cIVfar60GROi8',
|
||||
key: GOOGLE_API_KEY,
|
||||
}}
|
||||
style={style}
|
||||
options={options}
|
||||
|
||||
@ -11,19 +11,27 @@ import {
|
||||
} from 'recompose';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { susolvkaCoords, generateMarkers, heatmapData } from './data/fakeData';
|
||||
import {
|
||||
susolvkaCoords,
|
||||
generateMarkers,
|
||||
heatmapData,
|
||||
generateHeatmapData,
|
||||
} from './data/fakeData';
|
||||
|
||||
import GoogleMapReact from '../src';
|
||||
import SimpleMarker from './markers/SimpleMarker';
|
||||
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import { GOOGLE_API_KEY } from './config/Google_API_key';
|
||||
import withSafeInterval from './utils/withSafeInterval';
|
||||
|
||||
export const gMapHeatmap = (
|
||||
{
|
||||
style,
|
||||
hoverDistance,
|
||||
options,
|
||||
heatmap,
|
||||
mapParams: { center, zoom },
|
||||
onChange,
|
||||
onChildMouseEnter,
|
||||
@ -34,7 +42,7 @@ export const gMapHeatmap = (
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
bootstrapURLKeys={{
|
||||
key: 'AIzaSyBMqz4ueWMfGGqdXlvwE_cIVfar60GROi8',
|
||||
key: GOOGLE_API_KEY,
|
||||
}}
|
||||
style={style}
|
||||
options={options}
|
||||
@ -45,7 +53,7 @@ export const gMapHeatmap = (
|
||||
onChange={onChange}
|
||||
onChildMouseEnter={onChildMouseEnter}
|
||||
onChildMouseLeave={onChildMouseLeave}
|
||||
heatmap={heatmapData}
|
||||
heatmap={heatmap}
|
||||
heatmapLibrary
|
||||
>
|
||||
{markers}
|
||||
@ -76,11 +84,22 @@ export const gMapHOC = compose(
|
||||
)),
|
||||
withState('hoveredMarkerId', 'setHoveredMarkerId', -1),
|
||||
withState('mapParams', 'setMapParams', { center: susolvkaCoords, zoom: 6 }),
|
||||
withSafeInterval,
|
||||
withState('heatmap', 'setHeatmap', heatmapData),
|
||||
// describe events
|
||||
withHandlers({
|
||||
onChange: ({ setMapParams }) =>
|
||||
onChange: ({ setMapParams, setSafeInterval, setHeatmap, mapParams }) =>
|
||||
({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
const boundSetHeatmap = setHeatmap.bind(this);
|
||||
setSafeInterval(
|
||||
() => {
|
||||
boundSetHeatmap(
|
||||
generateHeatmapData(mapParams.center.lat, mapParams.center.lng)
|
||||
);
|
||||
},
|
||||
3000
|
||||
);
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) =>
|
||||
(hoverKey, { id }) => {
|
||||
|
||||
@ -18,6 +18,7 @@ import SimpleMarker from './markers/SimpleMarker';
|
||||
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import { GOOGLE_API_KEY } from './config/Google_API_key';
|
||||
|
||||
export const gMap = (
|
||||
{
|
||||
@ -34,7 +35,7 @@ export const gMap = (
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
bootstrapURLKeys={{
|
||||
key: 'AIzaSyBMqz4ueWMfGGqdXlvwE_cIVfar60GROi8',
|
||||
key: GOOGLE_API_KEY,
|
||||
}}
|
||||
style={style}
|
||||
options={options}
|
||||
|
||||
@ -24,6 +24,7 @@ import ReactiveMarker from './markers/ReactiveMarker';
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import props2Stream from './utils/props2Stream';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import { GOOGLE_API_KEY } from './config/Google_API_key';
|
||||
|
||||
export const gMap = (
|
||||
{
|
||||
@ -40,7 +41,7 @@ export const gMap = (
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
bootstrapURLKeys={{
|
||||
key: 'AIzaSyBMqz4ueWMfGGqdXlvwE_cIVfar60GROi8',
|
||||
key: GOOGLE_API_KEY,
|
||||
}}
|
||||
style={style}
|
||||
options={options}
|
||||
|
||||
@ -19,6 +19,7 @@ import SimpleMarker from './markers/SimpleMarker';
|
||||
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import { GOOGLE_API_KEY } from './config/Google_API_key';
|
||||
|
||||
export const gMapResizable = (
|
||||
{
|
||||
@ -35,7 +36,7 @@ export const gMapResizable = (
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
bootstrapURLKeys={{
|
||||
key: 'AIzaSyBMqz4ueWMfGGqdXlvwE_cIVfar60GROi8',
|
||||
key: GOOGLE_API_KEY,
|
||||
}}
|
||||
style={style}
|
||||
options={options}
|
||||
|
||||
2
develop/config/Google_API_key.js
Normal file
2
develop/config/Google_API_key.js
Normal file
@ -0,0 +1,2 @@
|
||||
// use your own google maps API key with localhost permissions below
|
||||
export const GOOGLE_API_KEY = '';
|
||||
@ -48,3 +48,26 @@ export const heatmapData = {
|
||||
opacity: 0.7,
|
||||
},
|
||||
};
|
||||
|
||||
function getRandomNumberBetween(min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
export const generateHeatmapData = (lat, lng) => {
|
||||
const newFakeReadings = x => {
|
||||
const newReadings = [];
|
||||
|
||||
for (let i = 0; i <= x; i++) {
|
||||
newReadings.push({
|
||||
weight: getRandomNumberBetween(0.1, 4),
|
||||
lat: getRandomNumberBetween(lat - 1, lat + 1),
|
||||
lng: getRandomNumberBetween(lng - 1, lng + 1),
|
||||
});
|
||||
}
|
||||
return newReadings;
|
||||
};
|
||||
return {
|
||||
positions: newFakeReadings(10),
|
||||
options: heatmapData.options,
|
||||
};
|
||||
};
|
||||
|
||||
48
develop/utils/withSafeInterval.js
Normal file
48
develop/utils/withSafeInterval.js
Normal file
@ -0,0 +1,48 @@
|
||||
import { createElement, Component } from 'react';
|
||||
|
||||
const safeTimerFactory = (setFn, clearFn, propName, hocName) =>
|
||||
Target => {
|
||||
class SafeTimer extends Component {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.unsubscribers = [];
|
||||
this[propName] = this[propName].bind(this);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unsubscribers.forEach(unsubscribe => unsubscribe());
|
||||
|
||||
this.unsubscribers = [];
|
||||
}
|
||||
|
||||
[propName](...args) {
|
||||
const id = setFn(...args);
|
||||
const unsubscriber = () => clearFn(id);
|
||||
|
||||
this.unsubscribers.push(unsubscriber);
|
||||
|
||||
return unsubscriber;
|
||||
}
|
||||
|
||||
render() {
|
||||
return createElement(Target, {
|
||||
...this.props,
|
||||
[propName]: this[propName],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
SafeTimer.displayName = `${hocName}`;
|
||||
}
|
||||
|
||||
return SafeTimer;
|
||||
};
|
||||
|
||||
export default safeTimerFactory(
|
||||
global.setInterval,
|
||||
global.clearInterval,
|
||||
'setSafeInterval',
|
||||
'withSafeInterval'
|
||||
);
|
||||
@ -386,6 +386,18 @@ export default class GoogleMap extends Component {
|
||||
});
|
||||
this._setLayers(nextProps.layerTypes);
|
||||
}
|
||||
|
||||
if (
|
||||
this.heatmap &&
|
||||
!shallowEqual(nextProps.heatmap.positions, this.props.heatmap.positions)
|
||||
) {
|
||||
this.heatmap.setData(
|
||||
nextProps.heatmap.positions.map(p => ({
|
||||
location: new this.maps_.LatLng(p.lat, p.lng),
|
||||
weight: p.weight,
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user