Chart Renderering using Web ADF

 

These are days am working with ArcGIS Server [9.2+SP3]- Java edition. I’ve started with ESRI samples and grown up to creating tasks for my application. Task framework is handy to create our own custom business logic with rich UI. I’m trying to recreate or mimic ‘Charts’ functionality similar to Arc Map.  User can select a layer (yet to code), field(s) and chart type to draw charts.   User has option to prevent overlap, change map base symbol color, field(s) color also. It works fine. No harm, charts draws fine. 

 

While I try to remove the rendering, I couldn’t do so. Later, When I investigated, chart rendering has been applied to the map service (i.e. on server objects) since it is pooled one. I have searched in forum/developers help, I learnt that com.esri.adf.web.data.renderer package has ONLY five classes WebClassBreakInfo, WebClassBreaksRenderer, WebSimpleRenderer, WebUniqueValueInfo, and WebUniqueValueRenderer.  The Chart Rendering option is NOT available with the web ADF.  My senior colleague who attended Dev Summit has explained me that only ArcIMS has this functionality through ArcXML using Chart Symbol Object and not in 9.2. ESRI will incorporate in 9.3 ;adding charts in graphics layer or from other source. This helps me that am working in right direction.

 

As a developer, you should not expect that everything can only done thru available methods/properties, sometimes we may need to use reverse logic to obtain desired result. One of my fellow colleague suggested that before applying chart rendering to layer object, feature renderer of the layer is stored temporarily once chart renderer is applied , web context is refreshed. Then now apply the feature renderer stored in temporary object to server object so that user can see the charts whereas a server object doesn’t get changed. This is simple and better idea for time being. 

 

There are several other interesting learning’s/findings in creating this task. I’ve used custom xsl from Daniel Garcia Roman Class break rendering. 

 

I’m facing some problems like how to update overview map dynamically when rendering type is changed, while changing radio events are not firing properly (I’ve to click twice). Yet to implement normalization, exclusions, orientation, size etc. For a developer who is fairly having good understanding of ArcObjects doing task is not so tough. Here, we are working with ArcObjects remotely. I always use VBA help to understand methods/properties of classes. Then try to migrate to java. Proper casting, creating objects in server context, error handling, using appropriate packages are very vital in server app development. I strongly feel that lack of samples in Developer help for Java as in .NET is a big handicap. We have depend on forums/experts  to understand certain basic issues.

 

 

Advertisements

Tags: , ,

5 Responses to “Chart Renderering using Web ADF”

  1. David García Says:

    The solution about the change of the render without change the state of the service works well, but I have a question. Did you realize about the fact that all the operations that you performed in your map ( zoom in, zoom out, etc…) will remove your new render? Because if you request an operation from the GIS Server, it will send you the response with the “old” render, so you will have to override all the defaults tasks and operation to change the render, refresh and restore the original render.

    Other problem is the TOC. This control will show you the original render, because it takes the information of the layer from the GIS Server which have the original render. Do you have a solution for this?

    Regards,

    David García García

  2. iamlaksh1 Says:

    Dear David,
    Can you elborate “so you will have to override all the defaults tasks and operation to change the render, refresh and restore the original render” how to do this. You have to update webtoc and webover view and refresh the context.

    //refresh the context because the Mapdescription has changed and we want to see the changes

    WebToc newToc = new WebToc();
    newToc.init(webContext);
    webContext.setWebToc(newToc);

    WebOverview wOverview = new WebOverview();
    wOverview.init(webContext);
    webContext.setWebOverview(wOverview);

    webContext.refresh(wOverview);
    webContext.refresh(newToc);

    webContext.refresh();

  3. David García Says:

    Hi,

    Thanks to answer me.

    When I say that you will have to override all the defaults tasks and operations I meant that all the default tasks that gives you a map ( zoom in, zoom out, zoom to extent, etc..) will render this new image with the original render of the layer that we have changed for our session.

    If you make a class that extends com.esri.adf.web.tasks.MapToolsTask, reference it in the faces-config.xml flie, and overrides all the methods that have a ADFEvent (TaskEvent or MapEvent) as parameter, in these methods call the parent method (super.method(event);) and then replace the original render for ours, call the refresh method and then replace our render for the original. It will avoid that when we navigate in the map through a tool of the MapToolsTask the layer returns an image with the original render.

    A better way to do this, is to use a class that extends of com.esri.adf.web.data.WebContext and overrides the refresh (Object object) method like this:

    public class AGSExtendedWebContext extends WebContext
    {
    protected IFeatureRenderer renderer;
    protected int layerId;

    public int getLayerId() {
    return layerId;
    }

    public void setLayerId(int layerId) {
    this.layerId = layerId;
    }

    public IFeatureRenderer getRenderer() {
    return renderer;
    }

    public void setRenderer(IFeatureRenderer renderer) {
    this.renderer = renderer;
    }

    public void refresh()
    {
    super.refresh();
    }

    public void refresh(Object object)
    {
    Map resources = this.getResources();
    AGSLocalMapResource agsResource = (AGSLocalMapResource)resources.get(“ags0”);
    IFeatureRenderer oldRenderer = null;
    if ( this.renderer != null)
    {
    try
    {
    oldRenderer = ((IGeoFeatureLayer)agsResource.getLocalMapServer().getLayer(agsResource.getMapName(),layerId)).getRenderer();
    ((IGeoFeatureLayer)agsResource.getLocalMapServer().getLayer(agsResource.getMapName(),layerId)).setRendererByRef(renderer);
    }
    catch(Exception ex)
    {
    ex.printStackTrace();
    }
    }
    super.refresh(object);
    if ( this.renderer != null)
    {
    try
    {
    ((IGeoFeatureLayer)agsResource.getLocalMapServer().getLayer(agsResource.getMapName(),layerId)).setRendererByRef(oldRenderer);
    }
    catch(Exception ex)
    {
    ex.printStackTrace();
    }
    }

    }
    }

    Well, the only problem that I found now is the webTOC. when I click in the cross to deploy the layer render legend, it shows me the original render. I think that it makes a request to the Gis Server to do this. I will try to extend the webTOC to control this.

    Thanks for your help, if I discover something I notice you.

    Sorry for my english,

    Regards,

    David García

  4. iamlaksh1 Says:

    Thanks for your answers. Your idea is good. I’ll try this one. Once again thanks for your time!

  5. iamlaksh1 Says:

    Expanding TOC dynamically calls MapService, hence we default renderer is seen even after chart renderer is applied. This could be solved using workaround , by default you keep the TOC nodes expanded( you can use the expandLevel property – ContextAttributes). And remove the submit event from the rendererNode function in esri_toc.js file . Hope you agree with me

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: