Graphics and MapTips


In this topic


Graphic features

The Web Application Developer Framework (ADF) JavaScript library contains the components to create, manage, and render graphics on the client. Client-tier graphics are called graphic features and consist of geometry, attributes, and symbology. Graphic features are displayed in an ADF Map control, so a Map control must be present on the page to view them. Since graphic features persist as elements in a browser, you can interact with them using standard client actions, such as using the mouse cursor to hover over or click an element. The ADF MapTips control interactively displays attributes of a graphic feature by handling mouse actions on the feature.
The following diagram illustrates the relationships among graphic features and their components:
The GraphicFeatureBase component provides the properties and event handlers that can be applied to individual graphic features and groups of graphic features. The properties enable you to set the default symbol, selectedSymbol, and highlightSymbol. The highlightSymbol property is frequently used to identify the graphic feature over which the mouse cursor is hovering. MapTips can be applied to one or more graphic features using the GraphicFeatureBase.mapTips property. In addition, a set of mouse events are available to handle click, mouse over, mouse out, and mouse move events.
The GraphicFeature component extends GraphicFeatureBase to represent one graphic feature using geometry and attributes. Consider GraphicFeature to be a spatially enabled row of data. It can be explicitly highlighted and selected using the Highlight and Selected symbols defined in the base component (GraphicFeatureBase).
The GraphicFeatureGroup component extends GraphicFeatureBase to represent a group of graphic features. Consider GraphicFeatureGroup a spatially enabled table (feature class) with one or more graphic features. GraphicFeatureGroup enables you to apply common properties and behaviors across all graphic features it contains. As a result, you can define one symbol for a GraphicFeatureGroup and have it apply to all graphic features it contains. You can also define the opacity and visibility of all graphic features in the group.

Client-side graphics

The following techniques are used to work with client-side graphics in the ADF (ESRI.ADF.Graphics) using JavaScript:
  • Create and manage graphics in the Web tier and render them on the client
  • Create, manage, and render graphics on the client
The first option involves using Web ADF .NET graphics resources and layers to store and manage graphic content, then rendering graphics on the client using ADF JavaScript components. Graphics are available via .NET in the Web tier and JavaScript on the client. The second option consists of creating, managing, and rendering graphics on the client using ADF JavaScript components. Graphics are only available on the client (in browser memory).
This topic covers second option. Subcomponents of GraphicFeatures and GraphicFeatureGroups are covered—such as geometry and symbols—and optional components, such as MapTips, are presented.

Geometry

All graphic features use geometry to define their spatial component and a symbol to define how the geometry is displayed on the map. The ADF JavaScript library includes a set of simple geometry types to store and work with spatial entities on the client (ESRI.ADF.Geometries) as shown in the following diagram:
Geometry can be created explicitly or via interaction with the Map control. For example, to create a new point, see the following code:
[JavaScript]
 < script type = "text/javascript" > var newGeometry = new ESRI.ADF.Geometries.Point
     ( - 120, 45);
 <  / script >
Both polylines and polygons consist of parts (paths and rings, respectively). Each part is created and accessed as a CoordinateCollection component. For example, to create a polygon with a single ring, see the following JavaScript code:
[JavaScript]
 < script type = "text/javascript" > var ringString = "-120,45 -110,34 -115,42";
var pointArray = ringString.split(' ');

var newRing = new ESRI.ADF.Geometries.CoordinateCollection();

for (var i = 0; i < pointArray.length; i++){
    newRing.add(ESRI.ADF.Geometries.Point.fromString(pointArray[i]));
}

var map = $find('Map1');
var newPolygon = new ESRI.ADF.Geometries.Polygon(newRing, map.get_spatialReference())
    ;
 <  / script >
The CoordinateCollection component stores an array of points. Each point is created using the fromString convenience function, which assume a comma-delimited coordinate value. The polygon constructor optionally accepts a single ring (CoordinateCollection) and a spatial reference.
In many cases, geometry is retrieved via interaction with the map. The Map component maintains a getGeometry() function, which configures the map to capture user input. The following table lists the getGeometry() function input parameters:
Parameter
Description
type
The shape type to capture via interaction with the map. Valid types are defined in ESRI.ADF.Graphics.ShapeType and include Point, Line, Path, Envelope, Circle, Oval, and Ring.
onComplete
The JavaScript function to call when drawing geometry is complete. The geometry entered is passed as an argument.
  • If type = Ring, argument is of type Polygon.
  • If type = Line or Path, argument is of type Polyline.
  • If type = Envelope, argument is of type Envelope.
  • If type = Circle or Oval, argument is of type Oval.
onCancel
The JavaScript function to call if drawing geometry was cancelled. Optional parameter.
fillColor
Hypertext Markup Language (HTML) color code for fill color used when drawing. The fill color applies to surface types that have an opacity value of at least 0.2. Opacity values range from 0 (transparent) to 1 (opaque). Default is none. Optional parameter.
lineColor
HTML color code for line color used when drawing. The line color is used as outline color for surface types. Line size is 2 pixels. The default color is black. Optional parameter.
cursor
The style cursor to use when entering geometry. Cursor types include hand, crosshair, and pointer. Default is crosshair. Optional parameter.
continuous
If true, keeps collecting geometries until cancelGetGeometry() is called or the map's mouse mode changes. Default is false. Optional parameter.
Call the getGeometry() function to put the map in a state to accept user input geometry. By default, the map's mouse mode is set to ESRI.ADF.UI.MouseMode.Custom, which means you are responsible for processing user input. In this case, the JavaScript function that is specified when drawing geometry is completed contains the logic to process the input. Only one function can be called when drawing geometry has completed. You cannot call getGeometry() on the map multiple times and capture input geometry in multiple functions at the same time.
The following code shows the basic use of the getGeometry() function—to get geometry input by the user when interacting with the map. In this example, a key action (pressing the A key) changes the mouse mode of the map to accept a user provided envelope.
[JavaScript]
 < script type = "text/javascript" > var map;
Sys.Application.add_init(initialize);
function initialize(){
    map = $find('Map1');
    var keyDownGetGeometry = function(){
        map.getGeometry(ESRI.ADF.Graphics.ShapeType.Envelope, useGeometry, null,
            'red', '#0000FF', 'pointer', true);
    };

    var keyUpCancelGeometry = function(){
        map.cancelGetGeometry();
    };

    // Key action when the A key is pressed.
    map.setKeyAction(65, keyDownGetGeometry, keyUpCancelGeometry, null, false);
}

function useGeometry(inputGeometry){
    map.zoomToBox(inputGeometry, true);
}

 <  / script >
The call to getGeometry specifies the shape type of Envelope, the useGeometry function to process the user-provided envelope, and a null reference because a function is not called if getGeometry is cancelled. Additional parameters specify the color red for the envelope outline, the HTML code for the color blue to define the partially transparent fill of the envelope, a pointer as the mouse cursor while the envelope is entered, and a final Boolean value of true to indicate that as long as cancelGetGeometry has not been called, getGeometry is in effect.
In this case, the key up event calls cancelGetGeometry(). As long as the A key is pressed, the user can digitize an envelope. At run time, the user-provided envelope appears as shown in the following screen shot:
The useGeometry function illustrates how input geometry can be used. In this case, a call to the zoomToBox function on the Map control changes the extent of the map to coincide with the user-provided envelope. To cancel getGeometry(), call cancelGetGeometry() or change the map's mouse mode (set_mouseMode).

GraphicFeature

The colors specified in the getGeometry function provide visible graphics while you interact with the map. Once the geometry is created or captured, it must be packaged as a GraphicFeature class and associated with a symbol to persist as graphics in the map. The GraphicFeature class stores geometry and attributes as a client-tier feature. When creating graphic features, you can give each a unique ID and use the set_geometry and set_attributes properties to add geometry and attributes, respectively. You can also use the Microsoft Asynchronous JavaScript and XML (AJAX) JavaScript library $create shortcut function to create a GraphicFeature in one line of code.
The following code builds on the map key action handler code shown previously to digitize a user-defined ring and create a GraphicFeature:
[JavaScript]
function initialize(){
    map = $find('Map1');
    // Function that is called when the A key is pressed.
    var keyDownGetGeometry = function(){
        map.getGeometry(ESRI.ADF.Graphics.ShapeType.Ring, drawGeometry, null, 'red',
            '#0000FF', 'pointer', true);
    };
    var keyUpCancelGeometry = function(){
        map.cancelGetGeometry();
    };
    map.setKeyAction(65, keyDownGetGeometry, keyUpCancelGeometry, null, false);
}

var graphicCount = 0;
function drawGeometry(inputGeometry){
    var coords = inputGeometry.getRing(0).toString("<br>", ",");
    var attributes = {
        "graphicID": graphicCount, "featureCoordinates": coords
    };
    var graphicFeature = $create(ESRI.ADF.Graphics.GraphicFeature, {
        "id": graphicCount.toString(), "geometry": inputGeometry, "attributes":
            attributes
    }
    );
    graphicCount++;
}
The feature type for the getGeometry function call is set to Ring and the function to process the input geometry points to drawGeometry. In the drawGeometry function, the inputGeometry (a Polygon with one Ring) is interrogated to return its coordinates. The toString() function, valid for all geometry types at some level, can be used to convert geometry to a string. In most cases, you can define how the points and coordinates are separated.
In the previous code, the points in a Ring (a CoordinateCollection) are separated by an HTML page break (<BR>) and the individual coordinates are separated by a comma. The returned string is stored as an attribute with the GraphicFeature. Attributes are defined using an array of string:object pairs. Consider the string to be a field name and the object to be a field value. The pairs are wrapped in curly brackets and separated by a comma.
The $create shortcut function requires the type definition and an optional set of properties, event handlers, and so on. In the previous code, the type is ESRI.ADF.Graphics.GraphicFeature and the properties are id, geometry, and attributes. A unique ID is recommended to qualify the GraphicFeature; in this case an iterator stores an integer value. The geometry property is set to the user-defined polygon and the attributes property is set to the variable referencing the array of field:value pairs. At this stage, the GraphicFeature has been created but needs to be associated with a symbol to be rendered on the map.

Symbols

A GraphicFeature must be associated with a symbol to be rendered on a map. A set of simple symbol components are provided by the ADF JavaScript library (ESRI.ADF.Graphics). See the following diagram:
The geometry and symbol types that can be used to render the GraphicFeature are listed in the following table:
Geometry type
Supported symbol type
Point
MarkerSymbol
Polyline
LineSymbol
Surface:
  • Polygon
  • Envelope
  • Oval
LineSymbol (boundary)
FillSymbol (fill)
For all symbol types, you can define the opacity (0–1) and cursor when the mouse hovers over the GraphicFeature that is using the symbol. GraphicFeatureBase defines properties you can use to associate symbology with a GraphicFeature or a group of GraphicFeatures (GraphicFeatureGroup). These symbol properties are listed in the following table with a description of each:
GraphicFeatureBase symbol property
Description
symbol
Default symbol used if a GraphicFeature's highlight and isSelected properties are false.
highlightSymbol
Used when a GraphicFeature's highlight property is true. In many cases, the highlight property is set to true on a mouse over event of the GraphicFeature, and to false on a mouse out event.
selectedSymbol
Used if a GraphicFeature's isSelected property is true. This property can be used to define a subset of GraphicFeatures in a group.
The ADF JavaScript library does not provide a renderer; rather, the symbol properties on GraphicFeatureGroup operate as a simple renderer for all GraphicFeatures. To simulate a unique value or range renderer, each classification requires a separate GraphicFeatureGroup. Since symbols are often applied to a GraphicFeatureGroup, the next section covers creating a GraphicFeatureGroup and applying symbology where appropriate.

GraphicFeatureGroup

