![A Column Chart with a Smiley face that was created using Custom Annotations.](Images/Chart_Custom_Annotations_01.png)
It is possible to create Custom Annotations by implementing IAnnotation or inheriting Annotation. Once a custom annotation has been created, instances of these custom annotations can be added to the chart’s Annotations collection.
In Visual Basic:
Me.UltraChart1.Annotations.Add(New MyAnnotation())
In C#:
this.ultraChart1.Annotations.Add(new MyAnnotation());
The IAnnotation interface consists of one property, Location. When implementing the interface, it is sufficient to simply store this property in a private field within the class.
The important part of the IAnnotation interface is the RenderAnnotation method. There are two overloads for this method; one takes a Primitive object which represents the "parent" primitive, and the other overload takes a Point which represents the point the Annotation is to be rendered at.
These different overloads exists because of the different ways of matching an annotation to the chart using a Location object. In cases where row and/or column wildcards are used, this method may be called more than one time per annotation per chart.
For the overload of RenderAnnotation with a "parent" Primitive as a parameter, the static Annotation. GetRenderPointFromParent method is provided as an easy way to get a render point from the parent primitive. Further customization of an Annotation class would probably require custom code to get an appropriate point based on a parent Primitive . From this point, the other overload of RenderAnnotation can be called; of course this is not a requirement, just a programming guideline.
Code to draw annotations is just like code that goes in a custom layer’s FillSceneGraph method: Primitives must be created and added to the SceneGraph.
Following is an example of a simple, but complete, custom Annotation class:
In Visual Basic:
Imports System Imports System.Drawing Imports System.Drawing.Drawing2D Imports Infragistics.UltraChart.Core Imports Infragistics.UltraChart.Core.Primitives Imports Infragistics.UltraChart.Resources.Appearance Imports Infragistics.UltraChart.Shared.Styles Public Class MyAnnotation Implements IAnnotation Public Sub RenderAnnotation(ByVal scene As SceneGraph, _ ByVal renderPoint As Point) Implements IAnnotation.RenderAnnotation Dim head As New Ellipse(renderPoint, 50) head.PE.Fill = Color.Yellow head.PE.StrokeWidth = 5 scene.Add(head) Dim mouth As New Wedge(renderPoint, 40, 0, 180) mouth.PE.Fill = Color.Black mouth.PE.FillStopColor = Color.White mouth.PE.ElementType = PaintElementType.Hatch mouth.PE.Hatch = FillHatchStyle.Vertical mouth.PE.StrokeWidth = 3 scene.Add(mouth) Dim leftEye As New Ellipse(New Point(renderPoint.X - 20, renderPoint.Y - 20), 5) Dim rightEye As New Ellipse(New Point(renderPoint.X + 20, renderPoint.Y - 20), 5) leftEye.PE.Fill = Color.Black rightEye.PE.Fill = Color.Black scene.Add(leftEye) scene.Add(rightEye) End Sub Public Sub RenderAnnotation(ByVal scene As SceneGraph, _ ByVal parent As Primitive) Implements IAnnotation.RenderAnnotation Dim renderPoint As Point = Annotation.GetRenderPointFromParent(parent) Me.RenderAnnotation(scene, renderPoint) End Sub Private _location As New Location() Public Property Location() As Location Implements IAnnotation.Location Get Return Me._location End Get Set(ByVal Value As Location) Me._location = Value End Set End Property End Class
In C#:
using System; using System.Drawing; using System.Drawing.Drawing2D; using Infragistics.UltraChart.Core; using Infragistics.UltraChart.Core.Primitives; using Infragistics.UltraChart.Resources.Appearance; using Infragistics.UltraChart.Shared.Styles; public class MyAnnotation : IAnnotation { public void RenderAnnotation(SceneGraph scene, Point renderPoint) { Ellipse head = new Ellipse(renderPoint, 50); head.PE.Fill = Color.Yellow; head.PE.StrokeWidth = 5; scene.Add(head); Wedge mouth = new Wedge(renderPoint, 40, 0, 180); mouth.PE.Fill = Color.Black; mouth.PE.FillStopColor = Color.White; mouth.PE.ElementType = PaintElementType.Hatch; mouth.PE.Hatch = FillHatchStyle.Vertical; mouth.PE.StrokeWidth = 3; scene.Add(mouth); Ellipse leftEye = new Ellipse(new Point(renderPoint.X - 20, renderPoint.Y - 20), 5); Ellipse rightEye = new Ellipse(new Point(renderPoint.X + 20, renderPoint.Y - 20), 5); leftEye.PE.Fill = Color.Black; rightEye.PE.Fill = Color.Black; scene.Add(leftEye); scene.Add(rightEye); } public void RenderAnnotation(SceneGraph scene, Primitive parent) { Point renderPoint = Annotation.GetRenderPointFromParent(parent); this.RenderAnnotation(scene, renderPoint); } private Location _location = new Location(); public Location Location { get { return this._location; } set { this._location = value; } } }