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.
Solved! Go to Solution.
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);
}
}
});
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.
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));
}
}
Maureen,
I would re-center the map once the contactsFeatureLayer2 is loaded:
contactsFeatureLayer2.on('load', function(){
waterMap.centerAt(new Point(-93.8, 46.3));
});
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.
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.
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!
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);
}
}
});
Thanks for the detailed help with resizing. This code is working for me consistently as well.