Select to view content in your preferred language

Remove a single graphics from graphics layer

8695
8
Jump to solution
04-10-2017 11:01 AM
RachelAlbritton
Frequent Contributor

I have a series of graphics that get added to a single graphics layer when a user toggles on a switch. There are different toggles for each graphic (they're routes to bus lines) but all route graphics are being added to the same graphics layer. When a user toggles off a certain route, I want the route to be removed from the graphics layer, but keep the other routes on the graphics layers if they're toggled on. I have assigned the graphic being added a unique ID, however, using graphicsLayerName.remove(graphicID) isn't working for me.

//create graphic layer
app.routesGraphicsLayer = new GraphicsLayer({
  id:'routesGraphicsLayer'
])

//Add graphics layer
app.map.addLayer(app.routesGraphicsLayer)
app.routesGraphicsLayer.hide() //will get shown when toggled on

//Create unique variable names for graphic IDs
var redRoute;

//When Toggled ON:
app.handleLayerVis = function (switchName, state) {
    require(["dojo/dom","dojo/dom-class","dojox/mobile/Switch"], function(dom,domClass,Switch){
      console.log(switchName + " -- " + state);
      if (state === "on") {
        console.log('app.showLoading()');
        app.showLoading();
      }

      //hide popup
      if (state === "off") {
        app.map.infoWindow.hide();
      }

      switch (switchName) {
         case "redShuttleSwitch":
          if (state === "on") {
            //Turn off All Active Shuttles if its currently toggled on
            app.switchLogic();
                //Request Route
                app.esriRouteRequest(15).then(function (routeResponse) {
                  app.routesGraphicFunction("Red", routeResponse, app.routesGraphicsLayer, redRoute);
                  //Display route 
                  app.showGraphicsLayer('routesGraphicsLayer');
                });
          
          else {
            //when route gets toggled off, remove graphic from graphics layer 
            app.routesGraphicsLayer.remove(redRoute);
            app.routesGraphicsLayer.redraw();
          }
          break;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 app.esriRouteRequest = function() {
    var routeRequest = new esriRequest({
      url: "http://www.uofubus.com/Services/JSONPRelay.svc/GetRoutesForMapWithScheduleWithEncodedLine",
      content: {
        apikey: "ride1791",
      },
      handleAs: "json",
      callbackParamName: "method"
    });
    routeRequest.then(app.routeRequestSucceeded, app.requestFailed);
    return routeRequest;
  }
  app.routeRequestSucceeded = function(data) {
    routesArray = [];
    for (i = 0; i < data.length; i++) {
      routesArray.push(data[i]);
    }
    return routesArray;
  }

  app.routesGraphicFunction = function (colorDescription, data, graphicslayer, routeGraphic) {

    var routeObjects = data;
    for (i = 0; i < routeObjects.length; i++) {
      if (routeObjects[i].Description == colorDescription){
        //Create Symbology
        var routeSLS = new SimpleLineSymbol ().setStyle(SimpleLineSymbol.STYLE_SOLID).setWidth(4).setColor(new Color(routeObjects[i].MapLineColor));
        //Create InfoTemplate
        var routesInfoTemplate = new InfoTemplate (routeObjects[i].Description+" Line", "<b>Stops Schedule: </b>" + app.moreInfoHyperlink(routeObjects[i].StopTimesPDFLink))
        //Create Graphic
        routeGraphic = new Graphic(new Polyline(app.decodeGooglePolyline(routeObjects[i].EncodedPolyline), app.map.SpatialReference), routeSLS, routeObjects[i].StopTimesPDFLink, routesInfoTemplate);
      }
    }
    //Add graphics to graphics layer
    graphicslayer.add(routeGraphic);
  }
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

R,

 You loop through the GraphicsLayer.graphics and look at each graphic for the unique Id.

View solution in original post

0 Kudos
8 Replies
RobertScheitlin__GISP
MVP Emeritus

R.

   So a GraphicsLayer.remove is expecting to be based a Graphic (not an Id), so is redRoute an actual graphic?

app.routesGraphicsLayer.remove(redRoute);
0 Kudos
RachelAlbritton
Frequent Contributor

Robert - 

My intention is that it is but I must be doing this incorrectly. 

In my app.routesGraphicFunction (line 66), at the very end of the function I create a new Graphic (line 76). 

in the function, rather than assigning a variable to the new graphic, I assign an argument that can be passed into the function with the idea that the argument value is the unique id. So in this example, when I call the app.routesGraphicFunction, I pass the argument redRoute as the new graphic variable.

'redRoute' was already defined as a global variable on line 11. 

What is an alternative for identifying a unique graphic?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

R,

 You loop through the GraphicsLayer.graphics and look at each graphic for the unique Id.

0 Kudos
RachelAlbritton
Frequent Contributor

Thanks Robert - that visually does what I need, but I am getting errors in the console which is leading me to believe that I may be doing something that's going to come back to bite me. 

I wrote in an app.removeGraphics function (see below) that loops through the graphics layer and identifies a graphic based on a graphic attribute. IF=f that attribute is there, the graphic is removed. When I toggle one line on and off the graphic clears and no errors are logged to the console. However, when I have 2 or more toggled turned on, the routes still are removed when toggled off, but I get an error in the console. I tried logging the graphicsLayer.graphics properties to the console directly after and new line gets toggled on and then again once a line gets toggled off and then removed. The logs beforehand loos as expected, but when I toggle off a line a get an empty array back even though there is still at least one graphic left visible on the graphics layer. 

Error:

main.js:2446 Uncaught TypeError: Cannot read property 'attributes' of undefined

New function:

app.removeGraphic = function (graphicsLayer, description){
  for (gL = 0; graphicsLayer.graphics.length; gL++){
    if (graphicsLayer.graphics[gL].attributes[0] == description){
      graphicsLayer.remove(graphicsLayer.graphics[gL]);
      graphicsLayer.redraw();
    }
  }
}
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

R,

   If you are going to remove items that you are looping though them you need to loop though in reverse (i.e. gl--).

RachelAlbritton
Frequent Contributor

Robert - 

I get a similar outcome, except, I now get the same error if I only toggle one layer on then off. 

app.removeGraphic = function (graphicsLayer, description){
  for (gL = graphicsLayer.graphics.length; gL>0; gL--){
    if (graphicsLayer.graphics[gL].attributes[0] == description){
      graphicsLayer.remove(graphicsLayer.graphics[gL]);
      //graphicsLayer.redraw();
    }
  }
}

I also tried it with

(gL = graphicsLayer.graphics.length-1

but then the graphic wasn't removed

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

R,

   The

gl = graphicsLayer.graphics.length -1

is the correct way.

So when you add these graphics they only have on attribute? Have you debugged this app and placed a break point in the for loop to see if 

graphicsLayer.graphics[gL].attributes[0]

is what you are expecting it to be?

RachelAlbritton
Frequent Contributor

Robert - Yes, I've been doing some console logs and breakpoints. I solved the issue by changing

 for (gL = graphicsLayer.graphics.length; gL>0; gL--){

to

 gL>=0

Now all graphics get removed when expected and no errors. Thank you. 

0 Kudos