Common Custom renderers
Common_CustomRenderers_CSharp\App_Code\LabelPointRenderer.cs
// Copyright 2011 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

namespace ESRI.ADF.Samples.Renderers
{

  /// <summary>
  /// Creates a label over a point with a background box like this:
  /// ---------------------
  /// |Attribute goes here|
  /// |________  _________|
  ///          \/
  /// </summary>
    public class LabelPointRenderer : ESRI.ADF.Samples.Renderers.RendererBase
    {
        #region Public Properties

        private string labelColumn = "Name";

        /// <summary>
        /// Name of the column containing text to use on the label
        /// </summary>
        [System.ComponentModel.Description("Name of the column containing text to use on the label")]
        public string LabelColumn
        {
            get { return labelColumn; }
            set { labelColumn = value; }
        }

        private System.Drawing.Color backgroundColor = System.Drawing.Color.White;
        /// <summary>
        /// The fill color of the label's callout
        /// </summary>
        [System.ComponentModel.Description("The fill color of the label's callout")]
        public System.Drawing.Color BackgroundColor
        {
            get { return backgroundColor; }
            set { backgroundColor = value; }
        }

        private System.Drawing.Color outlineColor = System.Drawing.Color.Black;
        /// <summary>
        /// The outline color around the label's callout
        /// </summary>
        [System.ComponentModel.Description("The outline color around the label's callout")]
        public System.Drawing.Color OutlineColor
        {
            get { return outlineColor; }
            set { outlineColor = value; }
        }

        private System.Drawing.Color fontColor = System.Drawing.Color.Black;
        // The font color used on the label
        [System.ComponentModel.Description("The font color used on the label")]
        public System.Drawing.Color FontColor
        {
            get { return fontColor; }
            set { fontColor = value; }
        }

        private System.Drawing.Font font;
        // The font used on the label
        [System.ComponentModel.Description("The font used on the label")]
        public System.Drawing.Font Font
        {
            get { return font; }
            set { font = value; }
        }

        #endregion

        // Use the constructor to set a default font
    public LabelPointRenderer()
      : base()
    {
      this.Font = new System.Drawing.Font("Arial", 8f);
        }

        #region IRenderer Members

        /// <summary>
        /// Main part of the IRenderer interface, within which a feature encapsulating the specified DataRow is to be 
        /// rendered on the specified graphics surface. The geometry instance has already been transformed to screen 
        /// coordinate, so we don't have to worry about that here.
        /// </summary>
        /// <param name="row">row containing the feature's data</param>
        /// <param name="graphics">GDI+ surface on which to render the feature</param>
        /// <param name="geometryColumn">column containing the feature's geometry</param>
        public override void Render(System.Data.DataRow row, System.Drawing.Graphics graphics, 
            System.Data.DataColumn geometryColumn)
    {
            // Validate method input
      if (row == null || graphics == null || geometryColumn == null)
        return;

            // Validate input geometry.  This renderer will only work on points.
      ESRI.ArcGIS.ADF.Web.Geometry.Geometry geometry = row[geometryColumn] as 
                ESRI.ArcGIS.ADF.Web.Geometry.Geometry;
      if (geometry == null || !(geometry is ESRI.ArcGIS.ADF.Web.Geometry.Point))
        return;

            // Get the input point
      ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = geometry as ESRI.ArcGIS.ADF.Web.Geometry.Point;

            // Make sure the input feature has the renderer's specified label column 
      if (row.Table.Columns.Contains(this.LabelColumn)) //Only if column exists
      {
                // Get the label's text
        string labelText = row[this.LabelColumn].ToString();

                // Get the size of the rendered label text
        System.Drawing.SizeF size = graphics.MeasureString(labelText, this.Font);

                // Label parameters
        int margin = 2; // Margin around text
        int arrowSize = 5; // size of leader arrow pointing to our point
        int width = (int)size.Width + margin * 2;
        int height = (int)size.Height + margin * 2;
        
        // Create polygon for text background such that the label will look like:
        // ---------------------
        // |Attribute goes here|
        // |________  _________|
        //          \/
        //         (x,y)

                // Use the input point's coordinates as the start point of the callout
        int x = (int)adfPoint.X;
        int y = (int)adfPoint.Y;

                // Populate an array with the callout polygon's points
        System.Drawing.Point[] calloutPoints = new System.Drawing.Point[8];
        calloutPoints[0] = new System.Drawing.Point(x, y); // Start point - tip of leader arrow
        calloutPoints[1] = new System.Drawing.Point(x - arrowSize, y - arrowSize);  // Top left of leader arrow
        calloutPoints[2] = new System.Drawing.Point(x - width / 2, calloutPoints[1].Y);      // Lower left of box
        calloutPoints[3] = new System.Drawing.Point(calloutPoints[2].X, calloutPoints[2].Y - height); // Upper left of box
        calloutPoints[4] = new System.Drawing.Point(calloutPoints[3].X + width, calloutPoints[3].Y);  // Upper right of box
        calloutPoints[5] = new System.Drawing.Point(calloutPoints[4].X, calloutPoints[4].Y + height); // Lower right of box
        calloutPoints[6] = new System.Drawing.Point(x + arrowSize, y - arrowSize);  // Top right of leader arrow
        calloutPoints[7] = new System.Drawing.Point(x, y); // End point
                
                // Add the callout polygon to a GDI+ graphics path
                System.Drawing.Drawing2D.GraphicsPath graphicsPath = new System.Drawing.Drawing2D.GraphicsPath();
                graphicsPath.AddPolygon(calloutPoints);

        // Draw the callout polygon's fill (i.e. background)
        graphics.FillPath(new System.Drawing.SolidBrush(this.BackgroundColor), graphicsPath);

                // Draw the callout polygon's outline
        graphics.DrawPath(new System.Drawing.Pen(this.OutlineColor), graphicsPath);

        // Draw the label text
        graphics.DrawString(labelText, this.Font, new System.Drawing.SolidBrush(this.FontColor),
          new System.Drawing.PointF(x - width / 2 + margin, y - height - arrowSize + margin));
      }
        }

        #endregion
    }
}