从单击ChartArea的X光标位置获取系列的Y值

我想得到一个系列的Y值,该系列对应于用户点击的ChartArea的X位置。

我试图在点击的图表区域内捕获鼠标的X位置,但我得到NaN返回结果:

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

一旦我在用户点击了鼠标的图表区域中获得了X位置,我就会想用它来获得该x位置的系列的Y值。

  • 你的代码出了什么问题?

至于chart.ChartAreas[0].CursorXChart Cursor是由缩放创建并用于缩放的对象,然后

表示沿轴定义位置的水平或垂直线。

因此它与鼠标光标没什么关系,并且在不缩放或(当禁用缩放时)选择时无效。

  • 那怎么解决你的问题呢?

你有几个选择; 不幸的是,没有一个既简单完全符合您的要求。

一个简单的事情是使用HitTest for Charts

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

这很简单且安全,但仅在光标实际位于DataPoint时才有效。 它适合你的程度可能取决于ChartType ; 非常适用于ColumnsColumns ,但对PointsBubbles不太好..

你可以调用PixelPositionToValue

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

从理论上讲,这只能从一个Paint事件调用是安全的,但在实践中,当从用户交互调用时它似乎也能正常工作。 (如果遇到问题,你可以在其中一个Paint事件上进行虚拟调用 ,并在拉出你想要的值之后用一个标志中止它;这个例子比你需要的更多,但我怀疑它会是必要的…)

但是它只会根据轴返回Values ,而不是最近的DataPoint 。 如果你真的需要获得实际的DataPoint那么你必须搜索你的SeriesPoints …:

 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(); 

这应该会显示上一个和下一个DataPoint 。 由您来决定使用哪一个..

首先将鼠标单击位置转换为相对位置:

 x= 100.0 * eX / chart.Width 

然后将相对位置转换为轴位置:

 double xMin= axis.Minimum; double xMax= axis.Maximum; double pMin= axis.GetPosition(xMin); double pMax= axis.GetPosition(xMax); xx= (x-pMin) * (xMax-xMin) / (pMax-pMin) + xMin; 

然后使用轴位置探测系列(例如插入或最近的点)

由于“MouseEventArgs”,您需要一个用于图表控件的MouseClick-Handler而不是普通的Click-Handler:

 private void chart1_MouseClick(object sender, MouseEventArgs e) { //check where you clicked, returns different information like the clicked series name and the index of the clicked point HitTestResult clicked = chart1.HitTest(eX, eY); //this is how you get your y-Value double yValue = chart1.Series[clicked.Series.Name].Points[clicked.PointIndex].YValues[0]; }