How to change Annotation Layer Text Color

1191
2
05-22-2019 09:30 AM
GregoryBologna
Occasional Contributor II

I want to change the text color of an Annotation Layer based on layer visibility. 

Annotation Text shown here in yellow. 

The yellow text does not change. I can change certain properties, like minScale, but I cannot add a labelingInfo class.

some info about the layer

Display Field: TEXTSTRING 

Type: Annotation Layer 

Has Labels: false
Can Modify Layer: false

Can Scale Symbols: true

Type ID Field: AnnotationClassID
Fields:

  • OBJECTID ( type: esriFieldTypeOID , alias: OBJECTID )
  • FEATUREID ( type: esriFieldTypeInteger , alias: FEATUREID )
  • ZORDER ( type: esriFieldTypeInteger , alias: ZORDER )
  • ANNOTATIONCLASSID ( type: esriFieldTypeInteger , alias: ANNOTATIONCLASSID )
  • ELEMENT ( type: esriFieldTypeBlob , alias: ELEMENT )
  • SYMBOLID ( type: esriFieldTypeInteger , alias: SYMBOLID )
  • STATUS ( type: esriFieldTypeSmallInteger , alias: STATUS , Coded Values: [0: Placed] , [1: Unplaced] )
  • TEXTSTRING ( type: esriFieldTypeString , alias: TEXTSTRING , length: 255 )
  • FONTNAME ( type: esriFieldTypeString , alias: FONTNAME , length: 255 )
  • FONTSIZE ( type: esriFieldTypeDouble , alias: FONTSIZE )
  • BOLD ( type: esriFieldTypeSmallInteger , alias: BOLD , Coded Values: [1: Yes] , [0: No] )
  • ITALIC ( type: esriFieldTypeSmallInteger , alias: ITALIC , Coded Values: [1: Yes] , [0: No] )
  • UNDERLINE ( type: esriFieldTypeSmallInteger , alias: UNDERLINE , Coded Values: [1: Yes] , [0: No] )
  • VERTICALALIGNMENT ( type: esriFieldTypeSmallInteger , alias: VERTICALALIGNMENT , Coded Values: [0: Top] , [1: Center] , [2: Baseline] , ...1 more... )
  • HORIZONTALALIGNMENT ( type: esriFieldTypeSmallInteger , alias: HORIZONTALALIGNMENT , Coded Values: [0: Left] , [1: Center] , [2: Right] , ...1 more... )
  • XOFFSET ( type: esriFieldTypeDouble , alias: XOFFSET )
  • YOFFSET ( type: esriFieldTypeDouble , alias: YOFFSET )
  • ANGLE ( type: esriFieldTypeDouble , alias: ANGLE )
  • FONTLEADING ( type: esriFieldTypeDouble , alias: FONTLEADING )
  • WORDSPACING ( type: esriFieldTypeDouble , alias: WORDSPACING )
  • CHARACTERWIDTH ( type: esriFieldTypeDouble , alias: CHARACTERWIDTH )
  • CHARACTERSPACING ( type: esriFieldTypeDouble , alias: CHARACTERSPACING )
  • FLIPANGLE ( type: esriFieldTypeDouble , alias: FLIPANGLE )
  • OVERRIDE ( type: esriFieldTypeInteger , alias: OVERRIDE )
  • SHAPE_AREA_1 ( type: esriFieldTypeDouble , alias: SHAPE_AREA_1 )
  • SHAPE_LEN_1 ( type: esriFieldTypeDouble , alias: SHAPE_LEN_1 )
  • SHAPE ( type: esriFieldTypeGeometry , alias: SHAPE )
  • SHAPE.AREA ( type: esriFieldTypeDouble , alias: SHAPE.AREA )
  • SHAPE.LEN ( type: esriFieldTypeDouble , alias: SHAPE.LEN )

Here is my map

      var mapLayerAndLabels = new MapImageLayer({
        url: mapLayerAndLabelsUrl,
        legendEnabled: true,
        visible: true,
        title: "Map Layers & Labels"
      }); // end mapLayerAndLabels
      map.add(mapLayerAndLabels);

