C# 在图表控件上显示鼠标轴坐标

C# 在图表控件上显示鼠标轴坐标,c#,.net,mschart,C#,.net,Mschart,是否有一种简单的方法来检索图表区域中任意点的X/Y坐标(当然是相对于该图表轴) 到目前为止,我只是在鼠标位于序列上(而不是在外部)时设法检索坐标 不管怎样,与MS图表控件一样,没有简单的方法来完成事情,但是有一个很时髦的方法来完成事情。很遗憾我已经习惯了 private void chart1_MouseWhatever(object sender, MouseEventArgs e) { chartArea1.CursorX.SetCursorPixelPosition(new Poi

是否有一种简单的方法来检索图表区域中任意点的X/Y坐标(当然是相对于该图表轴)

到目前为止,我只是在鼠标位于序列上(而不是在外部)时设法检索坐标


不管怎样,与MS图表控件一样,没有简单的方法来完成事情,
但是有一个很时髦的方法来完成事情。很遗憾我已经习惯了

private void chart1_MouseWhatever(object sender, MouseEventArgs e)
{
    chartArea1.CursorX.SetCursorPixelPosition(new Point(e.X, e.Y), true);
    chartArea1.CursorY.SetCursorPixelPosition(new Point(e.X, e.Y), true);

    double pX = chartArea1.CursorX.Position; //X Axis Coordinate of your mouse cursor
    double pY = chartArea1.CursorY.Position; //Y Axis Coordinate of your mouse cursor
}

我试过你的答案,但对我无效。它最终把光标放在一个点上,再也不动了。我相信这是因为我在两个轴上都使用了十进制/双精度值,并且光标被舍入到最接近的整数

经过几次尝试,我终于找到了一种方法来确定光标在图表中的位置。困难的部分是计算出图表元素的所有“位置”实际上都是百分比值(从0到100)

根据
:
“定义图表元素在相对坐标中的位置,范围从(0,0)到(100100)。”

我希望你不介意,我在这里发布这个答案只是为了子孙后代,以防其他人遇到这个问题,你的方法也不适用于他们。它在任何方面都不漂亮也不优雅,但到目前为止,它对我来说都很管用。

private struct PointD
{
  public double X;
  public double Y;
  public PointD(double X, double Y)
  {
    this.X = X;
    this.Y = Y;
  }
}

private void chart1_MouseMove(object sender, MouseEventArgs e)
{
  var pos = LocationInChart(e.X, e.Y);
  lblCoords.Text = string.Format("({0}, {1}) ... ({2}, {3})", e.X, e.Y, pos.X, pos.Y);
}

private PointD LocationInChart(double xMouse, double yMouse)
{
  var ca = chart1.ChartAreas[0];

  //Position inside the control, from 0 to 100
  var relPosInControl = new PointD
  (
    ((double)xMouse / (double)execDetailsChart.Width) * 100,
    ((double)yMouse / (double)execDetailsChart.Height) * 100
  );

  //Verify we are inside the Chart Area
  if (relPosInControl.X < ca.Position.X || relPosInControl.X > ca.Position.Right
  || relPosInControl.Y < ca.Position.Y || relPosInControl.Y > ca.Position.Bottom) return new PointD(double.NaN, double.NaN);

  //Position inside the Chart Area, from 0 to 100
  var relPosInChartArea = new PointD
  (
    ((relPosInControl.X - ca.Position.X) / ca.Position.Width) * 100,
    ((relPosInControl.Y - ca.Position.Y) / ca.Position.Height) * 100
  );

  //Verify we are inside the Plot Area
  if (relPosInChartArea.X < ca.InnerPlotPosition.X || relPosInChartArea.X > ca.InnerPlotPosition.Right
  || relPosInChartArea.Y < ca.InnerPlotPosition.Y || relPosInChartArea.Y > ca.InnerPlotPosition.Bottom) return new PointD(double.NaN, double.NaN);

  //Position inside the Plot Area, 0 to 1
  var relPosInPlotArea = new PointD
  (
    ((relPosInChartArea.X - ca.InnerPlotPosition.X) / ca.InnerPlotPosition.Width),
    ((relPosInChartArea.Y - ca.InnerPlotPosition.Y) / ca.InnerPlotPosition.Height)
  );

  var X = relPosInPlotArea.X * (ca.AxisX.Maximum - ca.AxisX.Minimum) + ca.AxisX.Minimum;
  var Y = (1 - relPosInPlotArea.Y) * (ca.AxisY.Maximum - ca.AxisY.Minimum) + ca.AxisY.Minimum;

  return new PointD(X, Y);
}
私有结构点d
{
公共双X;
公共双Y;
公共点D(双X,双Y)
{
这个.X=X;
这个。Y=Y;
}
}
私有void chart1_MouseMove(对象发送方,MouseEventArgs e)
{
var pos=位置初始值(e.X,e.Y);
lblCoords.Text=string.Format(({0},{1}).({2},{3})”,e.X,e.Y,pos.X,pos.Y);
}
专用点位置入口(双X住宅、双Y住宅)
{
var ca=chart1.ChartAreas[0];
//位于控件内部,从0到100
var relPosInControl=新点D
(
((双)xMouse/(双)execDetailsChart.Width)*100,
((双倍)Y使用/(双倍)执行细节部分高度)*100
);
//确认我们在图表区域内
如果(重新定位InControl.Xca.Position.Right
||relPosInControl.Yca.Position.Bottom)返回新的点D(double.NaN,double.NaN);
//位于图表区域内,从0到100
var relPosInChartArea=新点D
(
((重新定位InControl.X-约位置X)/约位置宽度)*100,
((重新定位InControl智能驭享-ca.Position.Y)/ca.Position.Height)*100
);
//确认我们在绘图区域内
如果(relPosInChartArea.Xca.InnerPlotPosition.Right
||relPosInChartArea.Yca.InnerPlotPosition.Bottom)返回新的点D(double.NaN,double.NaN);
//在绘图区域内的位置,0到1
var relPosInPlotArea=新点D
(
((relPosInChartArea.X-ca.InnerPlotPosition.X)/ca.InnerPlotPosition.Width),
((relPosInChartArea.Y-ca.InnerPlotPosition.Y)/ca.InnerPlotPosition.Height)
);
var X=relPosInPlotArea.X*(ca.AxisX.max-ca.AxisX.Minimum)+ca.AxisX.Minimum;
变量Y=(1-relPosInPlotArea.Y)*(ca.AxisY.Maximum-ca.AxisY.Minimum)+ca.AxisY.Minimum;
返回新的点d(X,Y);
}

