I'm sorry that I write a question here, but for some reason, StackOverflow says there is no tag for Vue2Leaflet, and I don't have enough reputation to create a new tag. This might actually be a bug / enhancement so hopefully it will be ok.
I have a Vue2Leaflet map with a GeoJSON layer. This layer has a style that depends on additional data from the features in the GeoJSON data, and also on an external parameter (the color depends on data, and the data to show depends on a selection of the user).
When I change the external property, the style doesn't update reactively. Is there a way to tell the style to recalculate itself?
I tried to access the mapObject and to re-set the style property (even though it's not strictly necessary) but I got an error saying the mapObject was undefined.
My code looks something like this:
<v-map ...>
<v-tilelayer ... />
<v-geojson-layer ref="geojsonLayer" :options="geoOptions"
:geojson="geojson" />
</v-map>
with the style function (simplified):
geoOptions: {
style: feature => {
if (this.var1 === '') return {}
let data = feature.properties.data
if (data[this.var1] === undefined) return {}
if (data[this.var1][this.var2] === undefined) return {}
return {
fillColor: scale(data[this.var1][this.var2]).hex()
...
}
}
}
where scale() is a chroma.js colorscale that depends on the value of this.var1. What I would like to have is that whenver this.var1 or this.var2 change (they are reactive variables), the style of the features will get re-evaluated.
I hope I expressed my problem clearly.
Thank you very much!
Omri
Hi @KoRiGaN,
I haven't, but I'll try and see how this works (I'm doing some extensive rewriting so it might be a while until I manage to get to this part).
Omri
But as far as I know, you should not use 'options' for a reactive style.
The options will use L.setOptions in Leaflet which updates options data but is not visible on the map.
The best way would be to use the setStyle function for each feature.
Never tried and not sure how to make it works with GeoJSON though.
Let me know if you find a good solution.
What I wound up doing was to create a different Geojson object for each dataset I had (I'm basically plotting a heatmap on top of a map) and switching the geojson object when I want to display different datasets.
It's probably not the most efficient solution but so far seems to work well for my purposes. I also only have features for those areas where I display a value, so the total number of objects in the feature collection is not too high. If I find a different solution I'll let you know.
Cheers,
Omri
I had the same issue but with mouse hovering and managed to implement the setStyle option onEachElement, like:
function onEachFeature (feature, layer) {
layer.on('mouseover', function (e) {
e.target.setStyle({
fillColor: '#ff0033',
});
});
layer.on('mouseout', function (e) {
e.target.resetStyle()
});
}
Only the resetStyle does not work yet
The way @KoRiGaN mentioned works:
onEachFeature(feature, layer) {
// set style for each feature
const color = getColor(feature.properties.color)
layer.setStyle({
color: color,
fillColor: color,
fillOpacity: 0.1,
})
}
Although I haven't quite figured out why we can't set the geojson style as the vector layers
up ! Still need to be to Recalculate the style of a GeoJSON layer based on reactive variables change !
Thanks
@cordlesstuba you can do something like this:
1) create computed property that changes anytime ANY of the properties that you are interested in change
2) add a watcher on such property
3) add a code like this in the watcher body
updateGeoJsonStyle (newStyle) {
this.$nextTick(() => {
if (this.$refs.geoJson && this.$refs.geoJson.mapObject) {
this.$refs.geoJson.mapObject.eachLayer((layer) => {
layer.setStyle(newStyle);
});
}
});
}
Thanks it works !
@cordlesstuba Or use options-style prop. Example
Hi!
You can use the following code inside a computed property:
onEachFeatureFunction() {
return (feature, layer) => {
layer.on({
mouseover(e){
this.setStyle({
fillColor: '#ff0000',
color: '#ff0000'
});
},
mouseout(e){
this.setStyle({
fillColor: '#bf9946',
color: '#bf9946'
});
},
}
})
}
Most helpful comment
@cordlesstuba you can do something like this:
1) create computed property that changes anytime ANY of the properties that you are interested in change
2) add a watcher on such property
3) add a code like this in the watcher body