我有一个图表表单,其中有一个图表,但有三个ChartAreas。此外,每个ChartArea都可以显示或不显示,意图至少有一个是可见的。用户还可以调整表单大小,从而导致整个图表的大小调整,但幸运的是没有重新定位;但是,由于调整大小,最大XY范围可能不同。
我希望能够根据鼠标操作在每个ChartArea上执行缩放/取消缩放操作。例如;将鼠标悬停在给定的ChartArea上并使用鼠标滚轮我想缩放/取消缩放。
我不确定如何确定ChartArea的地理位置。例如,我有一个图表,3个ChartAreas,那么它们之间是否会有一些缓冲?我如何确定图表之间的缓冲间距,甚至是属性?同样的问题是我是否有物理图表空间;这些是FastLine图表,因此我有一个X和Y轴,并标有这些图表。此外,数据的值可能会导致X轴标记更大 - 从而将该轴更多地向右移动。
我是否使用Axis(XY).PixelPositionToValue,如果该值<0,那么我不在ChartArea中?
答案 0 :(得分:1)
您可以依靠Chart
事件(由gunr2171建议)和给定的MouseMove
依靠其ChartArea
来定位鼠标在Position
上的位置property(MSDN link)。为了实现您所追求的定位,需要解决各种问题(X从左到右,Y从下到上;相对于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 link和rubber 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();
}
}