Drive map markers by data, not visibility
All checks were successful
Build Docker Image / build (push) Successful in 5m20s
All checks were successful
Build Docker Image / build (push) Successful in 5m20s
This commit is contained in:
@@ -50,7 +50,6 @@ const props = withDefaults(defineProps<{
|
||||
hoveredItem?: HoveredItem | null
|
||||
pointColor?: string
|
||||
entityType?: 'offer' | 'hub' | 'supplier'
|
||||
visibleTypes?: Array<'offer' | 'hub' | 'supplier'>
|
||||
initialCenter?: [number, number]
|
||||
initialZoom?: number
|
||||
infoLoading?: boolean
|
||||
@@ -71,7 +70,6 @@ const props = withDefaults(defineProps<{
|
||||
items: () => [],
|
||||
clusteredPoints: () => [],
|
||||
clusteredPointsByType: undefined,
|
||||
visibleTypes: undefined,
|
||||
relatedPoints: () => []
|
||||
})
|
||||
|
||||
@@ -300,10 +298,6 @@ const getServerClusterCountLayerId = (type: 'offer' | 'hub' | 'supplier') => `${
|
||||
const getServerPointLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-points`
|
||||
const getServerPointLabelLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-point-labels`
|
||||
|
||||
const isTypeVisible = (type: 'offer' | 'hub' | 'supplier') => {
|
||||
if (!props.visibleTypes || props.visibleTypes.length === 0) return true
|
||||
return props.visibleTypes.includes(type)
|
||||
}
|
||||
|
||||
const emitBoundsChange = (map: MapboxMapType) => {
|
||||
const bounds = map.getBounds()
|
||||
@@ -757,9 +751,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => {
|
||||
'circle-stroke-width': 2,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
},
|
||||
layout: {
|
||||
visibility: isTypeVisible(type) ? 'visible' : 'none'
|
||||
}
|
||||
layout: {}
|
||||
})
|
||||
|
||||
map.addLayer({
|
||||
@@ -769,8 +761,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => {
|
||||
filter: ['>', ['get', 'count'], 1],
|
||||
layout: {
|
||||
'text-field': ['get', 'count'],
|
||||
'text-size': 14,
|
||||
visibility: isTypeVisible(type) ? 'visible' : 'none'
|
||||
'text-size': 14
|
||||
},
|
||||
paint: { 'text-color': '#ffffff' }
|
||||
})
|
||||
@@ -783,8 +774,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => {
|
||||
layout: {
|
||||
'icon-image': `entity-icon-${type}`,
|
||||
'icon-size': 1,
|
||||
'icon-allow-overlap': true,
|
||||
visibility: isTypeVisible(type) ? 'visible' : 'none'
|
||||
'icon-allow-overlap': true
|
||||
}
|
||||
})
|
||||
|
||||
@@ -797,8 +787,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => {
|
||||
'text-field': ['get', 'name'],
|
||||
'text-offset': [0, 1.8],
|
||||
'text-size': 12,
|
||||
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],
|
||||
visibility: isTypeVisible(type) ? 'visible' : 'none'
|
||||
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold']
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#ffffff',
|
||||
@@ -962,24 +951,7 @@ watch(() => props.relatedPoints, () => {
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => props.visibleTypes, () => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
if (!usesTypedClusters.value) return
|
||||
for (const type of CLUSTER_TYPES) {
|
||||
const visibility = isTypeVisible(type) ? 'visible' : 'none'
|
||||
const layers = [
|
||||
getServerClusterLayerId(type),
|
||||
getServerClusterCountLayerId(type),
|
||||
getServerPointLayerId(type),
|
||||
getServerPointLabelLayerId(type)
|
||||
]
|
||||
layers.forEach((layerId) => {
|
||||
if (mapRef.value?.getLayer(layerId)) {
|
||||
mapRef.value.setLayoutProperty(layerId, 'visibility', visibility)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, { deep: true })
|
||||
// no visibility toggling; layers are data-driven by query
|
||||
|
||||
// Fit bounds when info loading finishes (all related data loaded)
|
||||
watch(() => props.infoLoading, (loading, wasLoading) => {
|
||||
@@ -1048,14 +1020,13 @@ watch(() => props.clusteredPoints, (points) => {
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
watch([() => props.clusteredPointsByType, () => props.visibleTypes], () => {
|
||||
watch(() => props.clusteredPointsByType, () => {
|
||||
if (!usesTypedClusters.value) return
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
if (didFitBounds.value) return
|
||||
|
||||
const bounds = new LngLatBounds()
|
||||
const visible = props.visibleTypes && props.visibleTypes.length > 0 ? props.visibleTypes : CLUSTER_TYPES
|
||||
visible.forEach(type => {
|
||||
CLUSTER_TYPES.forEach(type => {
|
||||
const points = serverClusteredGeoJsonByType.value[type]?.features ?? []
|
||||
points.forEach((p) => {
|
||||
const coords = (p.geometry as GeoJSON.Point).coordinates as [number, number]
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
:map-id="mapId"
|
||||
:items="isInfoMode ? [] : (useServerClustering ? [] : itemsWithCoords)"
|
||||
:clustered-points="isInfoMode ? [] : (useServerClustering && !useTypedClusters ? clusteredNodes : [])"
|
||||
:clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)"
|
||||
:visible-types="useServerClustering && useTypedClusters ? visibleTypes : undefined"
|
||||
:clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)"
|
||||
:use-server-clustering="useServerClustering && !isInfoMode"
|
||||
:point-color="activePointColor"
|
||||
:entity-type="activeEntityType"
|
||||
@@ -310,8 +309,6 @@ const activeClusterType = computed<'offer' | 'hub' | 'supplier'>(() => {
|
||||
return 'offer'
|
||||
})
|
||||
|
||||
const visibleTypes = computed(() => [activeClusterType.value])
|
||||
|
||||
const clusterLoading = computed(() => {
|
||||
if (!useTypedClusters.value) return singleClusterLoading.value
|
||||
if (activeClusterType.value === 'hub') return hubClusters.loading.value
|
||||
|
||||
Reference in New Issue
Block a user