I had added Polyline annotation to graph control. But it is not aligned properly in given datapoint in Addline() method.
PolylineAnnotation annotation = new PolylineAnnotation();
annotation.AxisX = chart1.ChartAreas[0].AxisX;
annotation.AxisY = chart1.ChartAreas[0].AxisY;
annotation.AnchorX = 0;
annotation.AnchorY = 0;
annotation.Height = 30;
annotation.Width = -30;
annotation.LineWidth = 3;
annotation.StartCap = LineAnchorCapStyle.None;
annotation.EndCap = LineAnchorCapStyle.None;
annotation.Alignment = ContentAlignment.BottomLeft;
annotation.AnchorAlignment = ContentAlignment.BottomRight;
annotation.AnchorDataPoint = new DataPoint(this.chart1.Series[0]);
annotation.AllowAnchorMoving = true;
annotation.AllowMoving = true;
annotation.AllowPathEditing = true;
annotation.AllowResizing = true;
annotation.AllowSelecting = true;
annotation.GraphicsPath.AddLine(10, 20, 30, 30);
chart1.Annotations.Add(annotation);
Annotations
are complex and anchoring them is too.
It starts rather simple: To anchor an Annotation
you need to set its AnchorDataPoint
to an existing DataPoint
.
This line does nothing like that:
annotation.AnchorDataPoint = new DataPoint(this.chart1.Series[0]);
as the newly created DataPoint
is empty. Its has been added and it has values of (0d, 0d)
, but you probably want to keep the Annotation
aligned to a real DataPoint
, maybe like this..:
annotation.AnchorDataPoint = chart1.Series[0].Points[someIndex];
But there is more: There actually are two ways to anchor an Annotation
:
DataPoint
orAnchorX
and AnchorY
values.(And then you can set them to fixed X & Y values, too.)
Your code actually does both! But: anchoring the coordinates takes precedence over anchoring to a DataPoint
.
This is nice as you can combine them and first anchor to a DataPoint
and then anchor one of the coordinates to a fixed value: say, x-value stays with the point but the y-value is maybe always at 0..
Also note that you are adding only one line to your polyline and you don't start it at (0,0)
but at (10,20)
which may be quite some way off the anchor..
And then there is the issue of size and alignment of the polyline itself!
It has a size which MSDN claims is given in pixels. This is nonsense. Instead it is given in value
units of the two respective Axes
. You can see this when you resize the Chart
the Annotation
will resize as well; see the screenshot!
Now for the GraphicsPath
and its points: Those are given in percent of the Size
of the Annotation
. To get a feeling for this add a test annotation path that encloses the whole area:
annotation.GraphicsPath.AddRectangle(new Rectangle(0, 0, 100, 100));
Here is a screenshot of what we have got:
As you can see the most logical alignment is TopLeft
and after translating the line to (0,0)
it would stick right into the point.
Note that I have added a 2nd Series
to make the anchor data point stand out.. - Also note that while the Annotation
size is a square (10,10)
is is stretched horizontally along with the whole chart.
This is the full code I used:
PolylineAnnotation annotation = new PolylineAnnotation();
annotation.AxisX = chart1.ChartAreas[0].AxisX;
annotation.AxisY = chart1.ChartAreas[0].AxisY;
annotation.Height = 10;
annotation.Width = 10;
annotation.LineWidth = 3;
annotation.StartCap = LineAnchorCapStyle.None;
annotation.EndCap = LineAnchorCapStyle.None;
annotation.Alignment = ContentAlignment.TopLeft;
annotation.AnchorAlignment = ContentAlignment.TopLeft;
annotation.X = annotation.Y = annotation.AnchorX = annotation.AnchorY = double.NaN;
DataPoint dp = chart1.Series[0].Points[33];
annotation.AnchorDataPoint = dp;
chart1.Series[1].Points.AddXY(dp.XValue, dp.YValues[0]); // my red points series
annotation.AllowAnchorMoving = true;
annotation.AllowMoving = true;
annotation.AllowPathEditing = true;
annotation.AllowResizing = true;
annotation.AllowSelecting = true;
annotation.GraphicsPath.AddLine(10, 20, 30, 30);
Rectangle r = new Rectangle(0, 0, 100, 100);
annotation.GraphicsPath.AddRectangle(r);
chart1.Annotations.Add(annotation);
Also note that just to make sure no wrong anchors are active I have reset the X/Y
and the AnchorX/Y
values by setting them to double.NaN
! This is not really needed here, as those are the defaults anyway..