The GraphicFeatureGroup class contains and manages a collection of GraphicFeatures. A GraphicFeatureGroup emulates a simple feature class in the ADF JavaScript library. Symbols associated with a GraphicFeatureGroup are applied to all GraphicFeatures it contains. A set of collection management functions, such as add(), remove(), and get(), enable the manipulation and interaction with the group contents. The visible and opacity properties provide a means for adjusting the visible properties of all features.
While symbols can be applied to individual GraphicFeatures, they are often applied to a GraphicFeatureGroup for ease of use. Building on the previous code examples, the following code defines a default and highlight symbol for a polygon, creates a GraphicFeatureGroup, applies the symbols, then adds a GraphicFeature. Remember, the GraphicFeature was created using geometry entered by the user.
[JavaScript]
var graphicCount = 0;
function drawGeometry(inputGeometry){
    var coords = inputGeometry.getRing(0).toString("<br>", ",");
    var attributes = {
        "graphicID": graphicCount, "featureCoordinates": coords
    };
    var graphicFeature = $create(ESRI.ADF.Graphics.GraphicFeature, {
        "id": graphicCount.toString(), "geometry": inputGeometry, "attributes":
            attributes
    }
    );
    graphicCount++;
    var graphicFeatureGroupID = "polygonGraphics";
    var graphicFeatureGroup = $find(graphicFeatureGroupID);
    if (!graphicFeatureGroup){
        var defaultSymbol = new ESRI.ADF.Graphics.FillSymbol('white', 'blue', 2,
            'default');
        defaultSymbol.set_opacity(0.5);
        var highlightSymbol = new ESRI.ADF.Graphics.FillSymbol('yellow', 'green', 4,
            'pointer');
        highlightSymbol.set_opacity(0.5);
        var graphicFeatureGroup = $create(ESRI.ADF.Graphics.GraphicFeatureGroup, {
            "id": graphicFeatureGroupID, "symbol": defaultSymbol, "highlightSymbol":
                highlightSymbol
        }
        );
        map.addGraphic(graphicFeatureGroup);
    }
    graphicFeatureGroup.add(graphicFeature);
}
Ensure that each GraphicFeatureGroup has a unique ID; in this case it is polygonGraphics. The code checks for the existence of the GraphicFeatureGroup using the Microsoft AJAX shortcut function $find(). If it exists, add the GraphicFeature. If it does not exist, such as when the first GraphicFeature is created, define default and highlight symbols, and assign them to a new GraphicFeatureGroup created using the $create() shortcut function. The FillSymbol constructor defines the fill and outline colors, the outline width, and the cursor when the mouse hovers over the symbol. To view the GraphicFeatureGroup content in the map, call the addGraphic function on the map component.
The following screenshot illustrates how this code functions at run time, enabling the user to add multiple GraphicFeatures to the same GraphicFeatureGroup, rendered using the default symbol.
The highlight symbol was defined but not used. How can it be utilized? In many cases, the highlight symbol is used to indicate that a mouse cursor has moved over a GraphicFeature. GraphicFeatureBase defines a set of event handlers to track mouse actions on GraphicFeatures and groups. In this case, define a set of functions to handle the mouseOver and mouseOut events when the GraphicFeatureGroup is created.
The following code shows how to create a GraphicFeatureGroup with the mouse out and over functions defined. Both event handlers receive the GraphicFeatureGroup (sender) and mouse event, which contains a reference to the GraphicFeature element.
[JavaScript]
var graphicFeatureGroup = $create(ESRI.ADF.Graphics.GraphicFeatureGroup, {
    "id": graphicFeatureGroupID, "symbol": defaultSymbol, "highlightSymbol":
        highlightSymbol
}

, {
    "mouseOver": onMouseOverGraphics, "mouseOut": onMouseOutGraphics
}

);
. . . 

function onMouseOverGraphics(sender, eventArgs){
    eventArgs.element.set_highlight(true);
}

function onMouseOutGraphics(sender, eventArgs){
    eventArgs.element.set_highlight(false);
}
When moving the mouse pointer over a GraphicFeature, the highlight property for the feature is set to true and is rendered using the highlight symbol defined for the GraphicFeatureGroup. On mouse out, the GraphicFeature highlight property for the feature is set to false and is rendered using the default symbol. The following screen shot shows how this looks at run time:

Displaying graphics on a map

The Map control maintains methods for managing the display of graphics on the map. These methods and their descriptions are listed in the following table:
Method
Description
addGraphic(GraphicFeatureBase)
Adds the GraphicFeature or group to the map. If symbology is associated with the graphic features, they display immediately.
removeGraphic(GraphicFeatureBase)
Removes the specified GraphicFeature or group from the map.
refreshGraphics(force)
Re-renders all graphics associated with a map. If force is true, this method redraws the graphic features and hooks up any event.
 
This method is called internally when the map initializes and when calling map.addGraphic(). It does not re-retrieve ADF .NET graphic layer content rendered on the client.
You can add individual GraphicFeatures or groups of GraphicFeatures. If working with a group, you only need to add the group once—after that, add GraphicFeatures to the group. Once added, you can use the Microsoft AJAX library $find shortcut function and specify the ID of the GraphicFeature or GraphicFeatureGroup to locate client graphic content.
Technically, there is no limit to the number of GraphicFeatures and groups that can be added to a map component. However, graphics that are rendered on the client reside in browser memory and require sufficient client-side resources to handle the volume. You need to manage client graphics wisely to balance performance and functionality.

MapTips

