Developing Web Applications with the Web ADF - Working with graphics  

Working with Web-tier graphics on the client



While the Web ADF includes a rich set of custom graphics functionality for developers to leverage in the Web tier (see Working with graphics), the Web ADF JavaScript Library provides client-side graphics objects for accessing functionality that can only be made available in the client tier (see the ADF JavaScript Graphics and map tips topic). In many instances, the functionality offered by the Web ADF in either the Web tier or the client tier will readily meet an application's requirements. When this is the case, the recommended best practice is to isolate graphic manipulation logic to one tier so as not to unnecessarily convolute program flow.

In some situations, however, it may be necessary or clearly advantageous to interact with the same set of graphics in both the Web and client tiers. For example, consider a case where a tool needs to issue a query against a map service and display the features satisfying the query on the map. Furthermore, when one of these features is moused over, the feature's attributes must be shown in a tabular display located elsewhere on the page. With the Web ADF, executing a query and converting the results to graphics can be done very easily using Web tier objects. But implementing functionality that executes when a graphic is moused over requires interacting with graphics in the client tier. Here, the best solution will require creating graphics in the Web tier and manipulating those graphics in the client tier. This document will explain the key concepts a Web ADF developer should understand when implementing functionality to handle such situations. 
 
Cross-tier graphics equivalencies

While the Web ADF graphics-related objects available in the Web and client tiers do not implement all the same capabilities, they do contain many equivalent properties, methods, and events. For managing sets of graphics, the Web tier ElementGraphicsLayer and FeatureGraphicsLayer classes correspond to the GraphicFeatureGroup object in the client tier. For individual graphics, the .NET DataRow and Web ADF GraphicElement Web tier classes correspond to the client tier GraphicFeature object. The equivalencies between the members of these objects are shown in the table below.



 
Enabling client-side functionality for a GraphicsLayer

When a GraphicsLayer (either element or feature) is instantiated and added to a graphics map resource in the Web tier, equivalent client tier graphics objects are not created by default. Rather, when the GraphicsLayer is rendered, the Web ADF creates an image of the layer's contents in the Web tier and then blends this image with those of other layers in the map. When this is the case, no client-side graphics functionality is available for the layer. To enable client tier interaction, the GraphicsLayer class includes a RenderOnClient property, which is false by default. When this property is set to true, the Web ADF will automatically create a client tier GraphicFeatureGroup and GraphicFeatures that mimic the properties of the Web tier GraphicsLayer and its underlying DataTable. The Web ADF will then leave rendering the graphics to these client-side objects, which will in turn create a DOM element to render each GraphicFeature.

Retrieving a GraphicsLayer's corresponding GraphicFeatureGroup

As mentioned above, a GraphicFeatureGroup is the client tier equivalent of a Web tier GraphicsLayer. So to manipulate a GraphicsLayer's client-side representation, we first need to get a reference to the corresponding GraphicFeatureGroup. When the Web ADF creates a GraphicFeatureGroup for a GraphicsLayer, it does so using the AJAX $create function. Thus, the group is registered as an AJAX component. Registered AJAX components can be retrieved by passing the ID of the component to the AJAX $find function. To get the GraphicFeatureGroup's component ID, we must use the Web ADF Map control's GetGraphicsLayerClientID method. The code snippet below illustrates these steps. Note that the code assumes it is executing during a callback or partial postback after which the Map's callback results will be processed on the client.

