@xyo-network/react-map 3.0.14 → 3.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/Components/LayerAnimator.d.ts.map +1 -1
- package/dist/browser/Components/MapBox.d.ts.map +1 -1
- package/dist/browser/Components/MapBoxPoints.d.ts.map +1 -1
- package/dist/browser/Contexts/HeatMapInitializer/Provider.d.ts.map +1 -1
- package/dist/browser/hooks/useDynamicMapResize.d.ts.map +1 -1
- package/dist/browser/hooks/useDynamicPositioning.d.ts +1 -1
- package/dist/browser/hooks/useDynamicPositioning.d.ts.map +1 -1
- package/dist/browser/index.mjs +83 -92
- package/dist/browser/index.mjs.map +1 -1
- package/package.json +12 -12
- package/src/Components/LayerAnimator.tsx +14 -17
- package/src/Components/MapBox.tsx +1 -0
- package/src/Components/MapBoxPoints.tsx +9 -10
- package/src/Contexts/HeatMapInitializer/Provider.tsx +10 -14
- package/src/hooks/useDynamicMapResize.tsx +3 -8
- package/src/hooks/useDynamicPositioning.tsx +4 -5
- package/src/hooks/useQuadKeyPayloadsToFeatures.tsx +2 -2
|
@@ -2,7 +2,7 @@ import type { WithChildren } from '@xylabs/react-shared'
|
|
|
2
2
|
import { useInterval } from '@xylabs/react-shared'
|
|
3
3
|
import type { Map } from 'mapbox-gl'
|
|
4
4
|
import React, {
|
|
5
|
-
useCallback, useEffect,
|
|
5
|
+
useCallback, useEffect, useMemo, useRef,
|
|
6
6
|
} from 'react'
|
|
7
7
|
|
|
8
8
|
import type { MapLayer } from '../Layers/index.ts'
|
|
@@ -21,9 +21,21 @@ const animatedLayerCount = 3
|
|
|
21
21
|
export const LayerAnimator: React.FC<WithChildren<LayerAnimatorProps>> = ({
|
|
22
22
|
animateLayers, children, layers, layersInitialized, map,
|
|
23
23
|
}) => {
|
|
24
|
-
const [fillLayers, setFillLayers] = useState<MapLayer[]>([])
|
|
25
24
|
const layerIndexQueue = useRef<number[]>([])
|
|
26
25
|
|
|
26
|
+
const fillLayers: MapLayer[] = useMemo(() => {
|
|
27
|
+
if (layers?.length && map && layersInitialized) {
|
|
28
|
+
return layers.filter((layer) => {
|
|
29
|
+
const fillLayer = layer.id.startsWith('location-fill')
|
|
30
|
+
if (fillLayer) {
|
|
31
|
+
map.setPaintProperty(layer.id, 'fill-opacity-transition', { delay: 0, duration: 4000 })
|
|
32
|
+
}
|
|
33
|
+
return fillLayer
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
return []
|
|
37
|
+
}, [layers, layersInitialized, map])
|
|
38
|
+
|
|
27
39
|
const incrementQueue = useCallback(
|
|
28
40
|
(index: number) => {
|
|
29
41
|
if (fillLayers[index]) {
|
|
@@ -71,21 +83,6 @@ export const LayerAnimator: React.FC<WithChildren<LayerAnimatorProps>> = ({
|
|
|
71
83
|
[map, unshiftQueue],
|
|
72
84
|
)
|
|
73
85
|
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
if (layers?.length && map && layersInitialized) {
|
|
76
|
-
// Only animate fill layers for now
|
|
77
|
-
setFillLayers(
|
|
78
|
-
layers.filter((layer) => {
|
|
79
|
-
const fillLayer = layer.id.startsWith('location-fill')
|
|
80
|
-
if (fillLayer) {
|
|
81
|
-
map.setPaintProperty(layer.id, 'fill-opacity-transition', { delay: 0, duration: 4000 })
|
|
82
|
-
}
|
|
83
|
-
return fillLayer
|
|
84
|
-
}),
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
}, [layers, layersInitialized, map])
|
|
88
|
-
|
|
89
86
|
//
|
|
90
87
|
const queueLayerAnimation = useCallback(() => {
|
|
91
88
|
const animatedLayers: MapLayer[] = []
|
|
@@ -50,6 +50,7 @@ export const MapBox: React.FC<MapBoxProps> = ({
|
|
|
50
50
|
|
|
51
51
|
// Allow external components to control the map
|
|
52
52
|
setMapBoxInstance?.(map)
|
|
53
|
+
// eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
|
|
53
54
|
setMap(map)
|
|
54
55
|
|
|
55
56
|
// save the map canvas ref to help with resizing
|
|
@@ -3,7 +3,7 @@ import { FlexCol } from '@xylabs/react-flexbox'
|
|
|
3
3
|
import type { Feature, Point } from 'geojson'
|
|
4
4
|
import type { MapOptions } from 'mapbox-gl'
|
|
5
5
|
import React, {
|
|
6
|
-
useCallback, useEffect,
|
|
6
|
+
useCallback, useEffect, useMemo,
|
|
7
7
|
} from 'react'
|
|
8
8
|
|
|
9
9
|
import { useMapBoxInstance, useMapSettings } from '../Contexts/index.ts'
|
|
@@ -25,7 +25,6 @@ export const MapboxPointsFlexBox: React.FC<MapboxPointsFlexBoxProps> = ({
|
|
|
25
25
|
zoom,
|
|
26
26
|
...props
|
|
27
27
|
}) => {
|
|
28
|
-
const [mapPoints, setMapPoints] = useState<MapPoints>()
|
|
29
28
|
const { mapSettings } = useMapSettings()
|
|
30
29
|
const { map, mapInitialized } = useMapBoxInstance()
|
|
31
30
|
|
|
@@ -40,6 +39,14 @@ export const MapboxPointsFlexBox: React.FC<MapboxPointsFlexBoxProps> = ({
|
|
|
40
39
|
return {}
|
|
41
40
|
}
|
|
42
41
|
|
|
42
|
+
const mapPoints = useMemo(() => {
|
|
43
|
+
return (map && features?.length)
|
|
44
|
+
? new MapPoints({
|
|
45
|
+
features, map, zoom,
|
|
46
|
+
})
|
|
47
|
+
: undefined
|
|
48
|
+
}, [map, features, zoom])
|
|
49
|
+
|
|
43
50
|
const updateFeatures = useCallback(() => {
|
|
44
51
|
if (mapPoints?.isMapReady && features?.length && layers)
|
|
45
52
|
for (const layer of layers) {
|
|
@@ -70,14 +77,6 @@ export const MapboxPointsFlexBox: React.FC<MapboxPointsFlexBoxProps> = ({
|
|
|
70
77
|
updateFeatures()
|
|
71
78
|
}, [mapPoints, fitToPointsPadding, updateFeatures, zoom])
|
|
72
79
|
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
if (map && features?.length) {
|
|
75
|
-
setMapPoints(new MapPoints({
|
|
76
|
-
features, map, zoom,
|
|
77
|
-
}))
|
|
78
|
-
}
|
|
79
|
-
}, [map, features, zoom])
|
|
80
|
-
|
|
81
80
|
useEffect(() => {
|
|
82
81
|
if (mapInitialized) {
|
|
83
82
|
updateMapSetup()
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { forget } from '@xylabs/forget'
|
|
2
2
|
import type { WithChildren } from '@xylabs/react-shared'
|
|
3
3
|
import type { Feature, Polygon } from 'geojson'
|
|
4
|
-
import React, {
|
|
5
|
-
useEffect, useMemo, useState,
|
|
6
|
-
} from 'react'
|
|
4
|
+
import React, { useEffect, useMemo } from 'react'
|
|
7
5
|
|
|
8
6
|
import type { AnimatedHeatMapColorProps, HeatMapColorProps } from '../../Colors/index.ts'
|
|
9
7
|
import { useDynamicPositioning } from '../../hooks/index.ts'
|
|
@@ -34,11 +32,18 @@ export const HeatMapInitializerProvider: React.FC<WithChildren<MapInitializerPro
|
|
|
34
32
|
layers,
|
|
35
33
|
zoom,
|
|
36
34
|
}) => {
|
|
37
|
-
const [mapHeat, setMapHeat] = useState<MapHeat>()
|
|
38
35
|
const { options } = useDynamicPositioning()
|
|
39
36
|
const { mapSettings } = useMapSettings()
|
|
40
37
|
const { map, mapInitialized } = useMapBoxInstance()
|
|
41
38
|
|
|
39
|
+
const mapHeat = useMemo(() => {
|
|
40
|
+
return (map && features?.length)
|
|
41
|
+
? new MapHeat({
|
|
42
|
+
features, map, zoom,
|
|
43
|
+
})
|
|
44
|
+
: undefined
|
|
45
|
+
}, [map, features, zoom])
|
|
46
|
+
|
|
42
47
|
const value: HeatMapInitializerState = useMemo(() => ({
|
|
43
48
|
MapHeat: mapHeat,
|
|
44
49
|
heatMapColorProps,
|
|
@@ -76,7 +81,7 @@ export const HeatMapInitializerProvider: React.FC<WithChildren<MapInitializerPro
|
|
|
76
81
|
map,
|
|
77
82
|
features,
|
|
78
83
|
)
|
|
79
|
-
} else if (options
|
|
84
|
+
} else if (options?.zoom && options.center) {
|
|
80
85
|
map.setZoom(options.zoom)
|
|
81
86
|
map.setCenter(options.center)
|
|
82
87
|
}
|
|
@@ -84,14 +89,5 @@ export const HeatMapInitializerProvider: React.FC<WithChildren<MapInitializerPro
|
|
|
84
89
|
}
|
|
85
90
|
}, [mapHeat, map, mapSettings, fitToPadding, options, mapInitialized, features])
|
|
86
91
|
|
|
87
|
-
useEffect(() => {
|
|
88
|
-
if (map && features?.length) {
|
|
89
|
-
// Every time we get a new map or features, we make a new class
|
|
90
|
-
setMapHeat(new MapHeat({
|
|
91
|
-
features, map, zoom,
|
|
92
|
-
}))
|
|
93
|
-
}
|
|
94
|
-
}, [map, features, zoom])
|
|
95
|
-
|
|
96
92
|
return <HeatMapInitializerContext.Provider value={value}>{children}</HeatMapInitializerContext.Provider>
|
|
97
93
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { Map } from 'mapbox-gl'
|
|
2
2
|
import type { MutableRefObject } from 'react'
|
|
3
|
-
import {
|
|
4
|
-
useEffect, useMemo, useState,
|
|
5
|
-
} from 'react'
|
|
3
|
+
import { useEffect, useMemo } from 'react'
|
|
6
4
|
|
|
7
5
|
/**
|
|
8
6
|
* Inspired by - https://bl.ocks.org/danswick/fc56f37c10d40be62e4feac5984250d2
|
|
@@ -13,8 +11,6 @@ export const useDynamicMapResize = (
|
|
|
13
11
|
mapInstance?: Map,
|
|
14
12
|
active = true,
|
|
15
13
|
) => {
|
|
16
|
-
const [dependenciesReady, setDependenciesReady] = useState(false)
|
|
17
|
-
|
|
18
14
|
const resizer = useMemo(
|
|
19
15
|
() =>
|
|
20
16
|
new ResizeObserver(() => {
|
|
@@ -29,9 +25,8 @@ export const useDynamicMapResize = (
|
|
|
29
25
|
[mapCanvasRef, mapContainerRef, mapInstance],
|
|
30
26
|
)
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
setDependenciesReady(dependenciesReady)
|
|
28
|
+
const dependenciesReady = useMemo(() => {
|
|
29
|
+
return !!(active && mapInstance && mapContainerRef?.current && mapCanvasRef.current)
|
|
35
30
|
}, [active, mapCanvasRef, mapContainerRef, mapInstance])
|
|
36
31
|
|
|
37
32
|
useEffect(() => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useWindowSize } from '@xylabs/react-shared'
|
|
2
2
|
import type { MapOptions } from 'mapbox-gl'
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo } from 'react'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Zoom level for the map
|
|
@@ -49,17 +49,16 @@ const linearInterpolate = (aspectRatio: number, degreeRange: number[], aspectRat
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const useDynamicPositioning = () => {
|
|
52
|
-
const [options, setOptions] = useState<Partial<MapOptions>>({})
|
|
53
52
|
const { width, height } = useWindowSize()
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
const options = useMemo(() => {
|
|
56
55
|
if (width && height) {
|
|
57
56
|
const aspectRatio = width / height
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
return {
|
|
60
59
|
center: [linearInterpolate(aspectRatio, lngRange), linearInterpolate(aspectRatio, latRange)],
|
|
61
60
|
zoom: defaultZoom,
|
|
62
|
-
}
|
|
61
|
+
} as Partial<MapOptions>
|
|
63
62
|
}
|
|
64
63
|
}, [height, width])
|
|
65
64
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { exists } from '@xylabs/exists'
|
|
2
2
|
import { GeoJson } from '@xyo-network/sdk-geo'
|
|
3
3
|
import type { Feature, Geometry } from 'geojson'
|
|
4
|
-
import {
|
|
4
|
+
import { useMemo, useState } from 'react'
|
|
5
5
|
|
|
6
6
|
import type { NetworkLocationHeatmapQuadkeyAnswerPayload } from '../types/index.ts'
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ const useQuadKeyPayloadsToFeatures = (payloads?: NetworkLocationHeatmapQuadkeyAn
|
|
|
26
26
|
const [features, setFeatures] = useState<Feature<Geometry>[]>([])
|
|
27
27
|
const [error, setError] = useState<Error>()
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
useMemo(() => {
|
|
30
30
|
// Convert Multiple Payloads from Quadkey to GeoJson
|
|
31
31
|
if (Array.isArray(payloads)) {
|
|
32
32
|
if ((payloads)?.filter(exists).length > 0) {
|