Hide Table of Contents
View Change attribute used for a renderer sample in sandbox
Change attribute used for a renderer

Description

This functionality requires an ArcGIS Server 10.1 service.

Dynamic layers provide the ability to change the renderer(s) for layers in a dynamic map service. In this sample, a drop-down list is populated with attribute field names for a layer that is displayed on the map using an ArcGIS Server 10.1 dynamic layer and a dynamic map service layer. When the selected field changes, a new map image is requested using the new field as the basis for the layer's renderer.

Code

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Change attribute used for a renderer</title>
    <link rel="stylesheet" href="https://js.arcgis.com/3.21/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.21/esri/css/esri.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      h3 { margin: 0 0 5px 0; border-bottom: 1px solid #444; text-align: center; }
      .shadow {
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      #map{ margin: 0; padding: 0; }
      #feedback {
        background: #fff;
        color: #444;
        font-family: arial;
        left: 30px;
        margin: 5px;
        padding: 10px;
        position: absolute;
        top: 30px;
        width: 300px;
        z-index: 40;
      }
      #note { font-size: 80%; font-weight: 700; padding: 0 0 10px 0; }
      #legendDiv { padding: 10px 0 0 0; }
    </style>

    <script src="https://js.arcgis.com/3.21/"></script>
    <script>
      // one global for persistent app variables
      var app = {};
      require([
        "esri/map",
        "esri/layers/ArcGISTiledMapServiceLayer", "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/request", "esri/config",
        "esri/tasks/ClassBreaksDefinition", "esri/tasks/AlgorithmicColorRamp",
        "esri/tasks/GenerateRendererParameters", "esri/tasks/GenerateRendererTask",
        "esri/layers/LayerDrawingOptions",
        "esri/symbols/SimpleFillSymbol", "esri/dijit/Legend",
        "dojo/parser", "dojo/_base/array", "esri/Color", "dojo/dom-style",
        "dojo/json", "dojo/dom",
        "dojo/data/ItemFileReadStore",
        "dijit/registry",

        "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/FilteringSelect",
        "dojo/domReady!"
      ], function(
        Map,
        ArcGISTiledMapServiceLayer, ArcGISDynamicMapServiceLayer,
        esriRequest, esriConfig,
        ClassBreaksDefinition, AlgorithmicColorRamp,
        GenerateRendererParameters, GenerateRendererTask,
        LayerDrawingOptions,
        SimpleFillSymbol, Legend,
        parser, arrayUtils, Color, domStyle,
        JSON, dom,
        ItemFileReadStore,
        registry
      ) {
        parser.parse();

        esriConfig.defaults.io.proxyUrl = "/proxy/";

        app.dataUrl = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2";
        app.defaultFrom = "#ffffcc";
        app.defaultTo = "#006837";

        app.map = new Map("map", {
          center: [-85.787, 39.782],
          zoom: 6,
          slider: false
        });

        var basemap = new ArcGISTiledMapServiceLayer("https://services.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer");
        app.map.addLayer(basemap);
        var ref = new ArcGISTiledMapServiceLayer("https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer");
        app.map.addLayer(ref);

        // add US Counties as a dynamic map service layer
        var urlDyn = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer";
        var usaLayer = new ArcGISDynamicMapServiceLayer(urlDyn, {
          id: "us_counties",
          opacity: 0.7,
          visible: false
        });
        usaLayer.setVisibleLayers([2]);
        app.map.addLayer(usaLayer);

        // get field info
        var countyFields = esriRequest({
          url: app.dataUrl,
          content: {
            f: "json"
          },
          callbackParamName: "callback"
        });
        countyFields.then(function(resp) {
          var fieldNames, fieldStore;

          fieldNames = { identifier: "value", label: "name", items: [] };
          arrayUtils.forEach(resp.fields.slice(6, 16), function(f) { // add some field names to the FS
            fieldNames.items.push({ "name": f.name, "value": f.name });
          });
          fieldStore = new ItemFileReadStore({ data: fieldNames });
          registry.byId("fieldNames").set("store", fieldStore);
          registry.byId("fieldNames").set("value", "POP2007"); // set a value
        }, function(err) {
          console.log("failed to get field names: ", err);
        });

        // update renderer when field name changes
        registry.byId("fieldNames").on("change", getData);
        registry.byId("fieldNames").set("value", "POP_2007"); // triggers getData()

        function getData() {
          classBreaks(app.defaultFrom, app.defaultTo);
        }

        function classBreaks(c1, c2) {
          var classDef = new ClassBreaksDefinition();
          classDef.classificationField = registry.byId("fieldNames").get("value") || "POP2000";
          classDef.classificationMethod = "natural-breaks"; // always natural breaks
          classDef.breakCount = 5; // always five classes

          var colorRamp = new AlgorithmicColorRamp();
          colorRamp.fromColor = new Color.fromHex(c1);
          colorRamp.toColor = new Color.fromHex(c2);
          colorRamp.algorithm = "hsv"; // options are:  "cie-lab", "hsv", "lab-lch"

          classDef.baseSymbol = new SimpleFillSymbol("solid", null, null);
          classDef.colorRamp = colorRamp;

          var params = new GenerateRendererParameters();
          params.classificationDefinition = classDef;
          var generateRenderer = new GenerateRendererTask(app.dataUrl);
          generateRenderer.execute(params, applyRenderer, errorHandler);
        }

        function applyRenderer(renderer) {
          // dynamic layer stuff
          var optionsArray = [];
          var drawingOptions = new LayerDrawingOptions();
          drawingOptions.renderer = renderer;
          // set the drawing options for the relevant layer
          // optionsArray index corresponds to layer index in the map service
          optionsArray[2] = drawingOptions;
          app.map.getLayer("us_counties").setLayerDrawingOptions(optionsArray);
          app.map.getLayer("us_counties").show();
          // create the legend if it doesn't exist
          if ( ! app.hasOwnProperty("legend") ) {
            createLegend();
          }
        }

        function createLegend() {
          app.legend = new Legend({
            map : app.map,
            layerInfos : [ {
              layer : app.map.getLayer("us_counties"),
              title : "US Counties"
            } ]
          }, dom.byId("legendDiv"));
          app.legend.startup();
        }

        function errorHandler(err) {
          // console.log("Something broke, error: ", err);
          console.log("error: ", JSON.stringify(err));
        }
      });
    </script>
  </head>

  <body class="tundra">
    <div data-dojo-type="dijit/layout/BorderContainer"
         data-dojo-props="design:'headline',gutters:false"
         style="width: 100%; height: 100%; margin: 0;">
      <div id="map"
           data-dojo-type="dijit/layout/ContentPane"
           data-dojo-props="region:'center'">

        <div id="feedback" class="shadow">
          <h3>Change the Attribute Field Used to Render Data</h3>
          <div id="info">
            <div id="note">
              Note:  This sample requires an ArcGIS Server version 10.1 map service to generate a renderer.
            </div>

            
            <label for="fieldNames">Render based on: </label>
            <select id="fieldNames" name="baseSym"
                    data-dojo-type="dijit/form/FilteringSelect"
                    data-dojo-props="style:'width:200px;'">
            </select>

            <div id="legendDiv"></div>

          </div>
        </div>
      </div>
    </div>
  </body>
</html>