How do you create an Annotation on-the-run and how do you enable end-user placement with Annotation.BeginPlacement()
? I\'ve tried to do this in multiple ways, b
You need to calculate the right positions. Remember that the MouseMove will not give you positions (percentages) or values(data) but pixels. You can transform them using the various axis functions. Officially they only work in a xxxPaint event, but during mouse events they also work fine.
Update: There two ways to do the anchoring:
Here is an example of the 1st kind:
LineAnnotation laNew = null;
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
if (cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
laNew = new LineAnnotation();
chart1.Annotations.Add(laNew);
double vx = ax.ValueToPosition(ax.PixelPositionToValue(e.X));
double vy = ay.ValueToPosition(ay.PixelPositionToValue(e.Y));
laNew.X = vx;
laNew.Y = vy;
}
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left) && cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
double vx = ax.ValueToPosition(ax.PixelPositionToValue(e.X))- laNew.X;
double vy = ay.ValueToPosition(ay.PixelPositionToValue(e.Y)) - laNew.Y;
laNew.Width = Math.Min(100, vx);
laNew.Height = Math.Min(100, vy);
laNew.LineColor = rb_green.Checked ? Color.Green : Color.Red;
laNew.AllowMoving = true; // optional
}
}
This works fine unles you need to rescale the axis in some way, like changing the axis minimum and/or maximum values.
First we need to relate the Annotation
to the Axes
and also set IsSizeAlwaysRelative
to false
. Then we can calculate the anchor and size values:
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
if (cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
laNew = new LineAnnotation();
chart1.Annotations.Add(laNew);
laNew.IsSizeAlwaysRelative = false;
laNew.AxisX = ax;
laNew.AxisY = ay;
laNew.AnchorX = ax.PixelPositionToValue(e.X);
laNew.AnchorY = ay.PixelPositionToValue(e.Y);
laNew.LineColor = rb_green.Checked ? Color.Green : Color.Red;
laNew.AllowMoving = true;
}
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left) && cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
laNew.Width = ax.PixelPositionToValue(e.X) - laNew.AnchorX; // values
laNew.Height = ay.PixelPositionToValue(e.Y) - laNew.AnchorY;
}
}
Note how I now can scale the maximum and also still resize the the chart and the annotations stay with the data points..:
Update: To restrict the line to the ChartArea
add this to the definition in the MouseDown
event:
laNew.ClipToChartArea = chart1.ChartAreas[0].Name;
To prevent an exception from leaving the Chart, add this to the condition in the MouseMove
..:
.. && chart1.ClientRectangle.Contains(e.Location)