我使用圆形标记来指示数据点的位置。当在轴上绘制点时,我无法选择它们(使用HitTest)......但是当我们在图表上的任何其他位置绘制它们时,我可以选择它们。不可选择的点似乎是在轴下绘制的。如果我将标记放大,我可以通过单击圆的边缘来选择轴上的点。
有没有办法让标记在轴上绘制(如果这是问题!)?
这是一个非常好的问题。
问题确实是真实的我不知道一个简单的解决方案。
当你发现你已经击中了X
或者Axis
或者AxisLabel
时,你可以修改你测试的TickMark
。计算轴上的镜像位置偏移其宽度并再次测试。
为此,您需要知道轴位置(以像素为单位)及其宽度。
后者是axis.Linewidth
。对于前者使用轴函数ax.ValueToPixelPosition
。它取y轴位置的x值。这将是x轴'最小值(如果已设置)或0
或某个自动值,具体取决于您的数据。
这确实改善了这种情况,虽然我发现TickMarks仍然倾向于妨碍,不知道为什么。
如果鼠标真正靠近,用户会喜欢,直到它们再次消失为止。您可以使用反向函数PixelPositionToValue
和一些Linq来找到最近的点。
更新:
这是一个函数的例子,可以找到最近的点,可能在MouseMove
事件中,或者可能在HitTest
击中轴或轴元素后...:
DataPoint GetNearestPoint(Series s, ChartArea ca, Point pt)
{
int limit = s.MarkerSize * 4; // pick a suitable distance!
Axis ay = ca.AxisY;
Axis ax = ca.AxisX;
var mins = s.Points.Cast<DataPoint>().Select((x, index) =>
new
{
val = Math.Abs(pt.Y - (int)ay.ValueToPixelPosition(x.YValues[0]))
+ Math.Abs(pt.X - (int)ax.ValueToPixelPosition(x.XValue)),
ix = index
});
var min = mins.Where(x => x.val == mins.Min(v => v.val)).Select(x => x.ix).First();
if (mins.ElementAt(min).val > limit) return null;
else return s.Points[min];
}
以下是我在创建类级变量后调用它的方法:
DataPoint lastHit = null;
当光标足够接近时,它会为最近的点着色..:
var nearest = GetNearestPoint(someSeries, someChart.ChartAreas[0], e.Location);
if (lastHit != null) lastHit.MarkerColor = someSeries.Color;
if (nearest != null)
{
lastHit = nearest;
nearest.MarkerColor = Color.Red;
}
扩大MarkerSize
当然也是如此简单(至少除非你的ChartType
是Bubble
,因为我的;-)
ElementPositions
和它的InnerPlotPosition
然后用它们作为叠加。现在你可以把系列移动到第二,上面的ChartArea
,并将其Axis
等关闭.. HitTest
应该按预期工作。但每次调整大小时都需要调整头寸。