如何通过在图表区域上移动鼠标来显示折线图的最近数据点信息

时间:2019-10-03 08:30:49

标签: c# charts

我将在Windows Form Application中使用c#绘制图表。我需要在折线图上画一个圆,并在标签上显示此数据点的值,当鼠标移到图表区域上时,标签上的数据点离鼠标指针的x轴最近。

我编写如下代码……

private void Chart1_MouseMove(object sender, MouseEventArgs e)
    {
        HitTestResult result = Chart1.HitTest(e.X, e.Y);

        DataPoint nearestPoint = null;

        if (prevPosition!=null)
        {

            Chart1.Series[0].Points[prevPosition.PointIndex].MarkerStyle = MarkerStyle.None;


        }


        if (result.ChartElementType == ChartElementType.DataPoint)
        {


            string xValue = DateTime.FromOADate(Chart1.Series[0].Points[result.PointIndex].XValue).ToString("yyyy/MM/dd");
            string yValue = Convert.ToString(Chart1.Series[0].Points[result.PointIndex].YValues[0]);

            Chart1.Series[0].Points[result.PointIndex].MarkerStyle = MarkerStyle.Circle;
            Chart1.Series[0].Points[result.PointIndex].MarkerSize = 7;
            Chart1.Series[0].Points[result.PointIndex].MarkerColor = Color.Green;

            label1.Text = "Date:" + xValue;
            label2.Text = "Price:" + yValue;
            prevPosition = result;

        }

但是,当鼠标移至所描绘的行附近时,此代码在行上显示值和相应的圆圈。当鼠标远离直线但在图表区域内时,它不会显示圆和数值。我需要在最接近鼠标指针X轴的线点上画圆,并将此数据显示在标签上

1 个答案:

答案 0 :(得分:0)

您可以找到仅测量x值或y值或测量绝对距离的最接近点。或者,您可以简单地在鼠标光标下输出值,而不管这些点如何。对于最后一个see here

对于第一个三个选项,这应该有所帮助:

用于设置和重置颜色的类级别变量。.

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

让我们看看它在工作:

enter image description here