He intentado su respuesta, pero no funcionó para mí. Terminó colocando el cursor en un punto y nunca moviéndose. Creo que esto se debe a que uso valores decimales/dobles a lo largo de ambos ejes, y el cursor se redondea al entero más cercano.
Después de varios intentos, pude encontrar un método para determinar dónde está el cursor dentro del gráfico. La parte difícil fue descubrir que todas las "posiciones" para los elementos del gráfico son en realidad valores porcentuales (de 0 a 100).
Según
http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.elementposition.aspx:
"define la posición del elemento gráfico en coordenadas relativas, que van desde (0,0) a (100100)".
Espero que no te importe, estoy publicando esta respuesta aquí solo para la posteridad, en caso de que alguien más se encuentre con este problema, y tu método tampoco funciona para ellos. No es bonito ni elegante de ninguna manera, pero hasta ahora me funciona.
private struct PointD
{
public double X;
public double Y;
public PointD(double X, double Y)
{
this.X = X;
this.Y = Y;
}
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
var pos = LocationInChart(e.X, e.Y);
lblCoords.Text = string.Format("({0}, {1}) ... ({2}, {3})", e.X, e.Y, pos.X, pos.Y);
}
private PointD LocationInChart(double xMouse, double yMouse)
{
var ca = chart1.ChartAreas[0];
//Position inside the control, from 0 to 100
var relPosInControl = new PointD
(
((double)xMouse/(double)execDetailsChart.Width) * 100,
((double)yMouse/(double)execDetailsChart.Height) * 100
);
//Verify we are inside the Chart Area
if (relPosInControl.X < ca.Position.X || relPosInControl.X > ca.Position.Right
|| relPosInControl.Y < ca.Position.Y || relPosInControl.Y > ca.Position.Bottom) return new PointD(double.NaN, double.NaN);
//Position inside the Chart Area, from 0 to 100
var relPosInChartArea = new PointD
(
((relPosInControl.X - ca.Position.X)/ca.Position.Width) * 100,
((relPosInControl.Y - ca.Position.Y)/ca.Position.Height) * 100
);
//Verify we are inside the Plot Area
if (relPosInChartArea.X < ca.InnerPlotPosition.X || relPosInChartArea.X > ca.InnerPlotPosition.Right
|| relPosInChartArea.Y < ca.InnerPlotPosition.Y || relPosInChartArea.Y > ca.InnerPlotPosition.Bottom) return new PointD(double.NaN, double.NaN);
//Position inside the Plot Area, 0 to 1
var relPosInPlotArea = new PointD
(
((relPosInChartArea.X - ca.InnerPlotPosition.X)/ca.InnerPlotPosition.Width),
((relPosInChartArea.Y - ca.InnerPlotPosition.Y)/ca.InnerPlotPosition.Height)
);
var X = relPosInPlotArea.X * (ca.AxisX.Maximum - ca.AxisX.Minimum) + ca.AxisX.Minimum;
var Y = (1 - relPosInPlotArea.Y) * (ca.AxisY.Maximum - ca.AxisY.Minimum) + ca.AxisY.Minimum;
return new PointD(X, Y);
}
Acabo de probar esto: pX funciona bien, pero pY permanece constante (= 1) (mientras que tanto e.X como e.Y cambian). También agrega un punto de mira completo que puede ser indeseable en algunos casos particulares. – Ivan