Hi everyone,
I am using the highlight method (https://developers.arcgis.com/javascript/latest/api-reference/esri-views-layers-FeatureLayerView.htm... https://developers.arcgis.com/javascript/latest/sample-code/highlight-point-features/) on the map view to highlight individual points one by one based on user input from another part of my application.
highlighted = mapView.highlight(feature);
Given that there are multiple features highlighted, is there a way to selectively remove the highlight from a feature (perhaps using the ObjectId or attribute) without removing the highlight from all of the features?
Every example that I've seen so far suggests removing all of the highlights and then creating a new highlight with the new graphic or array of graphics, like so.
if (highlighted) {
highlighted.remove();
}
highlighted = mapView.highlight(feature); // new graphic or array of graphics
This technically works, but it creates an undesirable effect where the highlighted features briefly flash before showing the new highlighted selection. If possible, I do not want the highlighted features to flash when removing/updating a highlight.
I've been looking into this for a while now and haven't found a solution. I'm hoping there is some way to do it. It looks possible because the Feature Table widget has a highlightOnRowSelectEnabled property, and that works smoothly when adding/removing highlights, but I don't know if any part of that is transferable here.
Any help is much appreciated. Thanks in advance!
Solved! Go to Solution.
I had a look at the API and you can use the following example -
view.allLayerViews.items[2]._highlightIds.delete(7423)
item #2 is the feature layer object - in your case, you'll need to recognise the right layer in the array of allLayersViews. You can do that in many way (hard coded like in my example would be the worse option.
Once you have the layer object available, you could have access to an object called _highlightIds which contains a map of all highlighted features. This array has a delete function that you pass an objectId you would like to remove as highlighted.
Hi,
Have you tried to highlight all the relevant features again minus the one you want to remove the highlight for?
Hi @shaylavi ,
Thanks for your reply. Yes, I have tried to call highlight again on the modified array. Added features get highlighted just fine, but any features that I remove from the array stay highlighted on the map (hence the need to remove all existing highlights before calling highlight again, but then this causes the flashing).
Well, I haven't checked this myself but my guess is that when features are highlighted, it's a new separated graphic layer created, which you can access and modify manually. Once you are able to validate this, your next issue would probably be to recognise the right point you would like to remove, which surely can be solved easily with a filter based on an attribute. Hope that make sense
Hi @shaylavi,
Thanks. Your explanation makes sense, but how do I access the separated graphic layer that was created so that I can query it for the right point? I don't have a reference to the layer, I don't know the ID, and it doesn't show up when I loop through all layers (I'm sure I'm overlooking something here).
I had a look at the API and you can use the following example -
view.allLayerViews.items[2]._highlightIds.delete(7423)
item #2 is the feature layer object - in your case, you'll need to recognise the right layer in the array of allLayersViews. You can do that in many way (hard coded like in my example would be the worse option.
Once you have the layer object available, you could have access to an object called _highlightIds which contains a map of all highlighted features. This array has a delete function that you pass an objectId you would like to remove as highlighted.
@shaylavi, that worked! Great! A BIG thank you! 🙂
I had to use _updateHighlight after removing the feature in order to see the change on the map.
const layer = view.allLayerViews.items.filter(d => d.layer.id === 'layer-id')[0]
layer._highlightIds.delete(id) // feature - object id
layer._updateHighlight();
Cool, glad I could help
I was going through the same issue and I did it like this. hope this will be helpful for many. basic idea I took from shaylavi's code. Thanks man.
this.appConfig.activeView.allLayerViews.items.forEach((item:any) => {
if (item && item._highlightIds) {
item._highlightIds.clear();
}
});
let results = event.results.filter((result:any) => {
if (result.graphic.layer.type === "feature") {
return result;
}
});
results.forEach((result:any) => {
if (result) {
this.layerViewCollection.forEach((layerView:any) => {
if (layerView.layer === result.graphic.layer) {
const highlightGraphic = layerView.highlight(result.graphic.clone());
this.appConfig.activeView.graphics.add(highlightGraphic);
this.highlights.push(highlightGraphic);
const feature = result.graphic;
popup.open({
location: event.mapPoint,
features: [feature],
});
}
});
}
});
Today I'd recommend using the includedEffect (see link below) on a point layer that will highlight the clicked points and have a second points layer with the same symbology to make sure excluded/unclicked points will remain the same.. this is a faster and cheaper way to highlight points.
https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FeatureEffect.html