[C#]
// Get the component ID of the GraphicFeatureGroup corresponding to graphicsLayer by
// passing graphicsLayer to Map control's GetGraphicsLayerClientID method
string graphicFeatureGroupID = Map1.GetGraphicsLayerClientID(graphicsLayer);

// Construct a JavaScript statement to retrieve the GraphicFeatureGroup having the ID
string jsGetGraphicFeatureGroup = string.Format("var graphicFeatureGroup = $find('{0}')",
graphicFeatureGroupID);

// Instantiate a callback result that will execute the JavaScript
ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult getGraphicFeatureGroupCallbackResult =
	ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(
    jsGetGraphicFeatureGroup);

// Add the callback result to the Map's collection
Map1.CallbackResults.Add(getGraphicFeatureGroupCallbackResult);

[VB]
' Get the component ID of the GraphicFeatureGroup corresponding to graphicsLayer by
' passing graphicsLayer to the Map control's GetGraphicsLayerClientID method
Dim graphicFeatureGroupID As String = Map1.GetGraphicsLayerClientID(graphicsLayer)

' Construct a JavaScript statement to retrieve the GraphicFeatureGroup having the ID
Dim jsGetGraphicFeatureGroup As String = _
String.Format("var graphicFeatureGroup = $find('{0}')", graphicFeatureGroupID)

' Instantiate a callback result that will execute the JavaScript
Dim getGraphicFeatureGroupCallbackResult As _
ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = _
ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript( _
jsGetGraphicFeatureGroup)

' Add the callback result to the Map's collection
Map1.CallbackResults.Add(getGraphicFeatureGroupCallbackResult)

Once we have a client tier reference to the GraphicFeatureGroup, we can use all the functionality provided by the Web ADF JavaScript Library to manipulate it and its contents. Note, however, that the GraphicFeatureGroup is synchronized with the Web tier DataTable underlying the corresponding GraphicsLayer when the map resource containing the layer is refreshed in the Web Tier (i.e. by calling Map.RefreshResource). This means that the properties stored in this table—geometries, attributes, and whether graphics are selected—will overwrite their client-side equivalents when the resource is refreshed. Thus the recommended best practice in this situation is to avoid client-side manipulation of members that have equivalents in the corresponding Web tier DataTable (e.g. geometry). Otherwise, properties of graphics that were established in the client tier may unexpectedly be lost.

Manipulating callouts in the Web-tier

One of the most common uses of client tier graphics functionality is to display a callout containing attribute-related information when a feature is moused over. When a GraphicsLayer is created in the Web tier and RenderOnClient is set to true, callouts containing member graphics' attribute information will be displayed by default whenever a member graphic is moused over. The Web ADF MapTips control, QueryAttributesTask, and SearchAttributesTask all leverage this functionality to display graphics with callouts.

The contents of these callouts can be modified by using the ApplyTitleTemplate and ApplyContentsTemplate methods of the GraphicsLayer class. The parameter passed to ApplyTitleTemplate determines the callout's initial display, while that passed to ApplyContentsTemplate determines what is shown when the callout is clicked. The parameters to these methods are strings containing the html markup and fields to be rendered. For further information on how to use template strings, see the Working with the Title and Contents Properties section of Working with layer formats.

Some situations may require that client tier graphics functionality be made available without the appearance of callouts. In the situation mentioned in the introduction, for instance, the attributes of moused over graphics are to be displayed in a table elsewhere on the page, so we would not want those attributes to also be displayed in a callout. To address such cases, the GraphicsLayer object has an EnableCallout property. To disable callouts for a GraphicsLayer that has RenderOnClient set to true, simply set EnableCallout to false.

Pushing Web-tier property changes to the client

As mentioned above, the graphics properties stored in a Web tier DataTable are automatically pushed to the corresponding client tier GraphicFeatureGroup whenever the map resource containing the graphics is refreshed. For properties that are not stored in the underlying DataTable, such as MapTips templates and symbology, passing Web tier modifications to the client requires setting the GraphicsLayer.ForceFullClientGraphicsRefresh property to true before refreshing the resource. Note that setting this property to true and refreshing the resource will overwrite all the properties of the corresponding client tier GraphicFeatureGroup with their Web tier equivalents. Because of this, the recommended best practice for modifying properties that are not captured in the GraphicsLayer's underlying DataTable is to isolate all such modification to either the client or the Web tier. Implementing an application that modifies these properties in the client tier in some situations and in the Web tier in others will unnecessarily convolute application architecture and introduce the likelihood that some use cases will cause graphic properties to be overwritten unexpectedly.