v-mapbox
v-mapbox copied to clipboard
Layers don't react on source data changes
I want to lazy load data in the source, otherwise it will slowdown too much the app at start up.
The layers must load these new data, but they dont react up. according to my understanding of the source code, they should because there is a watcher on the source.data
<MglGeojsonLayer
v-for="layer in layers"
:key="layer.id"
:sourceId="layer.sourceId"
:source="layer.source"
:layerId="layer.id"
:layer="layer"
:preserveDrawingBuffer="true"
:replaceSource="true"
/>```
``` computed: {
source() {
return {
type: "geojson",
data: {
features: this.$store.getters
.getSelectedProvidersGeoJsonData,
type: "FeatureCollection",
},
cluster: true,
clusterMaxZoom: 14,
clusterRadius: 50,
};
},
layers() {
return [
{
id: "clusterLayer",
type: "circle",
source: this.source,
sourceId: this.sourceId,
filter: ["has", "point_count"],
paint: {
"circle-color": [
"step",
["get", "point_count"],
"#51bbd6",
100,
"#f1f075",
750,
"#f28cb1",
],
"circle-radius": [
"step",
["get", "point_count"],
20,
100,
30,
750,
40,
],
},
},
... // other layers using the same source
]
}
this.$store.getters.getSelectedProvidersGeoJsonData
returns the geojson based on some selections that happend in an other components. the other component loads the data and the getter just returns the data based on some filtering.
I can see in the vuedev tools the source.data updating, even in the GeoJsonLayers components.
Can you pls create a codesandbox demo?
@vinayakkulkarni I figure out that my problem was with the clustered points. once i disabled that on the source it worked well.... however now i hit an other problem which is similar:
<div
v-for="provider of this.$store.getters.getSelectedProviders"
:key="provider.name"
>
<MglGeojsonLayer
:v-show="provider.isSelected"
v-for="layer in layers"
:key="layer.name + provider.name"
:sourceId="provider.sourceId + layer.name"
:source="provider.source"
:layerId="layer.name + provider.name"
:layer="layer"
:clearSource="true"
@click="onClick"
@mouseenter="mouseEnter"
@mouseleave="mouseLeave"
/>
</div>
.........
computed: {
layers() {
return [
{
name: "clusterLayer",
type: "circle",
filter: [
"all",
[">", ["get", "provider_name"], 1],
["==", ["get", "cluster"], true],
],
paint: {
"circle-color": "#fbb03b",
"circle-radius": [
"step",
["get", "provider_name"],
20,
100,
30,
750,
40,
],
},
},
{
name: "cluster-count",
type: "symbol",
filter: [
"all",
[">", ["get", "provider_name"], 1],
["==", ["get", "cluster"], true],
],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["Noto Sans Regular"],
"text-size": 12,
},
}, {
name: "unclustered-point",
type: "circle",
filter: ["!", ["has", "point_count"]],
paint: {
"circle-radius": 4,
"circle-stroke-width": 1,
"circle-stroke-color": "#fff",
},
....
With this code i add providers and their data based on a selection. This work well: I can load providers and their data and the layers are rendered accordingly. however, when I unselect a provider, the problem start:
only the clusterLayer
is removed, but the two others are still there ( I can still see the numbers and the unclustered points).
Checking with the vue dev tools, the GeoJsonLayer components are removed.
I'm expecting all the layers to be removed , and added back upon selection
Try to make a for loop with a couple of geojson layers, and then remove these layers ( by changing the :key for instance).
Only the first layer is removed from mapbox. the rest is staying. you can see them in map.getStyle().layers
. they get never removed.
I have similar problem with components removal (like if clearSource were false):
<MglGeojsonLayer
v-for="trip in tripsProcessed"
:key="trip.fileId"
:layer-id="trip.fileId"
:layer="trip.layer"
:source-id="trip.fileId"
:source="trip.source"
/>
computed: {
tripsProcessed () {
return this.trips.filter(trip => !this.routerData?.zoomToTrip || trip.page.id === this.routerData.zoomToTrip)
}
When a layer is once added it will never disappear on the map.
Is there at least some workaround how to hide it in the map based on computed data? Tried also v-show.
Maybe this codesandbox can be of your help?