theis188 theis188 - 1 month ago 13
Javascript Question

leaflet.js highlight GeoJSON on mouseover of separate list

edit: Here is a jsfiddle mockup: https://jsfiddle.net/6t8gnegf/

I have a table of locations outside the map and I want to have each area highlight when the corresponding table element is moused over. So I first make a list of the geojson layers, keyed by a name property:

var layarr = {}
for (i=0;i<listOfNames.length;i++) {
for (var prop in geojson['_layers']) {
if (!geojson['_layers'].hasOwnProperty(prop)) {
continue;
}
if (geojson['_layers'][prop]["feature"]["properties"]["name"]==listOfNames[i]) {
layarr[listOfNames[i]] = geojson['_layers'][prop]
}
}
}


Then I call this function:

function highlight(name) {
var laytouse = layarr[name]
laytouse.setStyle(highlightStyle)
}


Nothing happens, not even an error.

I already have a highlight function that works when the actual area on the map is moused over:

function highlightFeature(e) {
var layer = e.target;
layer.setStyle(highlightStyle);
}


Which is called in the following way:

function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
});
}

geojson=L.geoJson(neighbData, {style: style,
onEachFeature: onEachFeature
}).addTo(mymap);


Even if I do something like this directly on the console:

layarr[name].setStyle({fillOpacity: 1});


I still get nothing. It seems like I'm getting the wrong layer somehow, but the layer has the expected setStyle() method and I'm not getting any console errors.

edit: jsfiddle mockup: https://jsfiddle.net/6t8gnegf/

Answer

gist solution

Your question is very close to this one: Accessing Leaflet.js GeoJson features from outside. The trick is that the geoJSON layer is in fact a layergroup, and you can therefore use the layergroup methods, such as getLayer().

The idea is that you want to access your features based on their id. You first need to attach the polygon ID to your locations in the table (in the list in my gist example):

function onEachFeature(feature, layer) {
    nhood = parseInt(feature.id);
    name = feature.properties.name;
    $('#neighborhood').append('<li value="' + nhood + '">'+name+'</li>');
    layer._leaflet_id = nhood;
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
    });
}

Then when you mouseenter a location, you highlight the feature that matches the id of the location, as follows:

var hovered_id, layer;

$('#neighborhood li').on('mouseenter', function(e){
        hovered_id = e.target.value;
        layer = geojson.getLayer(hovered_id); //your feature id here
        layer.setStyle(highlightStyle);
    }).on('mouseout', function(e){
        geojson.resetStyle(layer);
    });

Please have a look at the gist I created, and you will see that the code is in reality much simpler than the one you initially shared.

EDIT: the leaflet ids must be unique, and the neighborhood names should be assigned to the feature ids. Below is the updated code:

function onEachFeature(feature, layer) {
    name = feature.properties.name;
    $('#neighborhood').append('<li data-value="' + name + '">'+name+'</li>');
    layer._leaflet_id = name;
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
    });
}

var hovered_id, layer;

$('#neighborhood li').on('mouseenter', function(e){
        hovered_id = $(e.target).data('value');
        console.log(hovered_id);
        layer = geojson.getLayer(hovered_id); //your feature id here
        layer.setStyle(highlightStyle);
    }).on('mouseout', function(e){
        geojson.resetStyle(layer);
    });
Comments