2011-03-24 9 views
11

¿Hay una manera simple de recuperar las coordenadas X/Y de CUALQUIER punto en el área del gráfico (en relación con ese eje del gráfico, por supuesto)?Mostrando las coordenadas del eje del mouse en el control de gráfico

A partir de ahora, sólo lograron recuperar las coordenadas cuando el ratón está sobre una serie (no fuera)

private void chart_GetToolTipText(object sender, ToolTipEventArgs e) 
{ 
    if (e.HitTestResult.Series != null) 
    { 
     e.Text = e.HitTestResult.Series.Points[e.HitTestResult.PointIndex].YValues[0] + " \n " + DateTime.FromOADate(e.HitTestResult.Series.Points[e.HitTestResult.PointIndex].XValue); 
    } 
} 

Respuesta

10

De todos modos, como siempre con MS Chart Controls, no hay manera fácil de hacer las cosas,
pero una solución original para hacer las cosas. Me estoy acostumbrando tristemente a él ...

private void chart1_MouseWhatever(object sender, MouseEventArgs e) 
{ 
    chartArea1.CursorX.SetCursorPixelPosition(new Point(e.X, e.Y), true); 
    chartArea1.CursorY.SetCursorPixelPosition(new Point(e.X, e.Y), true); 

    double pX = chartArea1.CursorX.Position; //X Axis Coordinate of your mouse cursor 
    double pY = chartArea1.CursorY.Position; //Y Axis Coordinate of your mouse cursor 
} 
+0

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

6

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); 
} 
8

Esto funciona para mis fines y no hace efecto secundario el cursor.

private Tuple<double,double> GetAxisValuesFromMouse(int x, int y) 
{ 
    var chartArea = _chart.ChartAreas[0]; 
    var xValue = chartArea.AxisX.PixelPositionToValue(x); 
    var yValue = chartArea.AxisY.PixelPositionToValue(y); 
    return new Tuple<double, double>(xValue, yValue); 
} 
+0

Este parece funcionar correctamente. – Ivan

1

Esto funciona

private void chart1_MouseWhatever(object sender, MouseEventArgs e) 
{ 
    Point chartLocationOnForm = chart1.FindForm().PointToClient(chart1.Parent.PointToScreen(chart1.Location));  

    double x = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X - chartLocationOnForm.X);  
    double y = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y - chartLocationOnForm.Y); 
} 

Y esto funciona

private void chart1_MouseWhatever(object sender, MouseEventArgs e) 
{ 
    Point chartLocationOnForm = chart1.FindForm().PointToClient(chart1.Parent.PointToScreen(chart1.Location));     

    chart1.ChartAreas[0].CursorX.SetCursorPixelPosition(new PointF(e.X - chartLocationOnForm.X, e.Y - chartLocationOnForm.Y), true); 
    chart1.ChartAreas[0].CursorY.SetCursorPixelPosition(new PointF(e.X - chartLocationOnForm.X, e.Y - chartLocationOnForm.Y), true); 

    double x = chart1.ChartAreas[0].CursorX.Position; 
    double y = chart1.ChartAreas[0].CursorY.Position; 
} 
+2

Un poco más de explicación siempre es buena para hacer que su respuesta sea más valiosa;) – ForceMagic

+0

La primera no funciona para mí. El valor de e.X era cero y la ubicación del mapa era 28, dando así un número negativo para x (que causó una excepción) cuando traté de localizar una anotación allí. – CramerTV

1
private void OnChartMouseMove(object sender, MouseEventArgs e) 
{ 
    var sourceChart = sender as Chart; 
    HitTestResult result = sourceChart.HitTest(e.X, e.Y); 
    ChartArea chartAreas = sourceChart.ChartAreas[0]; 

    if (result.ChartElementType == ChartElementType.DataPoint) 
    { 
     chartAreas.CursorX.Position = chartAreas.AxisX.PixelPositionToValue(e.X); 
     chartAreas.CursorY.Position = chartAreas.AxisY.PixelPositionToValue(e.Y); 
    } 
} 
0

Esto es lo que tengo, creo que muchos de nosotros estamos en la misma línea pero con diferentes interpretaciones de qué es lo que estás buscando

Esto le dará las coordenadas en cualquier ubicación en el área de trazado. Encontré que el HitTest proporciona una solución limpia y simple, pero hay que hacer algunas comprobaciones, ya sea que el cursor esté en un punto de datos, una cuadrícula o en el área de trazado (que parece tener prioridad en ese orden). Supongo que estarás interesado en la coordenada, independientemente de cuáles de esos objetos esté sobre el mouse.

private void chart_GetToolTipText(object sender, ToolTipEventArgs e) 
{ 
    // If the mouse isn't on the plotting area, a datapoint, or gridline then exit 
    HitTestResult htr = chart.HitTest(e.X, e.Y); 
    if (htr.ChartElementType != ChartElementType.PlottingArea && htr.ChartElementType != ChartElementType.DataPoint && htr.ChartElementType != ChartElementType.Gridlines) 
     return; 

    ChartArea ca = chart.ChartAreas[0]; // Assuming you only have 1 chart area on the chart 

    double xCoord = ca.AxisX.PixelPositionToValue(e.X); 
    double yCoord = ca.AxisY.PixelPositionToValue(e.Y); 

    e.Text = "X = " + Math.Round(xCoord, 2).ToString() + "\nY = " + Math.Round(yCoord, 2).ToString(); 
} 
Cuestiones relacionadas