ArcGIS Blog

Mapping

ArcGIS Maps SDK for JavaScript

Find graphics under a mouse click with the ArcGIS API for JavaScript

By Kelly Hutchins

Dojo filter exampleMapping applications built with the ArcGIS API for
JavaScript
 commonly allow users to click or hover over a map and get information about all the features under the current mouse location.
To add this functionality to your application you can listen for the graphics layer’s onClick event, however if graphics are stacked on
top of each other, only the top one fires an event. So how do you determine how many graphics are under the point?

One approach is to do the following:

  1. Listen for a click event, perhaps onMouseDown or onClick.
  2. Define a search radius by constructing a new extent around the input point.
  3. Use dojo.Filter to create a new array that contains only the features that are within the search radius.

Listen for onClick event

First, we use dojo.connect to listen for the onClick event. The code snippet below
connects an event handler to the map’s graphics layer that fires whenever a user clicks a graphic.

dojo.connect(map.graphics,"onClick",identifyFeatures);

The event argument provides access to the screen point, map point, and graphic. The map point is the location, in map units,
under the mouse cursor. In the handler function identifyFeatures, call a function that builds a search radius around the input mouse location and
returns the new extent.We’ll examine how to build the pointToExtent function in the next step.

   function identifyFeatures(evt){
    var extentGeom = pointToExtent(map,evt.mapPoint,10);
   }

Construct an extent around the input point

In this step, we’ll construct an extent
around the input map point using the following function. This function uses an input point and tolerance to calculate the extent.

function pointToExtent(map, point, toleranceInPixel) {
  //calculate map coords represented per pixel
  var pixelWidth = map.extent.getWidth() / map.width;
  //calculate map coords for tolerance in pixel
  var toleraceInMapCoords = toleranceInPixel * pixelWidth;
  //calculate & return computed extent
  return new esri.geometry.Extent( point.x - toleraceInMapCoords,
               point.y - toleraceInMapCoords,
               point.x + toleraceInMapCoords,
               point.y + toleraceInMapCoords,
               map.spatialReference );
}

Filter the graphics collection using dojo.filter and display the results

Dojo.filter takes an input array and a filtering function
and returns a new array that contains only the items that met the filter requirement.

Let’s look at how to use dojo.Filter to loop through the graphics in our graphics layer and test each graphic against a condition.
In this case, we use extent.contains to perform a spatial query to determine which graphics are within the extent. If a graphic is within the extent, the
function returns true and the graphic is included in the filteredGraphics output array.

  var filteredGraphics = dojo.filter(map.graphics.graphics, function(graphic) {
    return extentGeom.contains(graphic.geometry);
  })

Now we have an array that contains only graphics located within the specified tolerance. We can use this array to build a table containing
one row for each graphic under the mouse location. In the snippet below, we construct a table, then use dojo.forEach to
loop through the filteredGraphics array and add a row that displays the city name and population. Finally we build an info window to display the results.

  var content = "";
  content = "<i>Total Features: " + filteredGraphics.length + "</i>";
  content += "<table><tr><th>City</th><th>Population</th></tr>";

  //Build a table containing a row for each feature found
  dojo.forEach(filteredGraphics,function(row){
    content += ""
      + row.attributes['CITY_NAME'] +
      "</td><td>" + row.attributes['POP1990'] +
      "</td></tr>";
  })
  content += "</table>";

 //display the results in an infow window
 map.infoWindow.setContent(content);
 map.infoWindow.setTitle("Identify Results");
 map.infoWindow.show(evt.screenPoint,map.getInfoWindowAnchor(evt.screenPoint));

Click here to view a live sample that uses dojo.filter to display information about all the graphics under the mouse point.

Contributed by Kelly Hutchins of the ArcGIS API for JavaScript development team.

Share this article