[英].NET Charting - Zooming a chart by dragging the X-Axis
I'm trying to implement chart zooming using .NET charting by dragging a value on the X Axis to the right and then dropping it to a new location. 我正在尝试使用.NET图表来实现图表缩放,方法是将X轴上的值拖到右侧,然后将其放到新位置。 It kind of working but I have some problems.
它有点工作,但我有一些问题。 Here is my code:
这是我的代码:
public partial class ChartForm : Form
{
public ChartForm()
{
InitializeComponent();
}
private Axis AxisX { get; set; }
private double InitialAxisValue { get; set; }
protected override void OnLoad(EventArgs e)
{
chart1.Series.Add(CreateDataSeries());
AxisX = chart1.ChartAreas[0].AxisX;
InitialAxisValue = double.NaN;
chart1.MouseMove += OnChartMouseMove;
chart1.MouseDown += OnChartMouseDown;
chart1.MouseUp += OnChartMouseUp;
}
private static Series CreateDataSeries()
{
var dataSeries = new Series
{
ChartType = SeriesChartType.Line,
};
for (double spotPrice = 1100; spotPrice < 1300; spotPrice++)
{
dataSeries.Points.Add(new DataPoint(spotPrice, spotPrice));
}
return dataSeries;
}
private void OnChartMouseUp(object sender, MouseEventArgs e)
{
InitialAxisValue = double.NaN;
}
private void OnChartMouseDown(object sender, MouseEventArgs e)
{
if (!MouseOnXAxis(e.X, e.Y))
return;
double valueX = AxisX.PixelPositionToValue(e.X);
InitialAxisValue = valueX;
}
private void OnChartMouseMove(object sender, MouseEventArgs e)
{
try
{
Cursor = MouseOnXAxis(e.X, e.Y) ? Cursors.Hand : Cursors.Default;
HandleZoom(e);
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private void HandleZoom(MouseEventArgs e)
{
if (double.IsNaN(InitialAxisValue))
return;
AxisX.Maximum = GetNewAxisMaximumValue(e.X, InitialAxisValue);
}
private double GetNewAxisMaximumValue(double currentAxisCoordinate,
double initialAxisZoomPointValue)
{
double axisMinimumValue = AxisX.Minimum;
double axisMaximumValue = AxisX.Maximum;
double axisMinimumCoordinate = AxisX.ValueToPixelPosition(axisMinimumValue);
double axisMaximumCoordinate = AxisX.ValueToPixelPosition(axisMaximumValue);
double relativePos = (currentAxisCoordinate - axisMinimumCoordinate) /
(axisMaximumCoordinate - axisMinimumCoordinate);
double newAxisWidth = ((initialAxisZoomPointValue - axisMinimumValue)/relativePos);
return axisMinimumValue + newAxisWidth;
}
private bool MouseOnXAxis(int xCoor, int yCoor)
{
HitTestResult hitTestResult = chart1.HitTest(xCoor, yCoor);
return hitTestResult.ChartElementType == ChartElementType.AxisLabels &&
hitTestResult.Axis == AxisX;
}
}
The actual zooming effect occurs by chaging the maximum value of AxisX in HandleZoom(): 通过在HandleZoom()中查找AxisX的最大值来实现实际的缩放效果:
AxisX.Maximum = GetNewAxisMaximumValue(e.X, InitialAxisValue);
where 'InitialAxisValue' is the initial dragging value and 'eX' is the current mouse x axis coordinate. 其中'InitialAxisValue'是初始拖动值,'eX'是当前鼠标x轴坐标。
It works but I have a problem: sometimes the dragging movement is not smooth and sometimes there are back and forth undesired movements / blinks in the chart / grid (you can easily see it by dragging the mouse slowly to the right). 它有效,但我有一个问题:有时拖动动作不平滑,有时在图表/网格中有来回不希望的动作/闪烁(你可以通过慢慢向右拖动鼠标来看到它)。
The problem is probably in the implementation of HandleZoom() and GetNewAxisMaximumValue(). 问题可能在于HandleZoom()和GetNewAxisMaximumValue()的实现。
Any help would be great. 任何帮助都会很棒。
Thanks 谢谢
Solved ! 解决了 !
My zoom calculation is based on an assumption that the X axis width in pixels is fixed and apparently when the InnerPlotPosition property is set to TRUE, the X Axis width in pixel may change during runtime, for example while zooming. 我的缩放计算基于以下假设:X轴宽度(以像素为单位)是固定的,显然当InnerPlotPosition属性设置为TRUE时,像素中的X轴宽度可能会在运行时更改,例如在缩放时。
So the solution is to set the InnerPlotPosition property to FALSE and set the inner plot area manually: 所以解决方案是将InnerPlotPosition属性设置为FALSE并手动设置内部绘图区域:
chart1.ChartAreas[0].InnerPlotPosition.Auto = false;
chart1.ChartAreas[0].InnerPlotPosition.Height = 80.29209F;
chart1.ChartAreas[0].InnerPlotPosition.Width = 85F;
chart1.ChartAreas[0].InnerPlotPosition.X = 15F;
chart1.ChartAreas[0].InnerPlotPosition.Y = 5.07246F;
我可以看到你已经解决了缩放功能,但为什么不使用内置的.net图表缩放选项?
chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
图控制上的“DoubleBuffer = true”有帮助吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.