Reputation: 51
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
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();
}
}
}
Upvotes: 2
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