检测ChartArea中是否有鼠标

时间:2013-09-04 20:29:00

标签: c# mschart

我有一个图表表单,其中有一个图表,但有三个ChartAreas。此外,每个ChartArea都可以显示或不显示,意图至少有一个是可见的。用户还可以调整表单大小,从而导致整个图表的大小调整,但幸运的是没有重新定位;但是,由于调整大小,最大XY范围可能不同。

我希望能够根据鼠标操作在每个ChartArea上执行缩放/取消缩放操作。例如;将鼠标悬停在给定的ChartArea上并使用鼠标滚轮我想缩放/取消缩放。

我不确定如何确定ChartArea的地理位置。例如,我有一个图表,3个ChartAreas,那么它们之间是否会有一些缓冲?我如何确定图表之间的缓冲间距,甚至是属性?同样的问题是我是否有物理图表空间;这些是FastLine图表,因此我有一个X和Y轴,并标有这些图表。此外,数据的值可能会导致X轴标记更大 - 从而将该轴更多地向右移动。

我是否使用Axis(XY).PixelPositionToValue,如果该值<0,那么我不在ChartArea中?

2 个答案:

答案 0 :(得分:1)

您可以依靠Chart事件(由gunr2171建议)和给定的MouseMove依靠其ChartArea来定位鼠标在Position上的位置property(MSDN link)。为了实现您所追求的定位,需要解决各种问题(X从左到右,Y从下到上;相对于ChartArea给出的框架):

  • 更正Y值,将“反向”提供(从顶部(0) 到底(高度))。
  • 确定给定的坐标(参见图表)是否在给定的ChartArea中。
  • 将图表参考系统中的坐标转换为ChartArea参考系统。

首先是计算max./min。定义给定ChartArea的值:

int minX1, minY1, maxX1, maxY1;
minX1 = (int)chart1.ChartAreas[0].Position.X;
maxX1 = (int)(chart1.ChartAreas[0].Position.X + chart1.ChartAreas[0].Position.Width * chart1.Width /100);
minY1 = (int)chart1.ChartAreas[0].Position.Y;
maxY1 = (int)(chart1.ChartAreas[0].Position.Y + chart1.ChartAreas[0].Position.Height * chart1.Height/100);

在给定图表的MouseMove事件中:

private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    Point posChart = new Point(e.X, e.Y); //Position of the mouse respect to the chart
    if (posChart.X >= minX1 && posChart.X <= maxX1 && posChart.Y >= minY1 && posChart.Y <= maxY1)
    {
        //The mouse is inside the given area
        //Conversion of the mouse position to the ChartArea reference system, with the corresponding "inversion" of the Y values
        Point posChartArea = new Point(posChart.X - minX1, Math.Abs((posChart.Y - minY1) - maxY1));
    }
}

注意:Hans Passant提供interesting link来确定鼠标是否在某个ChartArea中。它可能会替换chart1_MouseMove方法上的条件,尽管不是最小/最大,X / Y计算在不同的参考系统(Chart和ChartArea)之间移动所需要的。在任何情况下,你必须确保这个功能所期望的确切输入(在提供的链接中没有明确解释),记住涉及3个不同的参考系统(全局的,图表和ChartArea之一)。在这种情况下,我更喜欢“手动”执行整个计算,以避免在使用不同的参考系统时出现兼容性问题。

答案 1 :(得分:0)

我参加聚会有点晚了,但是我也遇到了这个问题。 interesting linkrubber band rectangle 的组合被证明是对我来说最好的解决方案。完整的解决方案允许用户在要放大的区域周围绘制橡皮筋矩形。如果矩形超出了图表区域,或者跨越了多个图表区域,则取消缩放。如果鼠标下移和鼠标上移之间的经过时间小于双击时间,则忽略缩放。在这种情况下,双击将重置缩放。

OP只是要求一种通过单击鼠标来获取图表区域的方法,因此我将仅显示该代码段。给我发消息,如果您需要完整的解决方案。

private Point mouseDown = Point.Empty;
private Stopwatch clickTimer = null;
private ChartArea chartAreaToZoom = null;

private void chart1_MouseDown(object sender, MouseEventArgs e)
{
    HitTestResult result = chart1.HitTest(e.X, e.Y);
    if (result.ChartArea != null)
    {
        chartAreaToZoom = result.ChartArea;
        mouseDown = e.Location;
        clickTimer = Stopwatch.StartNew();
    }
}