轴绘制点并阻止DataVisualization.Charting中的选择

问题描述 投票:3回答:1

我使用圆形标记来指示数据点的位置。当在轴上绘制点时,我无法选择它们(使用HitTest)......但是当我们在图表上的任何其他位置绘制它们时,我可以选择它们。不可选择的点似乎是在轴下绘制的。如果我将标记放大,我可以通过单击圆的边缘来选择轴上的点。

有没有办法让标记在轴上绘制(如果这是问题!)?

enter image description here

c# mschart
1个回答
2
投票

这是一个非常好的问题。

问题确实是真实的我不知道一个简单的解决方案。

  • 这是一个可能的解决方法:

当你发现你已经击中了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当然也是如此简单(至少除非你的ChartTypeBubble,因为我的;-)

enter image description here

  • 另一种解决方法是相当混乱:你可以添加一个额外的ChartArea并将其覆盖在原始的一个上。你必须得到原始的ElementPositions和它的InnerPlotPosition然后用它们作为叠加。现在你可以把系列移动到第二,上面的ChartArea,并将其Axis等关闭.. HitTest应该按预期工作。但每次调整大小时都需要调整头寸。
© www.soinside.com 2019 - 2024. All rights reserved.