I'm trying to use PolygonAnnotation to draw a Polygon within a chart where I have four points that i would like to use as vertex.
Below my chart
These Points are set at runtime in a Bubble Series:
System.Windows.Forms.DataVisualization.Charting.Series serieSA = chartCartesian.Series.FindByName("SeriesSafetyArea");
DataPoint dpA = new DataPoint(radarConfigured.SafetyArea.PointA.X,new Double[]{radarConfigured.SafetyArea.PointA.Y, -20});
DataPoint dpB = new DataPoint(radarConfigured.SafetyArea.PointB.X, new Double[]{radarConfigured.SafetyArea.PointB.Y, -20});
DataPoint dpC = new DataPoint(radarConfigured.SafetyArea.PointC.X, new Double[] { radarConfigured.SafetyArea.PointC.Y, -20 });
DataPoint dpD = new DataPoint(radarConfigured.SafetyArea.PointD.X, new Double[] { radarConfigured.SafetyArea.PointD.Y, -20 });
dpA.Label = "A";
dpB.Label = "B";
dpC.Label = "C";
dpD.Label = "D";
serieSA.Points.Add(dpA);
serieSA.Points.Add(dpB);
serieSA.Points.Add(dpC);
serieSA.Points.Add(dpD);
I would like to obtain a figure like a rectangle using these points. i've tried usign this code:
safetyAreaAnnotation = new PolygonAnnotation();
safetyAreaAnnotation.ClipToChartArea = chartCartesian.ChartAreas[0].Name;
//safetyAreaAnnotation.AnchorX = 10;
//safetyAreaAnnotation.AnchorY = 20;
PointF[] points = new PointF[4];
points[0].X = (float)dpA.XValue;
points[0].Y = (float)dpA.YValues[0] ;
points[1].X = (float)dpB.XValue;
points[1].Y = (float)dpB.YValues[0];
points[2].X = (float)dpC.XValue;
points[2].Y = (float)dpC.YValues[0];
points[3].X = (float)dpD.XValue;
points[3].Y = (float)dpD.YValues[0];
byte[] type = new byte[4];
type[0] = (byte)PathPointType.Start;
type[1] = (byte)PathPointType.Line;
type[2] = (byte)PathPointType.Line;
type[3] = (byte)PathPointType.CloseSubpath;
safetyAreaAnnotation.GraphicsPath=new System.Drawing.Drawing2D.GraphicsPath(points,type);
// //safetyAreaAnnotation.IsSizeAlwaysRelative = false;
// //safetyAreaAnnotation.BackColor = Color.Red;
safetyAreaAnnotation.AxisX = chartCartesian.ChartAreas[0].AxisX;
safetyAreaAnnotation.AxisY = chartCartesian.ChartAreas[0].AxisY;
safetyAreaAnnotation.AnchorDataPoint = serieSA.Points[0];
// //safetyAreaAnnotation.AnchorX = 1;
// //safetyAreaAnnotation.AnchorY = 20;
chartCartesian.Annotations.Add(safetyAreaAnnotation);
But it doesn't work. Nothing is displayed in my chart. Maybe I should use something different to draw this polygon?
Update
That is the result after drawing a polygon:
Your Annotation doesn't show because you didn't set a size for it.
From MSDN on PolyLines:
Remarks
A polyline must use coordinates relative to an annotation object, where (0,0) denotes the top-left coordinates and (100,100) denotes the bottom-right coordinates of the annotation.
So the first thing you would need to do is the give the Annotation
a Size
:
safetyAreaAnnotation.Width = 10;
safetyAreaAnnotation.Height = 10;
This makes it rather big, as the Size
is given in percent of the ChartArea
..
For more see MSDN on Height etc..
But even if you find a suitable size it is rather hard to set the polyline coordinates from DataPoint
values to those relative to the Annotation
area..
Not recommended!
You can draw onto the Chart
in the Pre- or PostPaint
events:
ChartArea ca = chartCartesian.ChartAreas[0];
Axis ax = ca.AxisX;
Axis ay = ca.AxisY;
List<DataPoint> dp = new List<DataPoint>() { dpA, dpB, dpC, dpD };
List<PointF> points = dp.Select(x=> new PointF(
(float)ax.ValueToPixelPosition(x.XValue),
(float)ay.ValueToPixelPosition(x.YValues[0])
)).ToList();
using (SolidBrush brush = new SolidBrush(Color.FromArgb(64, Color.Gold)))
e.ChartGraphics.Graphics.FillPolygon(brush, points.ToArray());
Just make sure the code has access to the DataPoints
.
As you see this is rather simple: It makes use of the ValueToPixelPosition
methods of the Axes
.
This is directly relating to the DataPoints
, so it will automatically scale & move when resizing. I highly recommend drawing the area over using an the Annotation
.
By the way: Your way to add a polygon to a GraphicsPath
is overcomplicated. AddPolygon(PointList.ToArray())
would have have worked just as well. Only when you want a complex mix of rounded and pointed corners would you actually go into setting the Types
array..