5

I am new to Javascript and somewhat new to GIS (especially web applications of GIS). I'm trying to understand how I can have a drop down menu or html buttons to change which data is rendered in my map.

I have a feature layer hosted on ArcGIS Online, so I don't think I can use ArcGISDynamicMapServiceLayer. This is only if you have ArcGIS Server, right? I only have ArcGIS Desktop.

I can, however, customize my renderer using ClassBreaksRenderer. I thought it would make sense to set up a few different renderers, like so:

            var approvalRate = new ClassBreaksRenderer(symbol, "MEAN_appro");
                approvalRate.addBreak(0,.19999, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));
                approvalRate.addBreak(.2,.39999, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
                approvalRate.addBreak(.4,.59999, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
                approvalRate.addBreak(.6,.79999, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
                approvalRate.addBreak(.8,1, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5]))); 

            var averageMortgageAmount = new ClassBreaksRenderer(symbol, "MEAN_dolla");
                averageMortgageAmount.addBreak(0, 24.9999, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));
                averageMortgageAmount.addBreak(25,49.9999, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
                averageMortgageAmount.addBreak(50,99.9999, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
                averageMortgageAmount.addBreak(100,199.9999, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
                averageMortgageAmount.addBreak(200,Infinity, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5])));  

So, I have two different renderers set up, called approvalRate and averageMortgageAmount.

I thought I could set up some logic to change which renderer is applied based on user input. So I have set up the renderer variable, get its value from a button, and use that to determine which renderer to use with a switch. Like below.

            var renderer;

            function getRenderer(rendererFromButton) {
                renderer = rendererFromButton;
            }

            switch(renderer) {
                case "Approval Rate":
                    featureLayer.setRenderer(approvalRate);
                    break;
                case "Average Mortgage Amount":
                    featureLayer.setRenderer(averageMortgageAmount);
                    break;
                default:
                    featureLayer.setRenderer(approvalRate);
            }

This ends up with a map that correctly renders approvalRate, but never actually changes dynamically. The buttons work right (I've tested the output of the variable "renderer" value after pressing the buttons and it is correct).

It seems like the problem lies in the browser calling the map server again. I don't know what I'm talking about here, but I assume once the map is rendered by the server and sent to the browser as a graphic layer or whatever, it can't be called again and re-rendered.

Is that true?

Here's what I have so far: http://matthewiannowlin.com/planning/thesis/

This is long-winded, but I figured more detail gets a more helpful answer.

Bottom line: is there anyway I can change which field is rendered from an ArcGIS Online feature layer with user input? Do I need to link to different pages that each have different renderers defined? Or do I need to just get ArcGIS Server?

2 Answers 2

1

Thanks for the help above. It got me on the right track. I couldn't make either of those solutions work (likely due to my own errors), but I did get it to work by removing the featureLayer, setting the renderer, and then adding the featureLayer again:

function getRenderer(rendererFromSelect) {
 renderer = rendererFromSelect.value;
 switch(renderer) {
  case "approvalRate":
   map.removeLayer(featureLayer);
   featureLayer.setRenderer(approvalRate);
   map.addLayer(featureLayer);
   break;
  case "averageMortgageAmount":
   map.removeLayer(featureLayer);
   featureLayer.setRenderer(averageMortgageAmount);
   map.addLayer(featureLayer);
   break;
  case "homePurchaseRate":
   map.removeLayer(featureLayer);
   featureLayer.setRenderer(homePurchaseRate);
   map.addLayer(featureLayer);
   break;
  case "homeImprovementRate":
   map.removeLayer(featureLayer);
   featureLayer.setRenderer(homeImprovementRate);
   map.addLayer(featureLayer);
   break;
  case "totalLoanApps":
   map.removeLayer(featureLayer);
   featureLayer.setRenderer(totalLoanApps);
   map.addLayer(featureLayer);
   break;
 }
}

Because the switch is in a separate function from the map instance, I also had to change map and featureLayer to global variables (as well as all my renderers).

Once I did that it works perfectly. You can check it out here.

1
  • if you want to use a local scoped variable for the featureLayer, you could use its ID to get it. var fLayer = map.getLayer("myFeatureLayerId"); Commented Jan 13, 2015 at 17:43
1

Change your getRenderer() to this to prevent the featureLayer from flickering I remove the map.removeLayer and map.addLayer.

function getRenderer(rendererFromSelect) {
   renderer = rendererFromSelect.value;
   switch(renderer) {
    case "approvalRate":   
     featureLayer.setRenderer(approvalRate);   
     document.getElementById("legend0").style.display = "none";
     document.getElementById("legend1").style.display = "block";
     document.getElementById("legend2").style.display = "none";
     document.getElementById("legend3").style.display = "none";
     document.getElementById("legend4").style.display = "none";
     document.getElementById("legend5").style.display = "none";
     legend1.refresh();
     break;
    case "averageMortgageAmount":   
     featureLayer.setRenderer(averageMortgageAmount);
     document.getElementById("legend0").style.display = "none";
     document.getElementById("legend1").style.display = "none";
     document.getElementById("legend2").style.display = "block";
     document.getElementById("legend3").style.display = "none";
     document.getElementById("legend4").style.display = "none";
     document.getElementById("legend5").style.display = "none";
     legend2.refresh();
     break;
    case "homePurchaseRate":   
     featureLayer.setRenderer(homePurchaseRate);   
     document.getElementById("legend0").style.display = "none";
     document.getElementById("legend1").style.display = "none";
     document.getElementById("legend2").style.display = "none";
     document.getElementById("legend3").style.display = "block";
     document.getElementById("legend4").style.display = "none";
     document.getElementById("legend5").style.display = "none";
     legend3.refresh();
     break;
    case "homeImprovementRate":  
     featureLayer.setRenderer(homeImprovementRate);
     document.getElementById("legend0").style.display = "none";
     document.getElementById("legend1").style.display = "none";
     document.getElementById("legend2").style.display = "none";
     document.getElementById("legend3").style.display = "none";
     document.getElementById("legend4").style.display = "block";
     document.getElementById("legend5").style.display = "none";
     legend4.refresh();
     break;
    case "totalLoanApps":
     featureLayer.setRenderer(totalLoanApps);
     document.getElementById("legend0").style.display = "none";
     document.getElementById("legend1").style.display = "none";
     document.getElementById("legend2").style.display = "none";
     document.getElementById("legend3").style.display = "none";
     document.getElementById("legend4").style.display = "none";
     document.getElementById("legend5").style.display = "block";
     legend5.refresh();
     break;
   }

   featureLayer.redraw();
  }
1
  • I couldn't get this to work, but I'm hesitant to say it's incorrect, because it's probably my own errors that prevented this from working. However, I did make the solution I posted work. Commented Jan 13, 2015 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.