Work with graphics

Graphics and graphics layers are a flexible and powerful part of the API. Graphics are stored in memory on the client and are only available while the application is running, therefore graphics layers are very well suited to displaying large numbers of objects which are updated in a real time environment. A graphic can represent for example a moving vehicle whose position is changing over time, a polyline boundary around an area that a worker in the field has drawn on the map using mouse clicks, the result of a geocoding operation to represent a found location, and much more.

This topic assumes that you know how to create a graphics layer and add various graphics to it, as detailed in Add graphics and text. Read on for information on how to update graphics, remove graphics, select graphics, and control a graphic's attributes and draw order.

Update and move graphics

Graphic objects are immutable: this means once the graphic is created, its properties are set for the lifetime of the graphic. No 'setters' are present on the Graphic class and instead updating a graphic's properties (attributes, symbol, geometry, draw order) is done via the graphics layer itself.

There are various overloaded updateGraphic methods on the GraphicsLayer class which allow for the following operations on an existing graphic:

  • Updating its geometry (and thus moving or re-shaping the graphic).
  • Replacing it with a new graphic.
  • Updating its draw order.
  • Updating its symbol.
  • Updating its attributes.

In order for any of these operations to be carried out, the unique identification (ID) number of the graphic in the graphics layer must me known. This can be obtained when the graphic is added to the graphics layer, or later on from a query or hit test (finding all graphics within a certain pixel tolerance around a point) on the graphics layer. The following code shows an example of how a point graphic can be moved to a new location by updating its geometry:

// graphic ID stored, e.g. when adding the graphic
int graphicId = myGraphicsLayer.addGraphic(myGraphic);
// ...
 
// create a point for the new location
Point newLocation = new Point(-290122, 7594445);
 
// apply that new point geometry to the graphic
myGraphicsLayer.updateGraphic(graphicId, newLocation);

The above example using updateGraphic(int id, Geometry geometry) is applicable for any geometry type. However, for updating Point geometries, it is recommended you instead use the movePointGraphic method, which is optimized to handle updating points efficiently. This is shown in the code snippet below:

// as before, store graphic ID and create the new Point geometry
int graphicId = myGraphicsLayer.addGraphic(myGraphic);
Point newLocation = new Point(-290122, 7594445);
 
// move the graphic to the new point location
myGraphicsLayer.movePointGraphic(graphicId, newLocation);

Remove graphics

Similar to when updating a graphic, the ID of the graphic is needed in order to remove it from a graphics layer. The exception to this is if you want to remove all the graphics from a graphics layer, in which case you can use the parameter-less method removeAll() on the GraphicsLayer instance.

The code snippet below shows how to remove a graphic from a graphics layer:

// add the graphic to the graphics layer
int graphicId = myGraphicsLayer.addGraphic(pointGraphic);
 
// remove the graphic added above
myGraphicsLayer.removeGraphic(graphicId);

Add attributes to a graphic

Graphics in a graphics layer have the ability to store attributes against each graphic which can be queried and displayed. Attributing graphics is normally performed when the Graphic instance is created. There is an overloaded constructor which allows for the attributes of a graphic to be specified alongside the symbol and geometry.

The following code shows how to create a map of attributes and create a graphic using these attributes:

// create some attributes for the graphic
Map<String,Object> attributes = new HashMap<String, Object>();
attributes.put("Name", "Complex Polygon Example");
attributes.put("Category", "Island");
attributes.put("hasLake", true);
 
// graphic for complex polygon with attributes
Graphic complexPolyGraphic = new Graphic(complexPolygon, fillSymbol, attributes);
 
// add the graphic to your graphics layer
myGraphicsLayer.addGraphic(complexPolyGraphic);

Now that your graphic has attributes associated with it, you may want to display these attributes to your app's users. The API has two built-in ways to display graphic or feature attributes to users: you can use the MapTip class to display attributes when the mouse hovers over a graphic, or you can display attributes in a pop-up when a graphic is clicked. For more information on map tips, please see Show map tips.

The code sample below shows how you would add map tips to the graphic we created above:

// create a MapTip instance
MapTip maptip = new MapTip();
 
