2011-03-24 19 views
11

C'è un modo semplice per recuperare le coordinate X/Y di QUALSIASI punto nell'area del grafico (rispetto all'asse del grafico, ovviamente)?Visualizzazione delle coordinate dell'asse del mouse sul controllo grafico

A partire da ora, ho solo riuscito a recuperare le coordinate quando il mouse si trova su una serie (non all'esterno)

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

risposta

10

In ogni caso, come sempre con Chart Controls MS, non v'è alcun modo semplice per fare le cose,
ma una soluzione funky per fare le cose. Mi sto purtroppo abituando ...

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

Ho appena provato questo: pX funziona bene, ma pY rimane costante (= 1) (mentre entrambi e.X ed e.Y cambiano). Inoltre aggiunge un mirino a schema completo che può essere indesiderato in alcuni casi particolari. – Ivan

6

Ho provato la tua risposta, ma non ha funzionato per me. Ha finito per mettere il cursore in un punto e mai in movimento. Credo che questo sia dovuto al fatto che utilizzo valori decimali/doppi lungo entrambi gli assi e che il cursore sia arrotondato al numero intero più vicino.

Dopo diversi tentativi, sono stato in grado di elaborare un metodo per determinare dove si trova il cursore all'interno del grafico. La parte difficile è stata capire che tutte le "posizioni" per gli elementi del grafico sono in realtà valori percentuali (da 0 a 100).

Secondo
http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.elementposition.aspx:
"Definisce la posizione dell'elemento grafico in coordinate relative, che vanno da (0,0) a (100,100)."

Spero non ti dispiaccia, sto postando questa risposta qui solo per i posteri, nel caso in cui qualcun altro si imbatta in questo problema, e anche il tuo metodo non funziona per loro. Non è bello o elegante in alcun modo, ma finora funziona per me.

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

questo funziona per i miei scopi e non fa effetto collaterale il cursore.

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

Questo sembra funzionare bene. – Ivan

1

Questo funziona

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

E questo funziona

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 po 'più di spiegazione è sempre buona per rendere la tua risposta più preziosa;) – ForceMagic

+0

Il primo non funziona per me. Il valore e.X era zero e la posizione della tabella era 28, fornendo quindi un numero negativo per x (che ha causato un'eccezione) quando ho tentato di localizzare un'annotazione lì. – 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

Questo è quello che ho ottenuto, penso che molti di noi sono sulla stessa linea, ma con diverse interpretazioni di cosa stai cercando.

Ciò fornirà le coordinate in qualsiasi posizione nell'area di disegno. Ho trovato che lo HitTest fornisce una soluzione semplice e pulita, ma ci sono alcuni controlli da fare, indipendentemente dal fatto che il cursore si trovi su un punto dati, una griglia o nell'area di disegno (che sembrano avere la precedenza in questo ordine). Presumo che ti interesserà la coordinata indipendentemente da quale di questi oggetti il ​​mouse è finito.

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(); 
} 
Problemi correlati