我在Windows表单图形上有一个有效的鼠标单击事件,现在我想在每次单击上添加数据点,以使其在图形上的单击位置可见。在第3次点击时,前2次将清除,而第3次和第4次点击将具有自己的新数据点,依此类推(一次显示2个数据点以显示开始和停止位置,并且计算之间的差/差那些位置。
我当前的代码如下:
private void chart1_MouseClick(object sender, MouseEventArgs e)
{
HitTestResult result = chart1.HitTest(e.X, e.Y);
if (result.PointIndex >= 0)
{
if (diffCounter == 0)
{
xOne = result.Series.Points[result.PointIndex].YValues[0];
diffCounter++;
//Console.WriteLine("VALY " + xOne);
}
else if (diffCounter == 1)
{
xTwo = result.Series.Points[result.PointIndex].YValues[0];
diffCounter = 0;
//Console.WriteLine("Delta = " + Math.Round(Math.Abs(xTwo - xOne)), 2);
pointDifferenceTextBox.Text = Math.Round((Math.Abs(xTwo - xOne)), 2).ToString();
}
}
}
根据在折线图(或与此相关的任何图表)上执行点击测试的位置,我找不到任何有关添加数据点的信息。
差异Counter
只是int
,用于确定是第一次还是第二次点击。
xOne
用于获取第一个点击的y值,xTwo
是获取第二个点击的y值。
编辑:我想根据执行点击测试的位置创建一个圆形数据点。
答案 0 :(得分:0)
原始帖子要求在点击的位置添加DataPoint
。为此HitTest
没有用。
相反,您需要axis functions其中之一; PixelPositionToValue
会将像素位置转换为轴值 ..:
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
double x = ax.PixelPositionToValue(e.X);
double y = ay.PixelPositionToValue(e.Y);
DataPoint dp = new DataPoint(x, y);
dp.Color = Color.Red;
chart1.Series[0].Points.Add(dp);
请注意,这些功能仅在绘画之一或鼠标事件之一中仅有效!
答案 1 :(得分:0)
由于帖子已更改,因此似乎有必要提供新答案。
这里是如何在Paint
事件中创建两个要绘制的点。
首先我们需要存储它们:
PointF p1 = PointNull;
PointF p2 = PointNull;
要标记状态,我们还使用静态值:
static PointF PointNull = new PointF(-123f, -123f);
您也可以使用其他标志来控制第一点和第二点之间的切换。
接下来,我们需要在click中存储值:
private void chart1_MouseClick(object sender, MouseEventArgs e)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
double x = ax.PixelPositionToValue(e.X);
double y = ay.PixelPositionToValue(e.Y);
y = GetMedianYValue(chart1.Series[0], x);
if (p1 == PointNull ||(p1 != PointNull && p2 != PointNull))
{
p1 = new PointF((float)x, (float)y);
p2 = PointNull;
}
else
{
p2 = new PointF((float)x, (float)y);
}
// values have changed, trigger drawing them!
chart1.Invalidate();
}
请注意,我首先使用轴功能来获取单击位置的轴值。然后,我用一个计算直线上点的函数覆盖y值。
double GetMedianYValue(Series s, double xval )
{
// Findclosest datapoints:
DataPoint dp1 = s.Points.Where(x => x.XValue <= xval).LastOrDefault();
DataPoint dp2 = s.Points.Where(x => x.XValue >= xval).FirstOrDefault();
// optional
dp1.MarkerStyle = MarkerStyle.Circle;
dp1.MarkerColor = Color.Purple;
dp2.MarkerStyle = MarkerStyle.Circle;
dp2.MarkerColor = Color.Violet;
double dx = dp2.XValue - dp1.XValue;
double dy = dp2.YValues[0] - dp1.YValues[0];
// same point
if (dx == 0) return dp1.YValues[0];
// calculate median
double d = dp1.YValues[0] + dy / dx * ( xval - dp1.XValue) ;
return d;
}
请注意,此功能标记仅用于测试的相邻数据点!
最后我们需要画两点:
private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
int x1 = (int)ax.ValueToPixelPosition(p1.X);
int y1 = (int)ay.ValueToPixelPosition(p1.Y);
int x2 = (int)ax.ValueToPixelPosition(p2.X);
int y2 = (int)ay.ValueToPixelPosition(p2.Y);
if (x1 >= 0 && x1 < chart1.Width) // sanity check
if (p1 != PointNull)
e.ChartGraphics.Graphics.DrawEllipse(Pens.LightSeaGreen, x1 - 3, y1 - 3, 6, 6);
if (x2 >= 0 && x2 < chart1.Width) // sanity check
if (p2 != PointNull)
e.ChartGraphics.Graphics.DrawEllipse(Pens.Red, x2 - 3, y2 - 3, 6, 6);
}
这是结果: