Multiple Maps in Tabs: label layer bug in dojo?

2146
8
Jump to solution
08-30-2016 11:47 AM
MaureenMcFarlane
New Contributor II

I am creating a simple two tabbed app that displays one map on each tab. Each map will have slightly different data.

A strange issue is happening on the second tab. The layer that draws the labels on the map is confined to a small space in the upper left-hand corner of the map. Labels only appear for features overlapping this very small corner. Furthermore, the map doesn't load centered.

Take a look here (a simplified version of the app): Air and Water Data 

I've dug around the DOM tree and found a discrepancy between the two tabs. There is a  <filter> tag nested within an <svg> tag. It has "width" and "height" attributes that differ between the two tabs. When I manually correct the attributes in dev tools, this corrects it. I've tried multiple ways of then updating the javascript to change this on the fly, and it's really, really buggy and inconsistent.

I've also tried setting the second tab to be open instead of the first, and the problem is then reversed between the tabs. This makes me think it's a dojo bug of some sort connected to the tab container or the content pane. 

Here is the pertinent html:

<body class="claro">
   <div data-dojo-type="dijit/layout/TabContainer" style="width: 100%; height: 100%; margin: 0;">
      <div id="airmap" data-dojo-type="dijit/layout/ContentPane" title="Air Data"></div>
      <div id="watermap" data-dojo-type="dijit/layout/ContentPane" title="Water Data"></div>
   </div>
</body>

Here is the javascript:

