user1668272
user1668272

Reputation: 51

c# chart vertical text annotation

I'm adding annotations to a c# line chart. I'd like to change the text orientation but can't see any setting to allow this.

RectangleAnnotation annotation = new RectangleAnnotation();
annotation.AnchorDataPoint = chart1.Series[0].Points[x];
annotation.Text = "look an annotation";
annotation.ForeColor = Color.Black;
annotation.Font = new Font("Arial", 12); 
annotation.LineWidth = 2;   
chart1.Annotations.Add(annotation);

The annotation is added to the graph correctly and the rectangle and text run left to right. I want to orientate it to run up and down. Any suggestions on how to achieve this?

Upvotes: 5

Views: 9305

Answers (2)

Sergey
Sergey

Reputation: 640

The solution that worked for me.

First, add the annotation as usual. The key is to make it invisible and then draw it manually in the Chart.PostPaint event.

var text = new RectangleAnnotation();
text.ClipToChartArea = chart.ChartAreas[0].Name;
text.Text = "Title";
text.AxisX = chart.AxisX;
text.AxisY = chart.AxisY;
text.X = value;
text.Y = chart.AxisY.Maximum;
text.BackColor = chart.BaseSettings.ColorStorage["First"][1]; // Use your colors
text.LineColor = chart.BaseSettings.ColorStorage["First"][1];
text.ForeColor = Color.White;
text.Visible = false; // <- Hide the annotation.
chart.graph.Annotations.Add(text);
text.ResizeToContent();

Secondly, manually draw the text in Chart.PostPaint.

private static void ChartPostPaint(object sender, ChartPaintEventArgs e)
{    
    var chart = (Chart)sender;

    foreach (var annotation in chart.Annotations)
    {
        var text = annotation as RectangleAnnotation;
        if (text == null || text.Visible)
        {
            /* Skip all other irrelevant annotations and those which are visible. */
            continue;
        }

        var g = e.ChartGraphics.Graphics;
        var m = g.MeasureString(text.Text, text.Font);

        /* Convert the chart coordinates to the absolute values. */
        float x = (float)e.ChartGraphics.GetPositionFromAxis(text.ClipToChartArea, AxisName.X, text.X);
        float y = (float)e.ChartGraphics.GetPositionFromAxis(text.ClipToChartArea, AxisName.Y, text.Y);
        float w = m.Height;
        float h = m.Width;

        var p = e.ChartGraphics.GetAbsolutePoint(new PointF(x, y));

        using (var bg = new SolidBrush(text.BackColor))
        using (var fc = new SolidBrush(text.ForeColor))
        {
            g.FillRectangle(bg, p.X - m.Height, p.Y, w, h);

            /* Rotate the surface by 270 degrees around the text. */
            var dx = p.X - (m.Height / 2f);
            var dy = p.Y + (m.Height / 2f);
            g.TranslateTransform(dx, dy);
            g.RotateTransform(270);
            g.TranslateTransform(-dx, -dy);

            /* Draw the text as usual */
            g.DrawString(text.Text, text.Font, fc, p.X - m.Width, p.Y + 1);
            
            /* And rotate it back. */
            g.ResetTransform();
        }
    }
}

enter image description here

Upvotes: 2

tmwoods
tmwoods

Reputation: 2413

You cannot rotate annotations using the annotation library. You have to use postpaint or prepaint. Here is a good example of how to use the post-paint event. Hope this helps. I'll include the code from the link below:

protected void Chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
if (e.ChartElement is Chart)
{
    // create text to draw
    String TextToDraw;
    TextToDraw = "Printed: " + DateTime.Now.ToString("MMM d, yyyy @ h:mm tt");
    TextToDraw += " -- Copyright © Steve Wellens";

    // get graphics tools
    Graphics g = e.ChartGraphics.Graphics;
    Font DrawFont = System.Drawing.SystemFonts.CaptionFont;
    Brush DrawBrush = Brushes.Black;

    // see how big the text will be
    int TxtWidth = (int)g.MeasureString(TextToDraw, DrawFont).Width;
    int TxtHeight = (int)g.MeasureString(TextToDraw, DrawFont).Height;

    // where to draw
    int x = 5;  // a few pixels from the left border

    int y = (int)e.Chart.Height.Value;
    y = y - TxtHeight - 5; // a few pixels off the bottom

    // draw the string        
    g.DrawString(TextToDraw, DrawFont, DrawBrush, x, y);
}

}

EDIT: I just realized this example doesn't actually rotate the text. I know you have to use this tool so I will try to find an example using postpaint that rotates text.

EDIT 2: Aaah. Right here at SO. Basically you need to use the e.Graphics.RotateTransform(270); property (that line would rotate 270 degrees).

Upvotes: 0

Related Questions