The ADF JavaScript MapTips component enables interaction with client graphics in a map by displaying graphic feature attribute content in an animated, HTML-formatted dialog during a mouse over event on the respective graphic. Associating MapTips with a GraphicFeature or group is easily accomplished using the mapTips property. Each MapTips component has a callout component that represents the dialog that contains the GraphicFeature attributes. See the following graphic:
A callout represents the dialog and content associated with a MapTip and maintains two states, open and closed. When closed, only information in the title of the callout is visible. When open, both the title and the body of the callout are visible.
The MapTips component provides convenient properties to define the content of its callout. In general, the content is represented by a template that can contain valid browser content—such as HTML, JavaScript, and Cascading Style Sheets (CSS)—for both the title and the body of the callout. The hoverTemplate defines content and formatting for the callout title while contentTemplate property specifies the format of the callout body content.
The following code builds on the drawGeometry() function presented in previous code to add and enable MapTips on the user-provided geometry as a GraphicFeature:
[JavaScript]
function drawGeometry(inputGeometry){
    var ringCoords = inputGeometry.getRing(0).get_coordinates();
    for (var i = 0; i < ringCoords.length; i++){
        ringCoords[i][0] = ringCoords[i][0].toFixed(2);
        ringCoords[i][1] = ringCoords[i][1].toFixed(2);
    }
    var formattedCoords = new ESRI.ADF.Geometries.CoordinateCollection(ringCoords);
    var coords = formattedCoords.toString("<br>", ",");
    var attributes = {
        "graphicID": graphicCount, "featureCoordinates": coords
    };
    var graphicFeature = $create(ESRI.ADF.Graphics.GraphicFeature, {
        "id": graphicCount.toString(), "geometry": inputGeometry, "attributes":
            attributes
    }
    );
    graphicCount++;

    var graphicFeatureGroupID = "polygonGraphics";
    var graphicFeatureGroup = $find(graphicFeatureGroupID);
    if (!graphicFeatureGroup){
        var defaultSymbol = new ESRI.ADF.Graphics.FillSymbol('white', 'blue', 2,
            'default');
        defaultSymbol.set_opacity(0.5);
        var highlightSymbol = new ESRI.ADF.Graphics.FillSymbol('yellow', 'green', 4,
            'pointer');
        highlightSymbol.set_opacity(0.5);

        var mapTips = $create(ESRI.ADF.UI.MapTips, {
            "id": "polygonGraphicsMapTips", "animate": false
        }
        );

        mapTips.set_hoverTemplate("<b><nobr>Dynamic Map Tip {@graphicID}</nobr></b>")
            ;
        mapTips.set_contentTemplate('<span>Coordinates:
            <br><b>{@featureCoordinates}</b></span>')var graphicFeatureGroup =
            $create(ESRI.ADF.Graphics.GraphicFeatureGroup, {
            "id": graphicFeatureGroupID, "symbol": defaultSymbol, "highlightSymbol":
                highlightSymbol, "mapTips": mapTips
        }
        , {
            "mouseOver": onMouseOverGraphics, "mouseOut": onMouseOutGraphics
        }
        );
        map.addGraphic(graphicFeatureGroup);
    }
    graphicFeatureGroup.add(graphicFeature);
}
The following items related to MapTips are important in this code block:
  • The attributes of a GraphicFeature are prepared for presentation in a callout. The coordinate values of the input geometry are modified to provide a more presentable value. This highlights the task of preparing attribute data associated with a GraphicFeature that is presented in a MapTip callout.
  • The MapTips component is created using the $create shortcut function and is associated with a GraphicFeatureGroup using the mapTips property. Use $create, rather than new, to create MapTips components in the Web ADF since MapTips must be registered as AJAX components, which is done automatically when using $create.
  • There are two techniques for enabling MapTips on graphics: create the graphics (GraphicFeature or group) and set the mapTips property or create the MapTips component and use the AddGraphics() function to associate it with a GraphicFeature or group. Both techniques produce the same results, so the use of one or the other depends on developer preference only.
  • Set the content of the MapTips component by defining the hover (title) and content (body) portions of the MapTips callout. Use the hoverTemplate and contentTemplate properties, respectively. Both templates contain browser-supported content (such as HTML, style sheets, and JavaScript) and display attribute values associated with a GraphicFeature. In both templates, a placeholder variable stores the location of a GraphicFeature attribute value using the format {@<attribute name> }. The attribute value is populated when the MapTip callout is displayed for a GraphicFeature, usually during a mouse over event on the feature. The pertinent code and attributes are as follows:
[JavaScript]
var attributes = ("graphicID": graphicCount, "featureCoordinates": coords);
mapTips.set_hoverTemplate("<b><nobr>Dynamic Map Tip (@graphicID)</nobr></b>");
mapTips.set_contentTemplate('<span>Coordinates: <br><b>(@featureCoordinates)
    </b></span>')
A comprehensive sample of ADF JavaScript techniques and capabilities is available in this Help system. See the Common Custom JavaScript sample for instructions and code.


See Also:

Web ADF JavaScript Library
Mapping
Dynamic resources