Hide/Show graphic with 4.3 API

4012
5
Jump to solution
05-16-2017 01:37 PM
deleted-user-db3s_-rQ1tkN
New Contributor

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;
                        }             
                    }
                });
            }
        });
    });
1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

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.

View solution in original post

0 Kudos
5 Replies
KellyHutchins
Esri Frequent Contributor

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'";
ThomasSolow
Occasional Contributor III

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.

0 Kudos
mgeorge
Esri Contributor

FYI, we recently added a client-side FeatureFilter which provides a fast way of hiding/showing features based on an attribute. 

0 Kudos
williampreston
New Contributor II

How is "it's broken and won't be fixed" an answer?  This should be something simple. THis should be something that works. 

ThomasSolow
Occasional Contributor III

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 

0 Kudos