Here is my basic labelClass that will be added on layer visibility

        const labelClass = {
          // autocasts as new LabelClass()
          symbol: {
            type: "text", // autocasts as new TextSymbol()
            color: "green"
          },
          font: { // autocast as new Font()
            size: 20,
            family: "sans-serif",
            weight: "bold"
          }
        };

The target layer. labelingInfo is null

watch event to add the labelClass

                  watchUtils.whenFalse(item, "visible", function (newVal) {
                    switch (item.title) {
                      case "Latest Aerial":
                        if (!item.visible) {
                          if (item.layer.parent.allLayers && item.layer.parent.allLayers.length > 0) {
                            item.layer.parent.allLayers.forEach(function (item) {
                              if (item.title === "Map Layers & Labels") {
                                if (item.sublayers && item.sublayers.length > 0) {
                                  item.sublayers.forEach(function (item) {
                                    if (item.title === "Parcel Dimensions") {
                                      item.minScale = 55555; // this changes
                                      item.labelingInfo = [labelClass]; // not working
                                    }
                                  });
                                }
                              }
                            });
                          }
                        }
                    } // end switch
                  }); // end whenFalse
0 Kudos
2 Replies
RobertScheitlin__GISP
MVP Emeritus

Gregory,

  No you will not be able to change the annotations color in JS code. You are using a MapImageLayer (i.e. a picture drawn by ArcGIS Server) so there is no ability to change the annotations color since that is controlled by ArcGIS server and the MXD settings for that Anno layer.

GregoryBologna
Occasional Contributor II

Thanks Robert. Due to this limitation, the way I am handling this is by creating two listitems, one with black font color and the other with yellow, then toggling their listMode and visibility states.

Yellow font color looks really good on the aerials, but not on the beige background of basemaps. The yellow font is difficult to see. This is when I want to use the black font color.

Using two different layer listitems (black font and yellow), and watchUtils, I toggle the two aerial layers so only one will be checked in my LayerList design. Then I iterate over the listitems and set their listMode and visibility based on the font I want to use.

Black font color                                                                   Yellow font color

 

                  watchUtils.whenFalse(item.layer, "visible", function (newVal) {
                    layerListFormat(item);
                  });

                  watchUtils.whenTrue(item, "visible", function (newVal) {
                    layerListFormat(item);                   
                  }); // end watchUtils.whenTrue

        /*
          * Black font color when no aerials checked
          * Yellow font color when basemap is not an aerial
          * @param item LayerList Layeritem
         * @returns true
        */
        function layerListFormat(item) {

          var latest = item.layer.parent.allLayers.filter(function (a) {
            try {
              return a.title === "Latest Aerial";
            } catch (error) {
              console.error("latest: " + error);
            }
          });
          var prior = item.layer.parent.allLayers.filter(function (a) {
            try {
              return a.title === "Prior Year Aerials";
            } catch (error) {
              console.error("prior: " + error);
            }
          });
          var maplayers = item.layer.parent.allLayers.filter(function (a) {
            try {
              return a.title === "Map Layers & Labels";
            } catch (error) {
              console.error("maplayers: " + error);
            }
          });
          if (maplayers.length > 0) {
            var black = maplayers.items[0].sublayers.items.filter(function (a) {
              try {
                return a.id === 36;
              } catch (error) {
                console.error("black: " + error);
              }
            });
            var yellow = maplayers.items[0].sublayers.items.filter(function (a) {
              try {
                return a.id === 7;
              } catch (error) {
                console.error("yellow: " + error);
              }
            });
            if ((latest && latest.length > 0) && (prior && prior.length > 0)) {
              if ((black && black.length > 0) && (yellow && yellow.length > 0)) {

                // debug
                // black[0].title = "black";
                // yellow[0].title = "yellow";

                // show black when both are unchecked
                black[0].visible = !latest.items[0].visible && !prior.items[0].visible;
                // show yellow when one is checked
                yellow[0].visible = latest.items[0].visible || prior.items[0].visible;
                // show black when checked
                black[0].listMode = black[0].visible ? "show" : "hide";
                // show yellow when checked
                yellow[0].listMode = yellow[0].visible ? "show" : "hide";
              }
            }
          }
          return true;
        }
0 Kudos