这适用于我的目的,不会对光标产生副作用

private Tuple<double,double> GetAxisValuesFromMouse(int x, int y)
{
    var chartArea = _chart.ChartAreas[0];
    var xValue = chartArea.AxisX.PixelPositionToValue(x);
    var yValue = chartArea.AxisY.PixelPositionToValue(y);
    return new Tuple<double, double>(xValue, yValue);
}
private Tuple GetAxisValuesFromMouse(int x,int y)
{
var chartArea=_chart.ChartAreas[0];
var xValue=chartArea.AxisX.PixelPositionToValue(x);
var yValue=chartArea.AxisY.PixelPositionToValue(y);
返回新元组(xValue,yValue);
}
这很有效

private void chart1_MouseWhatever(object sender, MouseEventArgs e)
{   
    Point chartLocationOnForm = chart1.FindForm().PointToClient(chart1.Parent.PointToScreen(chart1.Location));     

    double x = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X - chartLocationOnForm.X);    
    double y = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y - chartLocationOnForm.Y);
}
这是有效的

private void chart1_MouseWhatever(object sender, MouseEventArgs e)
{ 
    Point chartLocationOnForm = chart1.FindForm().PointToClient(chart1.Parent.PointToScreen(chart1.Location));                

    chart1.ChartAreas[0].CursorX.SetCursorPixelPosition(new PointF(e.X - chartLocationOnForm.X, e.Y - chartLocationOnForm.Y), true);
    chart1.ChartAreas[0].CursorY.SetCursorPixelPosition(new PointF(e.X - chartLocationOnForm.X, e.Y - chartLocationOnForm.Y), true);

    double x = chart1.ChartAreas[0].CursorX.Position;
    double y = chart1.ChartAreas[0].CursorY.Position;
}

这就是我所得到的,我想我们中的许多人都有相同的想法,但对你所寻找的东西有不同的理解

这将为您提供绘图区域中任何位置的坐标。我发现
HitTest
提供了一个干净简单的解决方案,但是需要进行一些检查,不管光标是在数据点、网格线上还是在绘图区域(它们似乎以该顺序优先)。我假设你会对坐标感兴趣,不管鼠标在哪个对象上

private void chart_GetToolTipText(object sender, ToolTipEventArgs e)
{
    // If the mouse isn't on the plotting area, a datapoint, or gridline then exit
    HitTestResult htr = chart.HitTest(e.X, e.Y);
    if (htr.ChartElementType != ChartElementType.PlottingArea && htr.ChartElementType != ChartElementType.DataPoint && htr.ChartElementType != ChartElementType.Gridlines)
        return;

    ChartArea ca = chart.ChartAreas[0]; // Assuming you only have 1 chart area on the chart

    double xCoord = ca.AxisX.PixelPositionToValue(e.X);
    double yCoord = ca.AxisY.PixelPositionToValue(e.Y);

    e.Text = "X = " + Math.Round(xCoord, 2).ToString() + "\nY = " + Math.Round(yCoord, 2).ToString();
}

多一点解释总是有助于让你的答案更有价值;)第一个不适合我。e.X值为零,chartlocation为28,因此当我试图在此处定位注释时,X的值为负数(这导致了一个异常)。我刚刚尝试了以下方法:pX工作正常,但pY保持不变(=1)(而e.X和e.Y都发生了变化)。此外,它还添加了一个完整的图表十字线,这在某些特定情况下可能是不受欢迎的!谢谢
private void OnChartMouseMove(object sender, MouseEventArgs e)
{
    var sourceChart = sender as Chart;
    HitTestResult result = sourceChart.HitTest(e.X, e.Y);
    ChartArea chartAreas = sourceChart.ChartAreas[0];

    if (result.ChartElementType == ChartElementType.DataPoint)  
    {
        chartAreas.CursorX.Position = chartAreas.AxisX.PixelPositionToValue(e.X);
        chartAreas.CursorY.Position = chartAreas.AxisY.PixelPositionToValue(e.Y);
    }
}
private void chart_GetToolTipText(object sender, ToolTipEventArgs e)
{
    // If the mouse isn't on the plotting area, a datapoint, or gridline then exit
    HitTestResult htr = chart.HitTest(e.X, e.Y);
    if (htr.ChartElementType != ChartElementType.PlottingArea && htr.ChartElementType != ChartElementType.DataPoint && htr.ChartElementType != ChartElementType.Gridlines)
        return;

    ChartArea ca = chart.ChartAreas[0]; // Assuming you only have 1 chart area on the chart

    double xCoord = ca.AxisX.PixelPositionToValue(e.X);
    double yCoord = ca.AxisY.PixelPositionToValue(e.Y);

    e.Text = "X = " + Math.Round(xCoord, 2).ToString() + "\nY = " + Math.Round(yCoord, 2).ToString();
}