3.2 has a hide and show method for a graphic. Is there a way to do this with the 4.3 API? I've tried setting the visible property to false but the features still show on the map. What is the proper way to do this?
Example of how I'm trying to hide certain graphics based on attribute. All features still show on map.
view.whenLayerView(layerID).then(function (lyrView) {
lyrView.watch("updating", function (val) {
if (!val) {
lyrView.queryFeatures().then(function (results) {
for (var i = 0; i < results.length; i++) {
if (results[i].attributes.dow = "Tuesday") {
results[i].visible = false;
}
}
});
}
});
});
Solved! Go to Solution.
Setting the 'visible' property on a graphic works in 3D, so my feeling is that it should work in 2D also, but it doesn't right now.
example: JS Bin - Collaborative JavaScript Debugging
edit: I can confirm that this is a known issue. It doesn't look like it will be fixed by 4.4 though.
One simple way to do this would be to apply a definition expression to the layer. For example this expression will display all features where the Status is not equal to P or I.
featureLayer.definitionExpression = "Not Status = 'P' AND Not Status = 'I'";
Setting the 'visible' property on a graphic works in 3D, so my feeling is that it should work in 2D also, but it doesn't right now.
example: JS Bin - Collaborative JavaScript Debugging
edit: I can confirm that this is a known issue. It doesn't look like it will be fixed by 4.4 though.
FYI, we recently added a client-side FeatureFilter which provides a fast way of hiding/showing features based on an attribute.
How is "it's broken and won't be fixed" an answer? This should be something simple. THis should be something that works.
I didn't mean to imply that it was broken, which would mean that there's a bug to be fixed. That isn't the case as far as I know. My understanding is that some work needs to be done to deliver this functionality.
I agree that this should work. But there are workarounds.
For feature layers, I suggest you use a definition expression to show/hide certain features. For graphics layers you can probably get away with cloning and flipping the visibility property of the clone. Something like this:
// for graphics layer
// clone graphic and toggle visibility, remove old graphic and add clone
function toggleVisibility(graphic){
if (graphic.layer && graphic.layer.declaredClass === 'esri.layers.GraphicsLayer'){
const clone = graphic.clone();
clone.visibility = !graphic.visibility;
graphic.layer.remove(graphic);
graphic.layer.add(clone);
}
}
// for feature layer
// keep track of hidden graphics
let hiddenGraphics = []
// takes objectIdField and array of graphics and returns a definition expression
// to hide all those graphics
function getDefExpression(oidField, graphicsArray){
return graphicsArray.reduce((accum, curr) => {
if (accum.length === 0){
return `${oidField} != ${curr.attributes[oidField]}`;
} else {
return `${accum} AND ${oidField} != ${curr.attributes[oidField]}`;
}
},"");
}
// takes a graphic and uses the above function and array to toggle its visbility
// via definition expression
function toggleVisibility(graphic){
const layer = graphic.layer;
const oidField = layer.objectIdField;
if (layer && layer.declaredClass === 'esri.layers.FeatureLayer'){
let idx = hiddenGraphics.indexOf(graphic);
if (idx >= 0){
hiddenGraphics.splice(idx, 1);
} else {
hiddenGraphics.push(graphic);
}
layer.definitionExpression = getDefExpression(oidField, hiddenGraphics);
}
}
Here's a sample for feature layers. Click on graphics to hide them: JS Bin - Collaborative JavaScript Debugging