3

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

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

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

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

4

2 回答 2

1

Chart您可以通过依赖MouseMove事件(如 gunr2171 所建议的)和ChartArea通过依赖其Position属性(MSDN 链接)给出的来定位鼠标的位置。为了提供您所追求的定位类型,需要解决各种问题(X 从左到右,Y 从下到上;相对于 ChartArea 给出的框架):

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

首先是计算最大值/最小值。定义给定 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 提供了一个有趣的链接来确定鼠标是否在某个 ChartArea 内。它可能会取代chart1_MouseMove方法上的条件,尽管不是在不同参考系统(图表和 ChartArea 系统)之间移动所需的最小/最大值、X/Y 计算。在任何情况下,您都必须确保此函数所期望的确切输入(在提供的链接中没有明确解释),记住涉及 3 个不同的参考系统(全局系统、图表系统和ChartArea 之一)。在这种情况下,我更喜欢“手动”执行整个计算,以避免在使用不同的参考系统时出现兼容性问题。

于 2013-09-04T21:45:51.900 回答
1

我参加聚会有点晚了,但我也遇到了这个问题。有趣的链接橡皮筋矩形的组合被证明是我的最佳解决方案。完整的解决方案允许用户在他们想要放大的区域周围绘制一个橡皮筋矩形。如果矩形超出图表区域或跨越多个图表区域,则会取消缩放。如果鼠标按下和鼠标抬起之间的经过时间小于双击时间,则忽略缩放。在这种情况下,双击会重置缩放。

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();
    }
}
于 2018-11-29T03:21:51.343 回答