Hey guys.
Basically, what I need to do is have the left/right arrows of an infobubble cycle between two graphics that are at the same coordinates. I tried putting them on seperate graphic layers, but it did not give me the arrow.
Logic
See if two markers have the same coordinates -> link their info bubbles if they do.
Here is how I am separating the layers.
point = new esri.geometry.Point(item.lon, item.lat); coordinateCheck = item.lat; graphic = new esri.Graphic(point, symbol); graphic.setAttributes({'title': checkbox, 'desc': content}); if (usedCoordinates.indexOf(coordinateCheck) > -1){ graphicsLayer2.add(graphic); console.log('added to layer 2'); } else { graphicsLayer.add(graphic); usedCoordinates.push(coordinateCheck); console.log('added to layer 1 ' + usedCoordinates); }
Will this method work? How do I get the stacked markers to link info bubbles.
Solved! Go to Solution.
I'm almost out the door, so can't test at the moment, but if you remove the template you set in the constructors for your GraphicsLayers and use the map.infoWindow methods to manually populate the infoWindow, I think you'll get the desired behavior. The infoWindow templates on the graphicslayer would override the manual method and since they are not linked they won't do the toggle via next feature you are looking for. It will probably just the Popup for the topmost feature of the overlapping layers.
Depending on how much control you need over when the popup is shown and you really need to keep them in separate layers you could adjust the workflow slightly.
Unless the graphics are on the same layer, I don't think you could automate it much easier.
Here is a sample that uses the map.infoWindow.setFeatures method similar to how I was trying to describe it
You can add the features to the maps infoWindow which is an instance of the Popup
popup-amd | API Reference | ArcGIS API for JavaScript
So you could take your graphics and do something like
map.infoWindow.setFeatures([graphic1, graphic2]); // pass it an array of your graphics
map.infoWindow.show(e.mapPoint); // assuming this occurs after a maps click event
Be sure to use map.infoWindow.clearFeatures() every time you need to reset it.
Here is a section from docs on working with Popups
Info windows and graphics | Guide | ArcGIS API for JavaScript
I have the graphics displaying their popups, but I cannot get graphics to cycle between each other.
I should probably mention that all of the markers are generated client-side from JSON data from our database.
If you use the map.infoWindow.setFeatures([n1,n2,...]) that should cycle the graphics in the popup. Can you post the code you're using to display the popups?
//map is pulled from a webmap id
var graphicsLayer = new esri.layers.GraphicsLayer({
infoTemplate: template,
outFields: ["*"]
});
var graphicsLayer2 = new esri.layers.GraphicsLayer({
infoTemplate: template,
outFields: ["*"]
}); //create an artboard for our beautiful markers to rest on
map.addLayers([graphicsLayer, graphicsLayer2]);
function getIdResults(ids, sortOrder, sortby) {
map.resize(true);
map.hideZoomSlider();
var resData = {'T_IDTrans':ids, 'sortbyfield':sortby, 'sortbylist':sortOrder};
//reset the map position for seacrh
//this is done because the window resizes and causes the map to be left of stg.
var origin = esri.geometry.Point(-113.5581, 37.0953);
map.centerAndZoom(origin, 12);
graphicsLayer2.clear() //clean up
graphicsLayer.clear();//give us a clean map
usedCoordinates = []; //initialize and/or clear the coordinates used
$.ajax({
//Grab all the json data. Removed this because it is a lot of code
var point;
var symbol = new PictureMarkerSymbol(
{
//symbol info
});
var graphic; //initialize graphic variable. This is what will be added to the graphic layer
var checkbox = //corresponds to a toolbar check box
'<input id="p_check_m_'
+ item.mls
+ //more gibberish to make the checkbox
var content = '<div><b>' //the body of the info window
+ item.SaleLease
+ '</b></div><div>Listing: '
+ item.T_ListBrokerage
+ ' / '
+ item.T_ListAgent
+ buying
+ '</div>'
+ '<div>List Date:' + item.T_ListDate + '</div>'
+ '<div>List Price:' + item.price + '</div>'
+ '<div>' + addCommas(area) + '</div>';
point = new esri.geometry.Point(item.lon, item.lat); //point for graphic
coordinateCheck = item.lat;
//I just use latitude since I do not know how to check an array of arrays
graphic = new esri.Graphic(point, symbol); //create the graphic
graphic.setAttributes({'title': checkbox, 'desc': content}); //set its attributes
if (usedCoordinates.indexOf(coordinateCheck) > -1){
//check to see if item.lat has already been used
graphicsLayer2.add(graphic);
console.log('added to layer 2');
} else {
graphicsLayer.add(graphic);
usedCoordinates.push(coordinateCheck);
console.log('added to layer 1 ' + usedCoordinates);
}
});
/*dojo.forEach(graphicsLayer.graphics, function(relate){
var u;
});*/
updateContainer();
I'm almost out the door, so can't test at the moment, but if you remove the template you set in the constructors for your GraphicsLayers and use the map.infoWindow methods to manually populate the infoWindow, I think you'll get the desired behavior. The infoWindow templates on the graphicslayer would override the manual method and since they are not linked they won't do the toggle via next feature you are looking for. It will probably just the Popup for the topmost feature of the overlapping layers.
Depending on how much control you need over when the popup is shown and you really need to keep them in separate layers you could adjust the workflow slightly.
Unless the graphics are on the same layer, I don't think you could automate it much easier.
Here is a sample that uses the map.infoWindow.setFeatures method similar to how I was trying to describe it
Thanks for your help so far. I added a new function, but it does not work. If you get the time later, then perhaps you can tell me why it does not work. Should I just disable the template?
//replace the if/else from the first post
point = new esri.geometry.Point(item.lon, item.lat);
graphic = new esri.Graphic(point, symbol);
graphic.setAttributes({'title': checkbox, 'desc': content});
coordinateCheck = [item.lon, item.lat, graphic];
graphicsLayer.add(graphic);
if(checkCoordinatesAndLink(coordinateCheck, usedCoordinates)){
usedCoordinates.push(coordinateCheck);
}
//function somewhere else
function checkCoordinatesAndLink(graphicIn, listOfUsedCoordinates){
var array = listOfUsedCoordinates; //easier to type
var graphicLon = graphicIn[0]; //get longitude of the graphic we are checking
var graphicLat = graphicIn[1];
console.log(graphicLon + ' ' + graphicLat + ' ' + array);
for(i=0; i < array.length; i++){ //loop through already placed graphics
usedLon = array[0]; //get the longitude of already placed graphics
usedLat = array[1];
console.log("looping " + i);
if(usedLon == graphicLon && usedLat == graphicLat){
map.infoWindow.setFeatures([graphicIn[2], array[2]]);
console.log('linked');
return false; //do not add this coordinate to the list of used ones
}
}
return true; //add this praphic to the list of used ones
}