// specify the attributes displayed in the map tip
LinkedHashMap<String, String> displayfields = new LinkedHashMap<String, String>();
displayfields.put("Name", "Name: ");
displayfields.put("Category", "Category: ");
displayfields.put("hasLake", "has a lake: ");
maptip.setDisplayFields(displayfields);
 
// associate the maptip with the graphics layer
myGraphicsLayer.setMapTip(maptip);

Select graphics

Selecting graphics involves selecting the graphics in the graphics layer via their unique IDs and controlling how the selected graphics are rendered in the graphics layer.

Select graphics in the layer

You may want to select graphics in your application after some action was taken, for example in response to a mouse click, or after running a query. A graphic can be selected in a graphics layer via its unique graphic ID. The methods supporting selection are members of the GraphicsLayer class. To select features in an ArcGISFeatureLayer, the same methods are used as this class inherits from the GraphicsLayer class. The code snippet below shows how you would select graphics in response to a mouse click, where 'hitGraphicIDs' are the graphics hit by the latest click of the mouse:

for (int id : hitGraphicIDs) {
  if (graphicsLayer.isGraphicSelected(id)) {
    // if graphic is selected in the layer, unselect it
    graphicsLayer.unselect(id);
  } else {
    // otherwise select graphic in the layer
    graphicsLayer.select(id);
  }
}

To obtain the graphics hit by the mouse click, you could use the getGraphicIDs method on the graphics layer. This method takes an x and y coordinate (the clicked point), a pixel tolerance around this coordinate, and optionally a maximum number of results to return, and returns the graphics within this range.

Render the selected graphics

In order to render graphics which are selected in a layer, the API's default behavior is to render the graphics with a colored cyan outline (or highlight) for all types of graphics. When the graphic is then unselected, the colored outline will no longer be shown. An example of what selected graphics look like is below:

Selected graphics, default rendering

You can control the color of this outline for each graphics layer and feature layer and you can choose not to have a colored outline at all. There is one selection color per graphics layer or feature layer and if you change this color on-the-fly, for example when graphics are already selected in the layer, they will start showing with the new selection color once it is set. The code snippet below shows how you would set a yellow colored outline for selected graphics in your graphics layer:

// create a graphics layer
graphicsLayer = new GraphicsLayer();
// set the selection color - default is CYAN color
graphicsLayer.setSelectionColor(Color.YELLOW);
// ...add graphics to the layer
// when selected, graphics will have a yellow outline

Control the drawing order of graphics

If you want a set of graphics to appear on top of another set of graphics, the simplest way to do so is to have two graphics layers and to add them to your map in the correct sequence: the last layer added will appear on top of the other layers. However, in some situations you may want to control which graphics appear on top of others within a graphics layer. For example, you may want graphics selected via a mouse action or a query to appear above non-selected graphics, without having to move them to another graphics layer. The API provides you with methods to accomplish this, through the GraphicsLayer class. Note that because the ArcGISFeatureLayer class inherits from GraphicsLayer, these methods are applicable to these feature layers as well. A geometry's z value (height) does not have an effect on its draw order.

Draw order property

Each graphic in a graphics layer has a draw order property associated with it. The default value of this property is 0 if it is left unspecified when a graphic is created. A graphic with a higher draw order value than another will be drawn above that graphic in the map. If two or more graphics have the same draw order value, the order in which they appear is determined by the order in which they were added to the graphics layer: the last graphic added will appear on top, and so on.

Modifying the drawing order

As graphics cannot be modified once they are created (Graphic instances are immutable), the draw order property can be set at creation time, but from then on updating this property is done via the graphics layer. The GraphicsLayer class gives you fine-grained control over the drawing order of the graphics in a graphics layer. When you add a graphic to a graphics layer, the graphic appears in the layer and the method call returns a unique graphic ID. By storing its graphic ID, you can modify the drawing order of this graphic once it is in the layer. You can:

  • Bring a graphic to the front, to be drawn above all the other graphics in its layer.
  • Move a graphic to the back, to be drawn below all the other graphics in its layer.
  • Update the drawing order of a graphic to a particular value.
  • Update the drawing order of many graphics to one or more particular values.