2011-03-24 2 views
11

Есть ли простой способ получить координаты X/Y ЛЮБОЙ точки в диаграмме. Область (относительно этой оси графика, конечно)?Отображение координат оси мышки при управлении диаграммой

В настоящее время, я только что удалось получить координаты при наведении курсора мыши на серии (не снаружи)

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

ответ

10

Во всяком случае, как всегда с элементами управления Chart MS, не существует простой способ сделать что-то,
, но фанки обходной путь, чтобы все было сделано. К сожалению, я привык к этому ...

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

Я только что попробовал: pX работает нормально, но pY остается постоянным (= 1) (при изменении e.X и e.Y). Также он добавляет перекрестие с полным графиком, которое может быть нежелательным в некоторых конкретных случаях. – Ivan

6

Я пробовал ваш ответ, но это не сработало для меня. В итоге он помещал курсор в одно место и никогда не двигался. Я считаю, что это потому, что я использую десятичные/двойные значения вдоль обеих осей, а курсор округляется до ближайшего целого.

После нескольких попыток я смог выработать метод определения, где курсор находится внутри диаграммы. Трудная часть выясняла, что все «позиции» для элементов диаграммы фактически представляют собой процентные значения (от 0 до 100).

В соответствии с
http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.elementposition.aspx:
"Определяет положение элемента диаграммы в относительных координатах, которые варьируются от (0,0) до (100,100)."

Надеюсь, вы не против, я размещаю этот ответ здесь только для потомков, если кто-то сталкивается с этой проблемой, и ваш метод также не работает для них. Это не очень или элегантно, но пока это работает для меня.

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

Это работает для моих целей и не побочный эффект курсора.

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

Этот, кажется, работает в самый раз. – Ivan

1

Это работает

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

И это работает

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

Немного больше объяснений всегда полезно сделать ваш ответ более ценным;) – ForceMagic

+0

Первый не работает для меня. Значение e.X равнялось нулю, а chartlocation - 28, тем самым давая отрицательное число для x (что вызвало исключение), когда я попытался найти там аннотацию. – 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

Это то, что я получил, я думаю, что многие из нас по той же схеме, но с различными интерпретациями что вы ищете.

Это даст вам координаты в любом месте в области графика. Я нашел, что HitTest дает чистое и простое решение, но есть несколько проверок, которые необходимо сделать, будь то курсор на точке данных, линии сетки или в области графика (которые, похоже, имеют приоритет в этом порядке). Я предполагаю, что вас будет интересовать координата, независимо от того, из какого из этих объектов мышь закончилась.

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(); 
} 
Смежные вопросы