How to zoom from a point
for example zoom from point 300 to 500 axisX and 50 to 100 AxisY step by step
Current location
private void chart1_MouseClick(object sender, MouseEventArgs e) {
lastPoint = e.Location;
}
Zooming X And Y
private void btnZoomXY_Click(object sender, EventArgs e)
{
step = (int)(chart1.ChartAreas["ChartArea1"].AxisX.Maximum - lastPoint.X ) / 20;
if (zoomx > chart1.ChartAreas["ChartArea1"].AxisX.Maximum)
{
zoomx -= step;
}
else
zoomx += step;
this.chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Zoom(lastPoint.X+ zoomx, this.chart1.ChartAreas["ChartArea1"].AxisX.Maximum - zoomx);
if (Mode == SpectometrMode.Absorbance)
{
step1 = 0.2f;
}
else
step1 = (int)(chart1.ChartAreas["ChartArea1"].AxisY.Maximum - lastPoint.Y) / 20;
if (zoomY > chart1.ChartAreas["ChartArea1"].AxisY.Maximum)
{
zoomY -= step1;
}
else
zoomY += step1;
this.chart1.ChartAreas["ChartArea1"].AxisY.ScaleView.Zoom(lastPoint.Y+ zoomY, this.chart1.ChartAreas["ChartArea1"].AxisY.Maximum - zoomY);
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "{0}";
}
@taW
Here is a solution that will zoom in 2x with each click.
It uses a variable span
as the range of values that will be visible in the zoomed view.
It also moves the clicked position to the next closest DataPoint
. You may remove this to allow zooming in on positions between DataPoints
.
Let's see it in action:
Note that the first issue with your code is the coordinates you use.
These are three (!) coordinate systems in MSChart
:
MouseClick
Axis
valuesElementPositions
i.e. percentages related to the next higher containerYour main issue is that you mix pixels with values which will result in chaos.
You need to convert the pixels to values as in the code shown.
Here are the variables I use:
double span = 0; // axis range in values
Point lastPoint = Point.Empty; // the clicked position
PointF clickedValues = PointF.Empty; // the values of the clicked positiom
DataPoint closePoint = null; // the next closest DataPoint
Now the click code with the conversion:
private void chart1_MouseClick(object sender, MouseEventArgs e)
{
lastPoint = e.Location;
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
if (closePoint != null) closePoint.MarkerColor = chart1.Series[0].MarkerColor;
clickedValues = new PointF((float)ax.PixelPositionToValue(lastPoint.X),
(float)ay.PixelPositionToValue(lastPoint.Y));
closePoint = chart1.Series[0].Points.Where(x => x.XValue >= clickedValues .X).First();
closePoint.MarkerColor = Color.Red; // optionally mark the point
// optionally move clicked position to actual datapoint
nextDPoint = new PointF((float)closePoint.XValue, (float)closePoint.YValues[0]);
span = ax.Maximum - ax.Minimum; // the full range of values
}
Finally the code for the zoom-in button:
private void button1_Click(object sender, EventArgs e)
{
span /= 2; // zoom in 2x each time
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
ax.ScaleView.Zoom(nextDPoint.X - span, nextDPoint.X + span);
}
A few notes:
PointF
to store the clicked values. Usually floats
will do; this may not be true if the values are DateTime
, though. In such a case do use two doubles
!Axis
into variables. I usually do the same with Series
and ChartAreas
. Much easier to write, read and I think even (a little) faster to run.. .