Skip to content

Commit 2c430eb

Browse files
authored
Merge pull request #3138 from METAIIII/iiii-heatmap-f
2 parents f61253f + 83254dc commit 2c430eb

File tree

2 files changed

+190
-32
lines changed

2 files changed

+190
-32
lines changed

packages/react-google-maps-api/src/components/heatmap/HeatmapLayer.tsx

Lines changed: 95 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1-
import { type ContextType, PureComponent } from 'react'
2-
import invariant from 'invariant'
1+
import invariant from 'invariant';
2+
import { ContextType, memo, PureComponent, useContext, useEffect, useState } from 'react';
33

4-
import { unregisterEvents, applyUpdatersToPropsAndRegisterEvents } from '../../utils/helper'
5-
6-
import MapContext from '../../map-context'
4+
import MapContext from '../../map-context';
5+
import { applyUpdatersToPropsAndRegisterEvents, unregisterEvents } from '../../utils/helper';
76

87
const eventMap = {}
98

109
const updaterMap = {
1110
data(
1211
instance: google.maps.visualization.HeatmapLayer,
1312
data:
14-
| google.maps.MVCArray<google.maps.LatLng | google.maps.visualization.WeightedLocation>
13+
| google.maps.MVCArray<
14+
google.maps.LatLng | google.maps.visualization.WeightedLocation
15+
>
1516
| google.maps.LatLng[]
1617
| google.maps.visualization.WeightedLocation[]
1718
): void {
1819
instance.setData(data)
1920
},
20-
map(instance: google.maps.visualization.HeatmapLayer, map: google.maps.Map): void {
21+
map(
22+
instance: google.maps.visualization.HeatmapLayer,
23+
map: google.maps.Map
24+
): void {
2125
instance.setMap(map)
2226
},
2327
options(
@@ -36,17 +40,92 @@ export interface HeatmapLayerProps {
3640
// required
3741
/** The data points to display. Required. */
3842
data:
39-
| google.maps.MVCArray<google.maps.LatLng | google.maps.visualization.WeightedLocation>
43+
| google.maps.MVCArray<
44+
google.maps.LatLng | google.maps.visualization.WeightedLocation
45+
>
4046
| google.maps.LatLng[]
4147
| google.maps.visualization.WeightedLocation[]
4248
options?: google.maps.visualization.HeatmapLayerOptions | undefined
4349
/** This callback is called when the heatmapLayer instance has loaded. It is called with the heatmapLayer instance. */
44-
onLoad?: ((heatmapLayer: google.maps.visualization.HeatmapLayer) => void) | undefined
50+
onLoad?:
51+
| ((heatmapLayer: google.maps.visualization.HeatmapLayer) => void)
52+
| undefined
4553
/** This callback is called when the component unmounts. It is called with the heatmapLayer instance. */
46-
onUnmount?: ((heatmapLayer: google.maps.visualization.HeatmapLayer) => void) | undefined
54+
onUnmount?:
55+
| ((heatmapLayer: google.maps.visualization.HeatmapLayer) => void)
56+
| undefined
4757
}
4858

49-
export class HeatmapLayer extends PureComponent<HeatmapLayerProps, HeatmapLayerState> {
59+
function HeatmapLayerFunctional({
60+
data,
61+
onLoad,
62+
onUnmount,
63+
options,
64+
}: HeatmapLayerProps) {
65+
const map = useContext(MapContext)
66+
const [instance, setInstance] =
67+
useState<google.maps.visualization.HeatmapLayer | null>(null)
68+
69+
useEffect(() => {
70+
if (!google.maps.visualization) {
71+
invariant(
72+
!!google.maps.visualization,
73+
'Did you include prop libraries={["visualization"]} in useJsApiScript? %s',
74+
google.maps.visualization
75+
)
76+
}
77+
}, [])
78+
79+
useEffect(() => {
80+
invariant(!!data, 'data property is required in HeatmapLayer %s', data)
81+
}, [data])
82+
83+
// Order does matter
84+
useEffect(() => {
85+
if (instance !== null) {
86+
instance.setMap(map)
87+
}
88+
}, [map])
89+
90+
useEffect(() => {
91+
if (options && instance !== null) {
92+
instance.setOptions(options)
93+
}
94+
}, [instance, options])
95+
96+
useEffect(() => {
97+
const heatmapLayer = new google.maps.visualization.HeatmapLayer({
98+
...(options || {}),
99+
data,
100+
map,
101+
})
102+
103+
setInstance(heatmapLayer)
104+
105+
if (onLoad) {
106+
onLoad(heatmapLayer)
107+
}
108+
109+
return () => {
110+
if (instance !== null) {
111+
if (onUnmount) {
112+
onUnmount(instance)
113+
}
114+
115+
instance.setMap(null)
116+
}
117+
}
118+
}, [])
119+
120+
return null
121+
}
122+
123+
export const HeatmapLayerF = memo(HeatmapLayerFunctional)
124+
125+
export class HeatmapLayer extends PureComponent<
126+
HeatmapLayerProps,
127+
HeatmapLayerState
128+
> {
50129
static contextType = MapContext
51130
declare context: ContextType<typeof MapContext>
52131

@@ -69,12 +148,15 @@ export class HeatmapLayer extends PureComponent<HeatmapLayerProps, HeatmapLayerS
69148
google.maps.visualization
70149
)
71150

72-
invariant(!!this.props.data, 'data property is required in HeatmapLayer %s', this.props.data)
151+
invariant(
152+
!!this.props.data,
153+
'data property is required in HeatmapLayer %s',
154+
this.props.data
155+
)
73156

74157
const heatmapLayer = new google.maps.visualization.HeatmapLayer({
75158
...(this.props.options || {}),
76159
data: this.props.data,
77-
// @ts-ignore
78160
map: this.context,
79161
})
80162

packages/react-google-maps-api/src/index.ts

Lines changed: 95 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,124 @@ export { default as GoogleMap, type GoogleMapProps } from './GoogleMap'
22

33
export { default as LoadScript, type LoadScriptProps } from './LoadScript'
44

5-
export { default as LoadScriptNext, type LoadScriptNextProps } from './LoadScriptNext'
5+
export {
6+
default as LoadScriptNext,
7+
type LoadScriptNextProps,
8+
} from './LoadScriptNext'
69

710
export { useLoadScript } from './useLoadScript'
811

912
export { useJsApiLoader } from './useJsApiLoader'
1013

11-
export { default as TrafficLayer, TrafficLayerF, type TrafficLayerProps } from './components/maps/TrafficLayer'
14+
export {
15+
default as TrafficLayer,
16+
TrafficLayerF,
17+
type TrafficLayerProps,
18+
} from './components/maps/TrafficLayer'
1219

13-
export { default as BicyclingLayer, BicyclingLayerF, type BicyclingLayerProps } from './components/maps/BicyclingLayer'
20+
export {
21+
default as BicyclingLayer,
22+
BicyclingLayerF,
23+
type BicyclingLayerProps,
24+
} from './components/maps/BicyclingLayer'
1425

15-
export { default as TransitLayer, TransitLayerF, type TransitLayerProps } from './components/maps/TransitLayer'
26+
export {
27+
default as TransitLayer,
28+
TransitLayerF,
29+
type TransitLayerProps,
30+
} from './components/maps/TransitLayer'
1631

17-
export { default as DrawingManager, DrawingManagerF, type DrawingManagerProps } from './components/drawing/DrawingManager'
32+
export {
33+
default as DrawingManager,
34+
DrawingManagerF,
35+
type DrawingManagerProps,
36+
} from './components/drawing/DrawingManager'
1837

19-
export { default as Marker, MarkerF, type MarkerProps } from './components/drawing/Marker'
38+
export {
39+
default as Marker,
40+
MarkerF,
41+
type MarkerProps,
42+
} from './components/drawing/Marker'
2043

2144
export {
2245
default as MarkerClusterer,
2346
MarkerClustererF,
2447
type MarkerClustererProps,
2548
} from './components/addons/MarkerClusterer'
2649

27-
export { default as InfoBox, InfoBoxF, type InfoBoxProps } from './components/addons/InfoBox'
50+
export {
51+
default as InfoBox,
52+
InfoBoxF,
53+
type InfoBoxProps,
54+
} from './components/addons/InfoBox'
2855

29-
export { default as GoogleMarkerClusterer, type GoogleMarkerClustererProps } from './components/addons/GoogleMarkerClusterer'
56+
export {
57+
default as GoogleMarkerClusterer,
58+
type GoogleMarkerClustererProps,
59+
} from './components/addons/GoogleMarkerClusterer'
3060

31-
export { default as InfoWindow, InfoWindowF, type InfoWindowProps } from './components/drawing/InfoWindow'
61+
export {
62+
default as InfoWindow,
63+
InfoWindowF,
64+
type InfoWindowProps,
65+
} from './components/drawing/InfoWindow'
3266

33-
export { default as Polyline, PolylineF, type PolylineProps } from './components/drawing/Polyline'
67+
export {
68+
default as Polyline,
69+
PolylineF,
70+
type PolylineProps,
71+
} from './components/drawing/Polyline'
3472

35-
export { default as Polygon, PolygonF, type PolygonProps } from './components/drawing/Polygon'
73+
export {
74+
default as Polygon,
75+
PolygonF,
76+
type PolygonProps,
77+
} from './components/drawing/Polygon'
3678

37-
export { default as Rectangle, RectangleF, type RectangleProps } from './components/drawing/Rectangle'
79+
export {
80+
default as Rectangle,
81+
RectangleF,
82+
type RectangleProps,
83+
} from './components/drawing/Rectangle'
3884

39-
export { default as Circle, CircleF, type CircleProps } from './components/drawing/Circle'
85+
export {
86+
default as Circle,
87+
CircleF,
88+
type CircleProps,
89+
} from './components/drawing/Circle'
4090

41-
export { default as Data, DataF, type DataProps } from './components/drawing/Data'
91+
export {
92+
default as Data,
93+
DataF,
94+
type DataProps,
95+
} from './components/drawing/Data'
4296

43-
export { default as KmlLayer, type KmlLayerProps } from './components/kml/KmlLayer'
97+
export {
98+
default as KmlLayer,
99+
type KmlLayerProps,
100+
} from './components/kml/KmlLayer'
44101

45-
export { default as OverlayView, OverlayViewF, type OverlayViewProps, FLOAT_PANE, MAP_PANE, MARKER_LAYER, OVERLAY_LAYER, OVERLAY_MOUSE_TARGET } from './components/dom/OverlayView'
102+
export {
103+
default as OverlayView,
104+
OverlayViewF,
105+
type OverlayViewProps,
106+
FLOAT_PANE,
107+
MAP_PANE,
108+
MARKER_LAYER,
109+
OVERLAY_LAYER,
110+
OVERLAY_MOUSE_TARGET,
111+
} from './components/dom/OverlayView'
46112

47-
export { default as GroundOverlay, type GroundOverlayProps } from './components/overlays/GroundOverlay'
113+
export {
114+
default as GroundOverlay,
115+
type GroundOverlayProps,
116+
} from './components/overlays/GroundOverlay'
48117

49-
export { default as HeatmapLayer, type HeatmapLayerProps } from './components/heatmap/HeatmapLayer'
118+
export {
119+
default as HeatmapLayer,
120+
HeatmapLayerF,
121+
type HeatmapLayerProps,
122+
} from './components/heatmap/HeatmapLayer'
50123

51124
export {
52125
default as StreetViewPanorama,
@@ -78,7 +151,10 @@ export {
78151
type StandaloneSearchBoxProps,
79152
} from './components/places/StandaloneSearchBox'
80153

81-
export { default as Autocomplete, type AutocompleteProps } from './components/places/Autocomplete'
154+
export {
155+
default as Autocomplete,
156+
type AutocompleteProps,
157+
} from './components/places/Autocomplete'
82158

83159
export { default as MapContext, useGoogleMap } from './map-context'
84160

0 commit comments

Comments
 (0)