Javascript api, info bubbles for stacked graphics

3596
6
Jump to solution
07-16-2014 09:44 AM
alexlambson
New Contributor II

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.

0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor

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.

  • No template for GraphicsLayers
  • Listen for click event of map
  • Get graphics from multiple graphicslayers that intersect click point
  • Dynamically generate the content and add templates to graphics
  • Use map.infoWindow methods to add features to Popup
  • Display Popup

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

Feature layer with popup | ArcGIS API for JavaScript

View solution in original post

6 Replies
ReneRubalcava
Frequent Contributor

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

alexlambson
New Contributor II

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.

0 Kudos
ReneRubalcava
Frequent Contributor

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?

alexlambson
New Contributor II

//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();

0 Kudos
ReneRubalcava
Frequent Contributor

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.

  • No template for GraphicsLayers
  • Listen for click event of map
  • Get graphics from multiple graphicslayers that intersect click point
  • Dynamically generate the content and add templates to graphics
  • Use map.infoWindow methods to add features to Popup
  • Display Popup

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

Feature layer with popup | ArcGIS API for JavaScript

alexlambson
New Contributor II

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

    }

0 Kudos