【问题标题】:How to display nearest data point information of a line chart by moving the mouse over the chart area如何通过将鼠标移动到图表区域上来显示折线图的最近数据点信息
【发布时间】:2019-10-03 08:30:49
【问题描述】:

我将在 Windows 窗体应用程序中使用 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 轴的线点上画圆,并在标签上显示此数据

【问题讨论】:

    标签: c# charts


    【解决方案1】:

    您可以找到仅测量 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;
    }
    

    要找到两个方向上最近的点,您需要包含轴的比例,或者可能更简单,从 DataPoints 创建一个 List&lt;PointF&gt;,以像素为单位保存点的位置。为此,请使用反向轴功能。然后我以与上述 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;
    }
    

    让我们看看它的工作原理:

    【讨论】:

    • 谢谢。第一个是我真正想做的。
    • 但有时它会给出错误消息。 “位置参数应在 0 到 100 的范围内。参数名称:位置”在这一行。 double valx = ax.PixelPositionToValue(e.X);
    • 那将是令人惊讶的。是不是你写了PositionToValue?位置是第三个坐标系,指的是百分比..
    • 如果我写 PositionToValue 它会给我同样的错误。当图表上没有图表时,实际上会出现问题。在我的例子中,图表是在按钮点击事件上绘制的。
    • 啊,好的。 PositionToValue 是错误的。但是,如果图表上没有数据,则轴将无法运行。因此,您需要在事件开始时添加一个检查。我已经更新了答案..
    猜你喜欢
    • 1970-01-01
    • 2019-06-22
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多