LabelExpressionInfo not honoring where clause

4945
23
07-14-2015 01:20 PM
DavidColey
Frequent Contributor

Hello-

So I'm trying to override the default feature layer labels, but the where clause isn't being honored.  For my map constructor options:

showLabels : true

My LabelingInfo:

var labelArray = [
  {
  labelPlacement: "esriServerPointLabelPlacementAboveRight",
  labelExpression: "[AddNumber]",
  symbol: {
    type: "esriTS",
      color: [255,0,0,255], //[38,115,0,255],
      font: {
      family: "Arial",
      size: 9,
      style: "italic",
      weight: "bold",
      decoration: "none",
    }
    },
    minScale: 2401,
    maxScale: 0,
    where: "AddressStatus LIKE 'A%'"
  }
  ];
  console.log(labelArray);

and finally for the feature layer:

lyrAddresses.setLabelingInfo(labelArray);

All of the other constructor options for the labelng info are being honored, but wheneverI try to invoke the where clause, none of the points will label-

Thanks

David

Tags (3)
0 Kudos
23 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

David,

  Here is a sample app that uses the where clause in a LabelClass (and it works just fine):

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title></title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/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; }
      #loading { visibility: hidden; }
      #legendDiv { padding: 10px 0 0 0; }
    </style>

    <script src="http://js.arcgis.com/3.10/"></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/layers/LabelClass","esri/symbols/TextSymbol",
        "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,LabelClass,TextSymbol,
        SimpleFillSymbol, Legend,
        parser, arrayUtils, Color, domStyle,
        JSON, dom,
        ItemFileReadStore,
        registry
      ) {
        parser.parse();

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

        app.map = new Map("map", {
          center: [-86.708254, 33.053200],
          zoom: 8,
          slider: false
        });

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

        // add US Counties as a dynamic map service layer
        urlDyn = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer";
        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);
        });

        // hide the loading icon when the counties layer finishes updating
        usaLayer.on("update-end", function() {
          domStyle.set("loading", "visibility", "hidden");
        });

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

        function getData() {
          // dynamic layer stuff
          var optionsArray = [];
          var drawingOptions = new LayerDrawingOptions();
          var labelClass = new LabelClass({
            labelExpression: '[' + (registry.byId("fieldNames").get("value") || "POP2000") +']',
            labelPlacement: 'esriServerPolygonPlacementAlwaysHorizontal',
            symbol: new TextSymbol(),
            where: "STATE_NAME = 'Alabama'"
          });

          drawingOptions.labelingInfo = [labelClass];
          drawingOptions.showLabels = true;

          // 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();
        }

        function errorHandler(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>

            <!-- filtering select -->
            <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>

            <img id="loading" src="http://dl.dropbox.com/u/2654618/loading_black.gif" />

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

          </div>
        </div>
      </div>
    </div>
  </body>
</html>
thejuskambi
Regular Contributor

Robert,

Your example is for Dynamic layers and the question is for FeatureLayer. Does FeatureLayer support Labelinginfo.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Thejus,

  Man, I completely missed that. FeatureLayer does support labelingInfo though.

FeatureLayer | API Reference | ArcGIS API for JavaScript | labelingInfo

So let me see if I can create a sample for FeatureLayer instead.

0 Kudos
DavidColey
Frequent Contributor

Thanks Robert.  I wasn't actually specifiying a labelClass reference as I wasn't sure I needed to  - - that's likely what I am missing.

David

0 Kudos
JssrRR
by
Occasional Contributor II

This tutorial shows how to label a FeatureLayer, step 5 using Label layer and specifying the field to use as the source for labels:

Labeling features client-side | Guide | ArcGIS API for JavaScript

RobertScheitlin__GISP
MVP Esteemed Contributor

David,

  OK here is an updated sample for labeling a Feature Layer.

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title></title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/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;
      }
      #loading { visibility: hidden; }
    </style>

    <script src="http://js.arcgis.com/3.10/"></script>
    <script>
      // one global for persistent app variables
      var app = {};
      require([
        "esri/map",
        "esri/layers/ArcGISTiledMapServiceLayer",
        "esri/layers/FeatureLayer",
        "esri/layers/LabelLayer",
        "esri/renderers/SimpleRenderer",
        "esri/request",
        "esri/symbols/TextSymbol",
        "dojo/parser",
        "dojo/json",
        "dojo/dom",
        "dojo/data/ItemFileReadStore",
        "dijit/registry",
        "dojo/_base/array",
        "dojo/dom-style",
        "esri/Color",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dijit/form/FilteringSelect",
        "dojo/domReady!"
      ], function(
        Map,
        ArcGISTiledMapServiceLayer,
        FeatureLayer,
        LabelLayer,
        SimpleRenderer,
        esriRequest,
        TextSymbol,
        parser,
        JSON,
        dom,
        ItemFileReadStore,
        registry,
        arrayUtils,
        domStyle,
        Color
      ) {
        parser.parse();

        app.dataUrl = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2";

        app.map = new Map("map", {
          center: [-86.708254, 33.053200],
          zoom: 8,
          slider: false,
          showLabels : true
        });

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

        // add US Counties as a Feature layer
        var usaLayer = new FeatureLayer(app.dataUrl, {
          id: "us_counties",
          opacity: 0.7,
          visible: true
        });
        app.map.addLayer(usaLayer);

        var usaLblLayer = new FeatureLayer(app.dataUrl, {
          id: "us_counties_lbl",
          opacity: 0.7,
          visible: true,
          outFields: ["*"]
        });
        usaLblLayer.setDefinitionExpression("STATE_NAME = 'Alabama'");
        app.map.addLayer(usaLblLayer);

        // 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);
        });

        // hide the loading icon when the counties layer finishes updating
        usaLayer.on("update-end", function() {
          domStyle.set("loading", "visibility", "hidden");
        });

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

        function getData() {
          var fl = app.map.getLayer("us_counties_lbl");
          if(app.map.getLayer("labels")){
            app.map.removeLayer(app.map.getLayer("labels"));
          }
          var statesLabel = new TextSymbol().setColor(new Color("#ff0000"));
          statesLabel.font.setSize("14pt");
          statesLabel.font.setFamily("arial");
          var renderer = new SimpleRenderer(statesLabel);
          var labelLayer = new LabelLayer({ id: "labels" });
          labelLayer.addFeatureLayer(fl, renderer, "{" + (registry.byId("fieldNames").get("value") || "POP2000") + "}");
          app.map.addLayer(labelLayer);
        }

        function errorHandler(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 Label Data</h3>
          <div id="info">
            <!-- filtering select -->
            <label for="fieldNames">Label based on: </label>
            <select id="fieldNames" name="baseSym"
                    data-dojo-type="dijit/form/FilteringSelect"
                    data-dojo-props="style:'width:200px;'">
            </select>
            <img id="loading" src="http://dl.dropbox.com/u/2654618/loading_black.gif" />
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
DavidColey
Frequent Contributor

Robert,  I'm not certain I have made this situation clear. In your sample above, you're basically jsut adding a lable layer after a setDefinitionExpression has been applied to the feature layer that is passed into the label layer, then adding that label layer to the map which is totally doable.  What I am trying to do is set up two label classes with where clauses based on the REST API sample thusly:

var acClass =  new LabelClass({
  labelPlacement: "esriServerPointLabelPlacementAboveRight",
  labelExpression: "[AddNum]",
  symbol: {
    type: "esriTS",
      color: [38,115,0,255], //255,0,0,255],
      font: {
      family: "Arial",
      size: 7,
      style: "italic",
      weight: "bold",
      decoration: "none",
    },
    },
    minScale: 2401,
    maxScale: 0,
    //where: "AddressStatus LIKE 'A%'"
});

var iaClass =  new LabelClass({
  labelPlacement: "esriServerPointLabelPlacementAboveRight",
  labelExpression: "[AddNum]",
  symbol: {
    type: "esriTS",
      color: [255,0,0,255], //[38,115,0,255],
      font: {
      family: "Arial",
      size: 7,
      style: "italic",
      weight: "bold",
      decoration: "none",
    },
    },
    minScale: 2401,
    maxScale: 0,
    //where: "AddressStatus LIKE 'I%'"
});

Then add the label classes to an array:

var labelArray  = [acClass,iaClass];

and lastly set the labeling info on the feature layer per it's labeling info property accessed via setLabelingInfo method (per the jsapi):

lyrAddresses.setLabelingInfo(labelArray);

All of the value changes per label class optoins such as a placement change or a font style or color change are immediatly visible EXCEPT the where clauses.  Whenever I un-comment them, the labels will no longer render as graphics

David

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

David,

  Yep I am not able to label the layer using the LabelClass unless using a dynamic layer and NOT a FeatureLayer.

0 Kudos
thejuskambi
Regular Contributor

May be the LabelClass works for FeatureLayer if we set it before adding it/at the time of initializing it. Otherwise why would they provide  a setLabelingInfo method.