Вы можете найти ближайшую точку, измеряющую только значения x или y, или измеряющую абсолютные расстояния. Или вы можете просто вывести значения под курсором мыши, независимо от точек. Для этого последнего см. Здесь !
Для каждого из первых трех вариантов это должно помочь:
Переменные уровня класса, используемые для установки и сброса цветов ..:
DataPoint dpXaxis = null;
DataPoint dpYaxis = null;
DataPoint dpAbs = null;
И список точек для сохранения местоположения пикселей всех точек:
List<Point> pixPoints = null;
Событие MouseMove
:
private void chart_MouseMove(object sender, MouseEventArgs e)
{
ChartArea ca = chart.ChartAreas[0];
Axis ax = ca.AxisX;
Axis ay = ca.AxisY;
Series s = chart.Series[0];
if (!s.Points.Any()) return; // no data, no action!
// option 1:
// the values at the mouse pointer:
double valx = ax.PixelPositionToValue(e.X);
double valy = ay.PixelPositionToValue(e.Y);
// the deltas on the x-axis (with index):
var ix = s.Points.Select((x, i) => new {delta = Math.Abs(x.XValue - valx), i})
.OrderBy(x => x.delta).First().i;
var dpx = s.Points[ix];
// option 2:
// the deltas on the y-axis (with index):
var iy = s.Points.Select((x, i) =>
new {delta = Math.Abs(x.YValues[0] - valy), i })
.OrderBy(x => x.delta).First().i;
var dpy = s.Points[iy];
// option 3:
// the absolute distances (with index):
var ind = pixPoints.Select((x, i) =>
new { delta = Math.Abs(x.X - e.X) + Math.Abs(x.Y - e.Y), i}).
OrderBy(x => x.delta).First().i;
// find index of smallest delta
var dpca = s.Points[ind];
// set/reset colors
if (dpXaxis != null) dpXaxis.Color = s.Color;
dpXaxis = dpx;
dpXaxis.Color = Color.LawnGreen;
// set/reset colors
if (dpYaxis != null) dpYaxis.Color = s.Color;
dpYaxis = dpy;
dpYaxis.Color = Color.Cyan;
if (dpAbs != null) dpAbs.Color = s.Color;
dpAbs = dpca;
dpAbs.Color = Color.Red;
}
Чтобы найти ближайшую точкув обоих направлениях вам нужно будет либо включить шкалы осей, либо, возможно, проще, создать List<PointF>
из DataPoints
, который будет содержать положения точек в пикселях. Для этого используйте функции обратной оси. Затем я вычисляю дельты таким же образом, как и в Linq выше.
Список заполняется / обновляется примерно так:
List<Point> getPixPoints(Series s, ChartArea ca)
{
List<Point> points = new List<Point>();
foreach (DataPoint dp in s.Points)
{
points.Add(new Point(
(int)ca.AxisX.ValueToPixelPosition(dp.XValue),
(int)ca.AxisY.ValueToPixelPosition(dp.YValues[0]) ));
}
return points;
}
Давайте посмотрим на это в работе: