How-To: Annotations in MS Chart

Diagramme leben nicht nur von den dargestellten Zahlen und Farben, sondern auch von ihrer Verständlichkeit. Zugegeben so ein paar Balken, Kreise oder Linie sind schon für sich einfacher zu erfassen als Berge von Zahlen oder mathematischen Formeln. Immerhin ist das ja auch einer der Hauptgründe warum man sich die Arbeit damit überhaupt macht. Dennoch kommt man manchmal nicht drum herum einige Erklärungen hinzuzufügen.

MS Chart bietet dafür die sogenannten Annotations. Kleine Symbole, Linien oder Texte die direkt an Datenpunkte angehangen, frei im Diagram platziert oder vom Nutzer selbst bearbeitet werden können. Folgende Annotations gibt es:

LineAnnotation

–         Linie die durch zwei Punkte führt

VerticalLineAnnotation

–         spezielle Linie die parallel zur Y-Achse durch einen Punkt führt

HorizontalLineAnnotation

–         spezielle Linie die parallel zur X-Achse durch einen Punkt führt

PolylineAnnotation

–         Kette von Linien die durch mehrere Punkte führen

–         Kann genutzt werden um Symbole zu zeichnen

PolygonAnnotation

–         Wie Polyline mit dem Unterschied, dass eine Fläche gezeichnet wird

TextAnnotation

–         Stellt einen String dar

CalloutAnnotation

–         Stellt einen String dar

–         Kann diesen auf verschiedene Art einrahmen

–         Hat einen festen Referenzpunkt auf den „gezeigt“ wird

RectangleAnnotation

–         Enthält einen Text der von einem Rechteck umrahmt ist

Border3DAnnotation

–         Wie Rectangle nur mit 3D-Effekt

EllipseAnnotation

–         Wie Rectangle nur als Ellipse

ArrowAnnotation

–         Ein Pfeilsymbol das auf einen vorgegeben Punkt zeigt

ImageAnnotation

–         Stellt ein beliebiges Bildobjekt dar

Wie man sieht ist alles dabei was das Herz begehrt. Kommen wir also zum tatsächlichen Einsatz der Dinger:

var rectangleAnnotation = new RectangleAnnotation();
rectangleAnnotation.Text = "This diagram shows a\na sinus function";
rectangleAnnotation.ClipToChartArea = chart.ChartAreas[0].Name;
rectangleAnnotation.AnchorX = 30;
rectangleAnnotation.AnchorY = 75;
chart.Annotations.Add(rectangleAnnotation);

Wie man sieht kann jede Annotation einer ChartArea “angehangen”, sprich dessen Koordinatensystem zugeordnet werden. Dadurch wird sie automatisch beim Zoomen, Scrollen usw. mit bewegt. Aus gleichem Grund wurden auch AnchorX und AnchorY gesetzt. Denn sie geben den Ankerpunkt innerhalb des zuvor definierten Koordinatensystems an. In unserem Fall das Koordinatensystem der ChartArea.

Sehr vorsichtig muss man in diesem Zusammenhang mit der Höhe und Breite der Annotations sein. Der Wert ist zur Laufzeit meist 0 und wird meines Erachtens auch überschrieben. Gleiches gilt für die Methode ResizeToContent. Es scheint mir als zähle Text nicht als Inhalt, weshalb ein Aufruf der Methode dazu führen kann, dass die Annotation nicht mehr zu sehen ist.

Ganz interessant finde ich die CalloutAnnotations, unter deren Namen man sich leider nicht sonderlich viel vorstellen kann. Tatsächlich sind sie wie eine Art Label zu verstehen, welches an bestimmte Datenpunkte angehangen wird und diese näher beschreibt. Das Beispiel unten markiert 1 / 2 Pi im oberen Bild.

var calloutAnnotation = new CalloutAnnotation();
calloutAnnotation.Text = "1/2 Pi";
calloutAnnotation.BackColor = Color.LightYellow;
calloutAnnotation.CalloutStyle = CalloutStyle.RoundedRectangle;
calloutAnnotation.AnchorOffsetY = 5;
calloutAnnotation.AnchorAlignment = ContentAlignment.BottomCenter;

var dataPoints = chart.Series[0].Points;
foreach (var point in dataPoints)
{
   if (Math.Round(point.XValue, 1) == 1.4)
   {
      calloutAnnotation.AnchorDataPoint = point;
      break;
   }
}

chart.Annotations.Add(calloutAnnotation);

Diese CalloutAnnotations haben eine besondere Eigenschaft Namens CalloutStyle über welche es möglich ist, ihr Aussehen näher zu bestimmen. So kann man den Text als Rechteck, Sprechblase und auf andere Weise darstellen. Darüber hinaus kann man über AnchorAlignment bestimmen wo der „Zipfel“, welcher auf den Datensatz zeigt, angebracht sein soll. In unserem Fall also unten in der Mitte.

rectangleAnnotation.AllowSelecting = true;
rectangleAnnotation.AllowMoving = true;
rectangleAnnotation.AllowPathEditing = true;
rectangleAnnotation.AllowTextEditing = true;
rectangleAnnotation.AllowResizing = true;

Eine Sache die ich besonders interessant finde ist, die Interaktion mit dem Nutzer. So hat jede Annotation Eigenschaften, die das Selektieren, Ändern von Text, Verschieben und sogar Größenänderung erlaubt. Darüber hinaus, kann der Nutzer einen anderen Ankerpunkt anlegen und es werden Events ausgelöst sobald eine der Eigenschaften verändert wird. Auf diese Weise kann man dem Nutzer also eine Plattform geben mit der er direkt Bestandteile des Diagrams kommentieren kann ohne es als Bild in ein Word oder ähnliches Dokument einfügen zu müssen, darin rum zu kritzeln und dann das „Machwerk“ weiter zu leiten.