How to implement TOC legends for custom feature renderers


Summary
A custom feature renderer can be developed to control the way features of a feature layer are drawn. When you develop a custom feature renderer, it is essential to implement table of contents (TOC) legends for your custom renderer. Implementing TOC legends ensures that the TOCs, and legends in your map documents and ArcMap show a list of the symbols, labels, and headings that correspond to your custom feature renderer. This topic describes how you can create TOC legends for custom renderers and preserve the state of your legend in map documents and layer files.

In this topic


About implementing TOC legends for custom feature renderers

TOC legends can be created for custom feature renderers by implementing the ILegendInfo interface. The custom feature renderer should have at least one LegendGroup with at least one LegendClass.
The LegendGroup manages an array of LegendClass objects. Each LegendClass object corresponds to one symbol. Store all required symbols for rendering the feature layer in the LegendClass objects. LegendClass objects, apart from symbols, also contain descriptive text strings for the label and description (the label shows in the table of contents).
The following illustration shows the legend groups, legend class, and symbols as applicable to the standard ArcGIS feature renderer, BiUniqueValueRenderer:

Implementing TOC legends

To implement a TOC legend for a custom feature renderer, the custom feature renderer Java class should implement the ILegendInfo interface. Create LegendGroups and LegendClasses to suit your custom feature renderer.
When applying the custom feature renderer to the GOLF feature layer, appropriate labels and symbols for the custom renderer are applied to the legends. The following illustration shows a custom TOC legend implemented for the PointDispersalRenderer custom feature renderer:
The following code example shows the implementation of the custom TOC legend for the preceding PointDispersalRenderer illustration:
[Java]
//See the PointDispersalRenderer sample.

//Step 1: The custom renderer Java class implements ILegendInfo.
@ArcGISExtension public class PointDispersalRenderer implements IFeatureRenderer,
    ILegendInfo, java.io.Externalizable, IDocumentVersionSupportGEN{

    private ILegendGroup legendGroup;
    private double dispersalRatio = 3.0;

    public PointDispersalRenderer(){
        try{

            //Legends are created when the object is created.
            createLegend();

        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    //The method that creates the TOC legend.
    public void createLegend()throws Exception{
        //Step 2: Create a legend group.
        legendGroup = new LegendGroup();
        legendGroup.setHeading("My Legend");
        legendGroup.setEditable(true);
        legendGroup.setVisible(true);

        //Step 3: Create a legend class.
        ILegendClass legendClass = new LegendClass();
        legendClass.setLabel("dispersed");
        // Make a default marker symbol.
        ISimpleMarkerSymbol simpleMarkerSym = new SimpleMarkerSymbol();
        simpleMarkerSym.setStyle(esriSimpleFillStyle.esriSFSSolid);
        simpleMarkerSym.setOutline(true);
        simpleMarkerSym.setSize(7);
        IColor color = new RgbColor();
        color.setRGB(255);
        simpleMarkerSym.setColor(color);

        //Add symbol to legend Class
        legendClass.setSymbolByRef((ISymbol)simpleMarkerSym);

        //Step 4: Add the legend class to the legend group.
        legendGroup.addClass(legendClass);
    }

    //Implement applicable methods of ILegendInfo according to your implementation.

    //Returns the associated LegendGroup.
    public ILegendGroup getLegendGroup(int arg0)throws IOException,
        AutomationException{
        if (legendGroup.esri_getClass(0).getSymbol() != null)
            return legendGroup;
        else
            return null;
    }

    //Returns the number (it is 1) of legend groups for PointDispersalRenderer.
    public int getLegendGroupCount()throws IOException, AutomationException{

        if (legendGroup != null)
            return 1;
        else
            return 0;
    }


    //Define further legend formatting for the layer in ArcMap.
    //Not implemented for PointDispersalRenderer.
    public ILegendItem getLegendItem()throws IOException, AutomationException{
        return null;
    }

    //Indicates whether the symbols used for a layer or renderer's legend vary by size.
    //For example, the proportional symbol renderer returns true for this property.
    //For PointDispersalRenderer, return false.
    public boolean isSymbolsAreGraduated()throws IOException, AutomationException{
        return false;
    }
}

Persisting TOC legends

If you want users to change the symbology of your custom renderer, persist the symbology in a .mxd document or .lyr file. Instead of persisting the symbols independently, persist them as legend groups.
When persisting legend groups, the IFeatureRenderer.draw() method extracts symbols from the legend group to render the feature layer appropriately.
The following code example shows how to persist the legend group in the java.io.Externalizable.readExternal() and java.io.Externalizable.writeExternal() methods, and how to extract the symbols of the legend group in the IFeatureRenderer.draw() method to draw the feature layer. For more information, see the sample, PointDispersalRenderer.   
[Java]
@ArcGISExtension public class PointDispersalRenderer implements IFeatureRenderer,
    ILegendInfo, java.io.Externalizable, IDocumentVersionSupportGEN{

    ILegendGroup grp;

    //Read values from the persisted medium.
    public void readExternal(ObjectInput in)throws IOException,
        ClassNotFoundException{
        legendGroup = (ILegendGroup)in.readObject();
        dispersalRatio = in.readDouble();
    }

    //Write values to the persisted medium.
    public void writeExternal(ObjectOutput out)throws IOException{
        out.writeObject(legendGroup);
        out.writeDouble(dispersalRatio);
    }


    public void draw(IFeatureCursor featureCursor, int drawPhase, IDisplay display,
        ITrackCancel trackCancel)throws IOException, AutomationException{

        //See the PointDispersalRenderer sample.

        //The symbol is derived from its legend class.
        //LegendGroup.esri_getClass(0) returns the legend class at 0 position.
        ISymbol pSym = legendGroup.esri_getClass(0).getSymbol();
        if (pSym == null){
            return ;
        }
        IDisplayTransformation displayTrans = display.getDisplayTransformation();
        IMarkerSymbol markerSym = (IMarkerSymbol)pSym;
        double dispersalDist = displayTrans.fromPoints(markerSym.getSize()) *
            dispersalRatio;
        //Set the symbol on the display
        display.setSymbol(pSym);

        //Loop through the features and draw them using the symbol.
        //Build a GeometryBag.
        //See the PointDispersalRenderer sample for the remaining code.
    }

    //See the PointDispersalRenderer sample for additional method implementation.
}


See Also:

Implementing persistence for a custom feature renderer
How to implement custom property pages for custom feature renderers




Development licensingDeployment licensing
Engine Developer KitEngine
ServerServer
ArcGIS for Desktop BasicArcGIS for Desktop Basic
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced