Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
392 views
in Technique[技术] by (71.8m points)

c# - Get Y value of series from the X Cursor position where a ChartArea is clicked on

I would like to get the Y Value for a series corresponding to the X position of a ChartArea that the user has clicked-upon.

I have tried to capture the X position of the mouse within the chartarea that is clicked upon but I am getting NaN returned for the result:

 private void chart_Click(object sender, EventArgs e)
    {
       double XVal = chart.ChartAreas[0].CursorX.Position;
    }

Once I have got the X position in the chartarea where the user has clicked the mouse, I would then like to use that to get the Y value of a series at that x-position.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  • What is wrong with you code?

As for chart.ChartAreas[0].CursorX: A Chart Cursor is an object created by and used for zooming and which then

Represents a horizontal or vertical line that defines a position along an axis.

So it has not much to do with the mouse cursor and is not valid when not zooming or (when zooming is disabled) for selecting.

  • How to solve your problem then?

There are a few options you have; unfortunately none are both simple and exactly what you asked for.

One simple thing is to use the HitTest for Charts:

private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    HitTestResult hit = chart1.HitTest(e.X, e.Y);
    if (hit.PointIndex >= 0)
        infoLabel.Text = "Over DataPoint No " +  hit.PointIndex;
}

This is simple and safe but will work only when the cursor is actually over a DataPoint. How well it suits you may depend on the ChartType; Very well for Columns or Bars but not so well for Points or Bubbles..

And you could call PixelPositionToValue:

private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    var xv =  chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X);                    
    var yv =  chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);
    infoLabel.Text = "x = " +  xv + "   y =" + yv;
}

In theory this is only safe to call from one of the Paint events but in practice it seems to work fine when called from user interactions as well. (If you run into problems you could do a dummy call on one of the Paint events and abort it with a flag after pulling the value(s) you want; the example does a lot more than what you need, but I doubt it will be necessary at all..)

However it will only bring back the Values according to the axis, not the nearest DataPoint. If you really need to get at the actual DataPoint you would then have to do a search over the Points of your Series..:

Series S = chart1.Series[0];            // short reference
DataPoint pPrev = S.Points.Select(x => x)
                        .Where(x => x.XValue >= xv)
                        .DefaultIfEmpty(S.Points.First()).First();
DataPoint pNext = S.Points.Select(x => x)
                        .Where(x => x.XValue <= xv)
                        .DefaultIfEmpty(S.Points.Last()).Last();

This should bring up the previous and next DataPoint. It is up to you to decide which one to use..


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...