require([
"dojo/dom",
"dojo/dom-construct",
"dojo/dom-class",
"esri/domUtils",
"esri/map",
"esri/basemaps",
"esri/arcgis/utils",
"esri/layers/FeatureLayer",
"dojo/parser",
"dijit/layout/TabContainer",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function (dom, domConstruct, domClass, domUtils, Map, esriBasemaps, arcgisUtils, FeatureLayer, parser){
parser.parse();

esriConfig.defaults.io.proxyUrl = 'https://www.barr.com/maps/DotNet/proxy.ashx';
esriConfig.defaults.io.alwaysUseProxy = true;
esriConfig.defaults.io.timeout = 15000000;

//script for tab #1: Air Data map
var airMap;


airMap = new Map("airmap", {
   basemap: 'dark-gray',
   center: [-93.8, 46.3],
   zoom: 7,
   showLabels: true
});

var contactsFeatureLayer = new    FeatureLayer("https://maps2013.barr.com/maps/rest/services/01_Testing/Tabbed_Maps_Test_Map_Service/MapServer/0 ",{
      mode: FeatureLayer.MODE_ONDEMAND,
      outFields: ["*"]
});

airMap.addLayer(contactsFeatureLayer);

//script for tab #2: Water Data map
var waterMap;

waterMap = new Map("watermap", {
   basemap: 'dark-gray',
   center: [-93.8, 46.3],
   zoom: 7,
   showLabels: true
});


var contactsFeatureLayer = new    FeatureLayer("https://maps2013.barr.com/maps/rest/services/01_Testing/Tabbed_Maps_Test_Map_Service/MapServer/0 ",{
      mode: FeatureLayer.MODE_ONDEMAND,
      outFields: ["*"]
});

waterMap.addLayer(contactsFeatureLayer);


});

This has been maddening. I'd appreciate any help.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Maureen,

   Here is your code that I modified and it is working for me:

require([
    "dojo/dom",
    "dojo/dom-construct",
    "dojo/dom-class",
    "esri/domUtils",
    "esri/map",
    "esri/basemaps",
    "esri/arcgis/utils",
    "esri/layers/FeatureLayer",
    "esri/geometry/Point",
    "dojo/parser",
    "dojo/on",
    "dijit/layout/TabContainer",
    "dijit/layout/ContentPane",
    "dojo/domReady!"
], function(dom, domConstruct, domClass, domUtils, Map, esriBasemaps, arcgisUtils, FeatureLayer, Point, parser, on) {
    parser.parse();

    esriConfig.defaults.io.proxyUrl = '/proxy.ashx';
    esriConfig.defaults.io.alwaysUseProxy = true;
    esriConfig.defaults.io.timeout = 15000000;

    //script for tab #1: Air Data map
    var airMap;
    airMap = new Map("airmap", {
        basemap: 'dark-gray',
        center: [-93.8, 46.3],
        zoom: 7,
        showLabels: true
    });

    var contactsFeatureLayer = new FeatureLayer("https://maps2013.barr.com/maps/rest/services/02_Barr/Tabbed_Maps_Test_Map_Service/MapServer/0", {
        mode: FeatureLayer.MODE_ONDEMAND,
        outFields: ["*"]
    });

    airMap.addLayer(contactsFeatureLayer);

    //script for tab #2: Water Data map
    var waterMap;

    var contactsFeatureLayer2 = new FeatureLayer("https://maps2013.barr.com/maps/rest/services/02_Barr/Tabbed_Maps_Test_Map_Service/MapServer/0", {
        mode: FeatureLayer.MODE_ONDEMAND,
        outFields: ["*"]
    });

    //initiate Water Data on tab change
    var waterDiv = dijit.byId("watermap");
    on(waterDiv, 'show', initiateWaterMap);

    function initiateWaterMap() {
        console.log("I see the water div");
        if (waterMap === undefined) {
            waterMap = new Map("watermap", {
                basemap: 'dark-gray',
                center: [-93.8, 46.3], //had to adjust center from [-93.8, 46.3] just to get it in the ballpark. Weird, weird glitch..
                zoom: 7,
                showLabels: true
            });
            waterMap.on('load', function() {
                waterMap.resize(true);
                waterMap.centerAt(new Point(-93.8, 46.3));
            });
            waterMap.addLayer(contactsFeatureLayer2);
        }
    }
});

View solution in original post

8 Replies
thejuskambi
Occasional Contributor III

By default the map initializes with a height and width of 400px, it then get the page/container size and resizes itself. In case the map div container is not displayed (has no width & height), the size is not reset.  In your case the contentpane for watermap is not displayed at first so the map is initialized at default extent. And for unknown reason, the label layer is not updated when the map autoresizes, when the tab is visible.

Since, your service are secured I am not able to use them in jsbin, to debug.

I would suggest you to try to resize the map when the tab changes. If that does not work, then you would have to initialize you watermap the first time the tab is clicked.

MaureenMcFarlane
New Contributor II

Thank you, thejus kambi . It was really helpful to know that the default map size is 400px and the reason for the strange behavior.

I ended up initalizing the watermap when the tab is clicked, and that solved the labeling problem. I'm now trying to solve the problem of the map not re-centering. The first click of the watermap tab does not recenter it, but clicking it a SECOND time recenters it.

Here is the code I added. I'm testing out centering the map in two different places in the code. I've also switched the service to be publicly accessible. If anyone is able to help me out further, I'd really appreciate it:

  var tabWidget = dijit.byId("dijit_layout_TabContainer_0_tablist_watermap");
  var dnode = tabWidget.domNode;
  dnode.onclick = function(){
      console.log("you clicked it!");
      if(!waterMap){
        waterMap = new Map("watermap", {
          basemap: 'dark-gray',
          center: [-93.8, 46.3],
          zoom: 7,
          showLabels: true
        });

        waterMap.centerAt(new Point(-93.8, 46.3));
        waterMap.addLayer(contactsFeatureLayer2);
      }

      if(waterMap) {
        waterMap.centerAt(new Point(-93.8, 46.3));
      }
    }

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Maureen,

   I would re-center the map once the contactsFeatureLayer2 is loaded:

contactsFeatureLayer2.on('load', function(){
    waterMap.centerAt(new Point(-93.8, 46.3));
});‍‍‍
0 Kudos
MaureenMcFarlane
New Contributor II

Thanks, Robert Scheitlin, GISP‌. Unfortunately, it didn't work. Interestingly enough, when I changed the coordinates for the center attribute directly when the map is initialized, it did initiate the map in a different location. It's as if the map "calibration" is off somehow on this second tab, even though I was using the exact same data and attributes as the first tab. Now I've changed the center from [-93.8, 46.3] to [-98.8, 48.3]. It's really sloppy, but now it's closer to where it needs to be for now.

If anyone has any idea about how a map's "center" gets out of whack, please chime in. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Maureen,

   You need to call map.resize(true); then:

Map | API Reference | ArcGIS API for JavaScript 3.17 | resize 

Resizes the map DIV. This method should be used after the map DIV has been resized.
0 Kudos
MaureenMcFarlane
New Contributor II

I appreciate the suggestions, rscheitlin. I've tried a number of ways of incorporating resize, and it's not working out. I know I'm not understanding the logic behind resize(true) and where it fits in re-centering the map. I am able to trigger console logs using map.on("resize", .....), but I'm unable to trigger a "centerAt" using that event. It throws errors of "unable to draw graphic".

It definitely is frustrating when something as simple as centering a map is inexplicably complicated. Thanks again for lending thoughts!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Maureen,

   Here is your code that I modified and it is working for me:

require([
    "dojo/dom",
    "dojo/dom-construct",
    "dojo/dom-class",
    "esri/domUtils",
    "esri/map",
    "esri/basemaps",
    "esri/arcgis/utils",
    "esri/layers/FeatureLayer",
    "esri/geometry/Point",
    "dojo/parser",
    "dojo/on",
    "dijit/layout/TabContainer",
    "dijit/layout/ContentPane",
    "dojo/domReady!"
], function(dom, domConstruct, domClass, domUtils, Map, esriBasemaps, arcgisUtils, FeatureLayer, Point, parser, on) {
    parser.parse();

    esriConfig.defaults.io.proxyUrl = '/proxy.ashx';
    esriConfig.defaults.io.alwaysUseProxy = true;
    esriConfig.defaults.io.timeout = 15000000;

    //script for tab #1: Air Data map
    var airMap;
    airMap = new Map("airmap", {
        basemap: 'dark-gray',
        center: [-93.8, 46.3],
        zoom: 7,
        showLabels: true
    });

    var contactsFeatureLayer = new FeatureLayer("https://maps2013.barr.com/maps/rest/services/02_Barr/Tabbed_Maps_Test_Map_Service/MapServer/0", {
        mode: FeatureLayer.MODE_ONDEMAND,
        outFields: ["*"]
    });

    airMap.addLayer(contactsFeatureLayer);

    //script for tab #2: Water Data map
    var waterMap;

    var contactsFeatureLayer2 = new FeatureLayer("https://maps2013.barr.com/maps/rest/services/02_Barr/Tabbed_Maps_Test_Map_Service/MapServer/0", {
        mode: FeatureLayer.MODE_ONDEMAND,
        outFields: ["*"]
    });

    //initiate Water Data on tab change
    var waterDiv = dijit.byId("watermap");
    on(waterDiv, 'show', initiateWaterMap);

    function initiateWaterMap() {
        console.log("I see the water div");
        if (waterMap === undefined) {
            waterMap = new Map("watermap", {
                basemap: 'dark-gray',
                center: [-93.8, 46.3], //had to adjust center from [-93.8, 46.3] just to get it in the ballpark. Weird, weird glitch..
                zoom: 7,
                showLabels: true
            });
            waterMap.on('load', function() {
                waterMap.resize(true);
                waterMap.centerAt(new Point(-93.8, 46.3));
            });
            waterMap.addLayer(contactsFeatureLayer2);
        }
    }
});
MaureenMcFarlane
New Contributor II

Thanks for the detailed help with resizing. This code is working for me consistently as well.

0 Kudos