我将在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轴的线点上画圆,并将此数据显示在标签上
答案 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;
}
让我们看看它在工作: