Select to view content in your preferred language

Change Map Service Label Color on Event

1847
3
11-14-2016 01:41 PM
LloydBronn
Occasional Contributor II

I have a dynamic map service with labels. I'm wondering how to change the color of labels when certain basemaps are chosen from the basemap gallery. I'm playing around with the label class, trying to set the label text from the default black to white when the dark gray canvas basemap is chosen. I've tried to use labelClass.where and it's not working, probably because the basemap is not a field in the layer (according to LabelClass | API Reference | ArcGIS API for JavaScript 3.18 ).

map = new Map("map", {
 basemap: "gray",
 center: [0, 40],
 zoom: 2,
 maxZoom: 12,
 minZoom: 2,
 infoWindow: popup,
 showLabels : true 
 });‍‍‍‍‍‍‍‍‍

var labelClass = new LabelClass();
 labelClass.symbol = new TextSymbol({
 font: new Font("12", Font.STYLE_NORMAL, Font.VARIANT_NORMAL, "Arial"),
 color: new Color("#FFFFFF")
 });

labelClass.where = basemapGallery.basemaps('basemap_7');‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I've also tried this:

basemapGallery.on("selection-change",function(){
 var tp = dijit.byId("TitlePane");
 var layer = map.getLayer(refLayerId); 
 if(basemapGallery.basemaps === 'basemap_7'){
 labelClass = true;
 }
 if(layer && tp != null){
 map.removeLayer(layer);
 tp.toggle();
 }
 else{tp.toggle();}
 });
‍‍‍‍‍‍‍‍‍‍‍‍

0 Kudos
3 Replies
JordanKing3
New Contributor III

Hey Lloyd,

There are a few things here. Firstly the LabelClass needs to be applied to a layer in your map, which will then render the layers labels in the way the LabelClass has specified. This snippet is taken directly from the LabelClass API reference in your link.

//make sure the Map's showLabels option is set to true   
var map = new Map("map", 
  {     
    basemap: "streets",     
    center:[-80, 30],     
    zoom: 5,     
    showLabels : true   
  });   

//create featurelayer   
var flayer = new FeatureLayer(url, 
  {     
    outFields: ["*"] //make sure field to label is specified here in outFields   
  });   

//create a text symbol and renderer to define the style of labels    
var labelSymbol = new TextSymbol();   
var json = {   
    "labelExpressionInfo": {"value": "{LocalTime}"},   
    "useCodedValues": false,   
    "labelPlacement":"above-right",   
    "fieldInfos": [{fieldName: "LocalTime",format: { "dateFormat": "shortDate"}}]   
};  

//create instance of LabelClass   
var lc = new LabelClass(json);   
lc.symbol = labelSymbol; // symbol also can be set in LabelClass' json   
flayer.setLabelingInfo([ lc ]);

This is creating Feature Layer and then a TextSymbol. The TextSymbol is then applied as the symbol for the LabelClass and then the LabelClass is applied to the layer. I'm not sure from your example if you're doing this or not. Also, the labelClass.where is a where clause which is applied to the features in the layer as far as I'm aware, say for example you only want to show labels for features with an attribute > some value. It has nothing to do with the basemap.

Secondly, to have the LabelClass change on basemap switch, a simple way to do this would be to define two seperate LabelClass definitions and then apply the correct one to the layer when needed. Or you can just use two TextSymbol definitions to change the colour of the label and apply that to the same LabelClass. Here's an example:

var labelSymbol1 = new TextSymbol(); 
var labelSymbol2 = new TextSymbol(); 
labelSymbol2.setColor(new Color([128,0,0])).setAlign(Font.ALIGN_START).setAngle(45).setFont(      
    new Font("12pt").setWeight(Font.WEIGHT_BOLD));

Here we now have two TextSymbols, the second one has a different colour applied to it. Now, when the basemap switches, we can apply the correct Text to the labels by updating the layers label info:

basemapToggle.on('toggle', function(sel) {     
  if (sel.currentBasemap == 'hybrid') { 
    symbol = labelSymbol2;         
    flayer.setLabelingInfo([ lc ]);     
  } else {         
    lc.symbol = labelSymbol1;         
    flayer.setLabelingInfo([ lc ]);     
  }  
});

Hopefully this is what you're after. Putting all this together should result in you being able to change your labels based on the basemap changing.

LloydBronn
Occasional Contributor II

Thanks! One issue I've had with the examples are that they all work from a feature layer with outfields. I'm using a dynamic map service layer with an identify task for all the different layers. Will that make a difference?

0 Kudos
JordanKing3
New Contributor III

Hey Lloyd,

Hmm, good question. I've never actually done that myself, used a Dynamic Map Service layer and manually set the labeling, however, having a look through the API, there is this property on the ArcGISDynamicMapServiceLayer:

layerDrawingOptions

If you have a look at the LayerDrawingOptions class, you'll see that it also has a labelingInfo parameter, which is of type LabelClass. Therefore, I'm wondering if you would be able to apply the LabelClass object you were creating to that. In the LabelClass page. there is a bit about the labelExpression and labelExpressionInfo which says you must use labelExpression if you're using an ArcGISDynamicMapServiceLayer. So from this, I'm guessing its possible!

I had a bit of a play, but haven't been able to get the labels to appear on a Map Service layer yet.

Hopefully someone else might be able to help out! Otherwise, I'll see if I can look at it again sometime.

0 Kudos