Background or highlight on textSymbol

15923
29
01-19-2011 05:50 AM
JasonMiller1
New Contributor
I have a map set up puts dots on the map, and draws lines connecting the dots to create a route.  Each dot has a textSymbol next to it that I'm using to label each dot for the user.  The problem is that with all the stuff in the background, it can be hard to read those labels sometimes. 

I'm wondering if there's any way to put a background behind the textSymbol to help it stand out.  I know about infoWindows, but I'm already using those when you click on the dot to give you more information. 

Here's a snippet from my code that runs when it's looping through the route and putting the dots on the map.  This is the portion that adds the labels.

...
font = new esri.symbol.Font("10pt", esri.symbol.Font.STYLE_NORMAL,
    esri.symbol.Font.VARIANT_NORMAL,esri.symbol.Font.WEIGHT_NORMAL,"Verdana");
...
var textSymbol =  new esri.symbol.TextSymbol(feature.attributes["LABEL"]).setColor(new dojo.Color([255, 0, 0])).
 setOffset(30, 0).setFont(font).setKerning(true);

var point = new esri.geometry.Point(feature.attributes["NNLL_LONG_DEC"], feature.attributes["NNLL_LAT_DEC"], map.spatialReference);

map.graphics.add(new esri.Graphic(point, textSymbol));
...


Any ideas?
0 Kudos
29 Replies
TracySchloss
Frequent Contributor

This is how it looks for me:

textShadow_IE11.png

0 Kudos
KenBuja
MVP Esteemed Contributor

I'm seeing this also on IE 11.0.9600.18015

0 Kudos
TracySchloss
Frequent Contributor

In the cited link  for adding CSS compatible text shadows, the example for IE doesn't display a shadow in either IE or Chrome.  It's from 2005 and mentions IE 5 and 6.  At least it confirms that IE in general is picky about textshadows.

0 Kudos
KellyHutchins
Esri Frequent Contributor

Based on a few google searches it seems like there are issues with text-shadow support on Svg for IE. Can't find anything definitive to link here. Tried a few workarounds but couldn't get anything to show the text shadow for IE11 but I'm not a css expert so perhaps someone else has struggled with this in IE and will have a solution.

0 Kudos
TracySchloss
Frequent Contributor

Too bad, but at least you've verified there are still issues with text-shadows in IE 11.  I wondered because I generated a text shadow on plain HTML text elements in my project, it just didn't work with text symbols.

0 Kudos
AndyMorgan1
New Contributor III

Similar to Rahul Metangale's post above, I found SVG rectangles to be the best approach.  This works well to remove & re-create the label background each time the map is redrawn (after pan or zoom).

function turnOnLabels() {
 var labelLayerNode = labelLyr.getNode();
  
 if (!labelLayerNode || labelLayerNode === null) {
  return;
 }
 var textLabels = query("text", labelLayerNode);
 array.forEach(textLabels, function (label) {
  var txtContent = label.textContent;
  label.textContent = txtContent.replace("null", "");
  var lBox = label.getBBox();
  label.innerHTML = label.textContent
  var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  rect.setAttribute("x", lBox.x);
  rect.setAttribute("y", lBox.y);
  rect.setAttribute("width", lBox.width + 1);  //added a little margin
  rect.setAttribute("height", lBox.height - 2);  //trimmed down margin
  rect.setAttribute("fill", "rgba(255,255,255,0.9)");  //opacity of 0.9 can be adjusted
  labelLayerNode.insertBefore(rect, label);
 });
}

function turnOffLabels() {
 var labelLayerNode = labelLyr.getNode();
 if (!labelLayerNode) { return; }
 var elements = labelLayerNode.querySelectorAll("rect");
 for (var i = 0; i < elements.length; ++i) {
  var elem = elements;
  labelLayerNode.removeChild(elem);
 }
}

app.map.on('update-start', function () {
 turnOffLabels();
});

app.map.on('update-end', function () {
 turnOnLabels();
});

Edit:  It works well enough for visual display on the screen, but I discovered these svg rectangles are lost when I export to PDF using PrintTask (esri/tasks/PrintTask).  I am going to contact ESRI about this, but I would be interested in knowing if there is any workaround.  Here is a JSFiddle example to illustrate the problem:  http://jsfiddle.net/r2nnrL3t

Edit #2:  I confirmed with ESRI support services this is a known issue:

The bug id is  NIM090851 : Export Web Map Task cannot print a map using SVG symbol types in JavaScript API 3.4. The status of the bug is set to "Tech review Complete" which means that the bug has been reviewed by the Technical Leads and now it's being reviewed by the Product Engineers, and then it will be assigned to the development team for a fix.

Therefore, my solution is to use LabelClass with halo color and halo size properties (Brendan Madden's solution below). It is compatible with PrintTask and gets the job done to provide a background for contrast.

0 Kudos
BrendanMadden1
New Contributor

I know this is an old thread, but I found a solution that doesn't require hacky workarounds and works in all browsers, and I thought I'd share for those interested.  Just a note that as far as I can tell, this method only works with dynamic map service layers where the service has 'Supports dynamic layers' set to true. 

Using Chrome's dev console, I looked at the response from an esriRequest on a layer that had the halo effect applied to its labels when published from ArcGIS Desktop.  Those labels rendered correctly in my app, so I figured there had to be a way to accomplish it programatically as well.

Here was the relevant part of the returned response:

json.PNG

Notice the symbol 'type' is 'esriTS', not 'textsymbol', and there are properties for 'haloColor' and 'haloSize.'  I ran with that in my code and rather than use the standard TextSymbol for my label's symbol, I created my own symbol instead and made the 'type' be 'esriTS', and added the properties for 'haloColor' and 'haloSize.'

var labelClass = new LabelClass({

   labelExpression: '[CULVERTID]',

   labelPlacement: 'above-along',

   symbol: {

                        'type': 'esriTS',

                        'color': [0,0,0,255],

                        'haloColor': [255,255,255,255],

                        'haloSize': 2,

                        'font': {

                            'family': 'Arial',

                            'size': 12,

                            'weight': 'bold'

                        }

                    }

  });

This worked for me.  Before and after label change shown below.

Before: (default labelling from the map service)

before.PNG

After (programatically changed labels):

after.PNG

Here's a fiddle as well (this is a modified fork of an existing fiddle: Edit fiddle - JSFiddle  )

AndyMorgan1
New Contributor III

Brilliant.  Thank you for sharing, Brendan!   I replaced my code to use the LabelClass with halos.  It now includes labels and a background when exporting to PDF using PrintTask, unlike LabelLayer class method (per my previous post above).   Works for IE 10 and 11.0.96.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

FYI: JS API 3.15 now has halo support

  • ENH-000088309: Added support for TextSymbol halo.
BrendanMadden1
New Contributor

Thanks for pointing this out Robert.  I'm glad it's officially supported now.

0 Kudos