MSCharts自定义平移

我正在尝试在MSCharts(Microsoft Charting Controls)中创建自己的自定义平移function。 我意识到有一个扩展用于缩放和平移,但是它没有很多我想要的function。 这是我目前的平移function:

//handles mouse panning, will pan while mouse left click if held down.. private int prevx = 0; private int prevy = 0; private void Mouse_Up(object sender, MouseEventArgs e) { //reset previous x and y on mouse click up if (e.Button == MouseButtons.Left) { prevx = 0; prevy = 0; } } private void Mouse_Move(object sender, MouseEventArgs e, Chart chart) { //if mouse was moved and mouse left click if (e.Button == MouseButtons.Left) { //a scalar, not entirely sure how useful it is, only works for my viewport double incr = 0.00130; if (prevx != 0 && prevy != 0) { //find x and y difference in mouse movement int diffx = eX - prevx; int diffy = eY - prevy; //how much to increment x and y double incrx = incr * Math.Abs(diffx); double incry = incr * Math.Abs(diffy); //get chart mins and maxs for both axes double minX = chart.ChartAreas[0].AxisX.Minimum; double maxX = chart.ChartAreas[0].AxisX.Maximum; double minY = chart.ChartAreas[0].AxisY.Minimum; double maxY = chart.ChartAreas[0].AxisY.Maximum; if (diffx > 0 && diffy > 0) { chart.ChartAreas[0].AxisX.Minimum -= (maxX - minX) * incrx; chart.ChartAreas[0].AxisX.Maximum -= (maxX - minX) * incrx; chart.ChartAreas[0].AxisY.Minimum += (maxY - minY) * incry; chart.ChartAreas[0].AxisY.Maximum += (maxY - minY) * incry; //Console.WriteLine("upleft"); } else if (diffx  0) { chart.ChartAreas[0].AxisX.Minimum += (maxX - minX) * incrx; chart.ChartAreas[0].AxisX.Maximum += (maxX - minX) * incrx; chart.ChartAreas[0].AxisY.Minimum += (maxY - minY) * incry; chart.ChartAreas[0].AxisY.Maximum += (maxY - minY) * incry; //Console.WriteLine("upright"); } else if (diffx > 0 && diffy < 0) { chart.ChartAreas[0].AxisX.Minimum -= (maxX - minX) * incrx; chart.ChartAreas[0].AxisX.Maximum -= (maxX - minX) * incrx; chart.ChartAreas[0].AxisY.Minimum -= (maxY - minY) * incry; chart.ChartAreas[0].AxisY.Maximum -= (maxY - minY) * incry; //Console.WriteLine("bottom left"); } else if (diffx < 0 && diffy  0 && diffy == 0) { chart.ChartAreas[0].AxisX.Minimum -= (maxX - minX) * incrx; chart.ChartAreas[0].AxisX.Maximum -= (maxX - minX) * incrx; //Console.WriteLine("right"); } else if (diffx  0 && diffx == 0) { chart.ChartAreas[0].AxisY.Minimum += (maxY - minY) * incry; chart.ChartAreas[0].AxisY.Maximum += (maxY - minY) * incry; //Console.WriteLine("down"); } else if (diffy < 0 && diffx == 0) { chart.ChartAreas[0].AxisY.Minimum -= (maxY - minY) * incry; chart.ChartAreas[0].AxisY.Maximum -= (maxY - minY) * incry; //Console.WriteLine("up"); } } prevx = eX; prevy = eY; } } 

我注意到有一个类似的问题,虽然它是在JavaFX中,我没有经验。我设想的平移function应该能够用图形移动鼠标。 因此,如果我点击某个点,向左拖动50px,那么相同的点仍然会直接在我的鼠标下面。 在我当前的视口中,这是有效的。 但是,如果我使图表变小或变大,则事情不起作用。 当图形变小时,图形比我的鼠标移动得慢,当图形变大时,图形比鼠标移动得更快。

我知道我应该以某种方式将视口或图表宽度包含在计算中,但我真的不知道如何。 你们有没有这方面的经验? 谢谢。

你很怀疑通过因子来计算像素值的“标量”方法。 这将永远不会工作,原因不止一个..

但无论如何,正确的解决方案要简单得多。 它利用其中一个轴转换函数在数据值和像素位置之间进行转换。 (也有一个转换为百分比位置,顺便说一句..)

我存储初始位置以避免在鼠标移动过程中出现舍入错误:

 private double prevXMax = 0; private double prevXMin = 0; private double prevYMax = 0; private double prevYMin = 0; private Point mDown = Point.Empty; 

我们现在需要的只是Mousedown

 private void chart_MouseDown(object sender, MouseEventArgs e) { //store previous data if (e.Button == MouseButtons.Left) { mDown = e.Location; prevXMax = chart.ChartAreas[0].AxisX.Maximum; prevXMin = chart.ChartAreas[0].AxisX.Minimum; prevYMax = chart.ChartAreas[0].AxisY.Maximum; prevYMin = chart.ChartAreas[0].AxisY.Minimum; } } 

更简单的MouseMove

 private void chart_MouseMove(object sender, MouseEventArgs e) { Axis ax = chart.ChartAreas[0].AxisX; Axis ay = chart.ChartAreas[0].AxisY; //if mouse was moved and mouse left click if (e.Button == MouseButtons.Left) { double x0 = ax.PixelPositionToValue(mDown.X); double x1 = ax.PixelPositionToValue(eX); double y0 = ay.PixelPositionToValue(mDown.Y); double y1 = ay.PixelPositionToValue(eY); ax.Minimum = prevXMin + (x0 - x1); ax.Maximum = prevXMax + (x0 - x1); ay.Minimum = prevYMin + (y0 - y1); ay.Maximum = prevYMax + (y0 - y1); } } 

缩放计算的一个问题是您可能想要调整图表的大小; 之后,规模将不再有效。 另一个是你必须取出ChartArea之外的东西,以及InnerPlotPosition ,即Axis.LabelsTitlesLegend因为它们占用的空间不应该缩放。

请注意,轴function仅在PaintxxxMousexxx事件期间有效。

结果如下:

在此处输入图像描述