Отображение координат оси мыши при управлении диаграммой
Есть ли простой способ получить координаты 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);
}
}
Ответы
Ответ 1
Во всяком случае, как всегда с помощью MS Chart Controls, нет простого способа сделать что-то, но, кстати, фанки обходного пути, чтобы все было сделано. Я с грустью привыкаю к этому...
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
}
Ответ 2
Это работает для моих целей и не влияет на курсор.
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);
}
Ответ 3
Я попробовал ваш ответ, но это не сработало для меня. В итоге он помещал курсор в одно место и никогда не двигался. Я считаю, что это потому, что я использую десятичные/двойные значения вдоль обеих осей, а курсор округляется до ближайшего целого числа.
После нескольких попыток я смог выработать метод определения, где курсор находится внутри диаграммы. Жесткая часть выясняла, что все "позиции" для элементов диаграммы фактически представляют собой процентные значения (от 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);
}
Ответ 4
Это работает
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;
}
Ответ 5
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);
}
}
Ответ 6
Это то, что я получил, я думаю, что многие из нас идут по одной линии, но с разными интерпретациями того, что вы ищете.
Это даст вам координаты в любом месте в области графика. Я обнаружил, что 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();
}