I try to select/deselect the layer using a mouse click. Firstly my map is in this way
After clicking on a layer I want to select it and highlight
Now if I click again on the previously selected layer, I want to deselect it and reset the highlight. This is the code that I use to do this:
onEachFeature: function(feature,layer) {
layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
layer.on('click', function(e) {
let isLayerAlreadySelected = // Some logic to undestand if layer alreeady selected
if(isLayerAlreadySelected)
layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
else
layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
}
}
But sometimes when I try to deselect previously selected layer, the layer style is not resetting the opacity remains. Some suggestions about this?
I try to select/deselect the layer using a mouse click. Firstly my map is in this way
After clicking on a layer I want to select it and highlight
Now if I click again on the previously selected layer, I want to deselect it and reset the highlight. This is the code that I use to do this:
onEachFeature: function(feature,layer) {
layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
layer.on('click', function(e) {
let isLayerAlreadySelected = // Some logic to undestand if layer alreeady selected
if(isLayerAlreadySelected)
layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
else
layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
}
}
But sometimes when I try to deselect previously selected layer, the layer style is not resetting the opacity remains. Some suggestions about this?
Share Improve this question edited Jan 14, 2020 at 7:55 Mukyuu 6,7698 gold badges41 silver badges63 bronze badges asked Jan 9, 2020 at 11:21 SkizzoSkizzo 2,9839 gold badges59 silver badges102 bronze badges 1- 1 can you create stackblitz? – Chellappan வ Commented Jan 13, 2020 at 14:51
5 Answers
Reset to default 10 +100Simply you can use resetStyle()
method to reset given vector layer's style to the original GeoJSON style.
var map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('http://{s}.tile.osm/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '© <a href="http://osm/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// get color depending on population density value
function getColor(d) {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.density)
};
}
function highlightFeature(e) {
geojson.resetStyle();
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
// Set style function that sets fill color property
function style(feature) {
return {
fillColor: '#004691',
fillOpacity: 0.5,
weight: 1,
opacity: 1,
color: '#424a44',
dashArray: '1'
};
}
var highlight = {
'fillColor': 'yellow',
'weight': 1,
'opacity': 1
};
function onEachFeature(feature, layer) {
layer.on({
click: highlightFeature
});
}
geojson = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
#map {
width: 600px;
height: 400px;
}
<link rel="stylesheet" href="https://unpkg./[email protected]/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg./[email protected]/dist/leaflet.js"crossorigin=""></script>
<div id='map'></div>
<script type="text/javascript" src="https://leafletjs./examples/choropleth/us-states.js"></script>
You can refer this and this for more info.
Hope this will helps you.
First you could slightly simplify your code by setting your "base" style using the Leaflet GeoJSON factory style
option. That way, your highlight function can reset the style conveniently using the Leaflet GeoJSON Layer Group resetStyle()
method:
let selected = false;
function onEachFeature(feature, layer) {
layer.on("click", function() {
selected = !selected;
if (selected) {
layer.setStyle({
fillOpacity: 0.4,
color: '#004691',
weight: 3
});
} else {
geojsonLayerGroup.resetStyle(layer);
}
});
}
const map = L.map('map').setView([48.86, 2.35], 11);
const geojsonData = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[2.35, 48.88],
[2.32, 48.84],
[2.38, 48.84],
[2.35, 48.88]
]
]
},
"properties": {}
};
const geojsonLayerGroup = L.geoJSON(geojsonData, {
onEachFeature: onEachFeature,
style: {
fillOpacity: 0.0,
color: '#424a44',
weight: 2
}
}).addTo(map);
L.tileLayer('https://{s}.tile.openstreetmap/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
html,
body,
#map {
height: 100%;
margin: 0;
}
<link rel="stylesheet" href="https://unpkg./[email protected]/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
<script src="https://unpkg./[email protected]/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>
<div id="map"></div>
Now from your ments, it sounds like you might run in the funny troubles of Angular zone. Actions that occur outside Angular Zone may not be painted by the browser.
If you try deselecting your layer and nothing seems to happen, try another action somewhere else in the browser: click somewhere else, resize the window, etc. If the deselection suddenly triggers, then it is most probably the effect of Angular Zone.
You could check by color and or the weight this will mean you have to overwrite the current behavior of highlight(Hover ie both the mouseover and mouseout) behavior so that you can differentiate when there is a click. this will mean doing something like
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: selectLayer
});
}
then selectLayer will be as
function selectLayer(e) {
let isLayerAlreadySelected = ((e.target.options.color === '#004691') &&(e.target.options.weight === 3))
if(isLayerAlreadySelected)
layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
else
layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
}
This will mean that the highlightFeature will be as follows
//Here you should set the highlight features different from when its clicked particularly take note of your wight and color since its what we use for the logic.
function highlightFeature(e) {
let layer = e.target;
layer.setStyle({
weight: 1,
color: '#666',
fillOpacity: 0.1
});
}
similarly resetHighlight will be like
//basically you will be putting the styles to their default here what ever values you choosed as default
function resetHighlight(e) {
let layer = e.target;
layer.setStyle({
weight: 0,
color: '#424a44',
fillOpacity: 0
});
}
You might find this documentation useful leaflet layer
you can prefer a swapping of mouse event functions to perform delection of highlighted layer
layer.setStyle({
fillColor: getRandomColor(),
fillOpacity: 0.50,
stroke: false
});
layer.on('mouseover', function(e) {
highlightFeature(e);
//open popup;
var popup = L.popup()
.setLatLng(e.latlng)
.setContent(feature.properties.Name)
.openOn(mymap);
});
layer.on('mouseout', function(e) {
defaultFeature(e);
//open popup;
var popup = L.popup()
.setLatLng(e.latlng)
.setContent(feature.properties.Name)
.openOn(mymap);
});
defaultfeature() is defined to perform deselection
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function highlightFeature(e) {
highlightLayer = e.target;
if (e.target.feature.geometry.type === 'LineString') {
highlightLayer.setStyle({
color: '#ffff00',
});
} else {
highlightLayer.setStyle({
fillColor: getRandomColor(),
fillOpacity: .25
});
}
}
function defaultFeature(e) {
if (e.target!=null) {
highlightLayer.setStyle({
color: getRandomColor(),
fillOpacity:.50
});
} else {
highlightLayer.setStyle({
fillColor: highlightFeature(),
fillOpacity: .25
});
}
}
You can test which color the layer has:
onEachFeature: function(feature,layer) {
layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
layer.on('click', function(e) {
let isLayerAlreadySelected = e.target.options.color === '#004691';
if(isLayerAlreadySelected)
e.target.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
else
e.target.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
});
}