Search code examples
c#winformsmschart

MS Chart Control: prevent zoom when clicking


I'm using a MS Chart Control that sets a cursor when the chart is clicked and that enables the user to zoom in and out. When the user tries to click into the chart it accidentally happens that he drags a very small zoom rectangle and the chart zooms in instead of handling the click.

What can be done to prevent zooming in when trying to click? Is there something like a minimum rectangle size for zooming?

Here's how I handle the click:

_area = new ChartArea();

private void chart1_MouseClick(object sender, MouseEventArgs e) 
{
    try 
    {
        _area.CursorX.SetCursorPixelPosition(new Point(e.X, e.Y), true);
    }
    catch (Exception ex) 
    { 

    }
}

And this is how I setup the zoom and cursor settings:

_area.AxisX.ScaleView.Zoomable = true;
_area.CursorX.IsUserSelectionEnabled = true;
_area.CursorX.IntervalType = DateTimeIntervalType.Seconds;
_area.CursorX.Interval = 1D;
_area.CursorY.IsUserSelectionEnabled = true;
_area.CursorY.Interval = 0;

Solution

  • Based on @Baddack's answer here's a complete solution. The key is to disable the zoom feature of the chart and zoom manually (like Baddack suggested) by using MouseUp/MouseDown events. The user selection feature of the chart is kept enabled to use the selection rectangle for setting the zoom interval.

    This sample code checks if the zoom retangle is at least 10 pixels wide and high. Only if that's the case the zoom is initiated:

    private ChartArea _area;
    private Point _chartMouseDownLocation;
    ...
    
    private void MainForm_Load(object sender, EventArgs e)
    {
        ...
        // Disable zooming by chart control because zoom is initiated by MouseUp event
        _area.AxisX.ScaleView.Zoomable = false;
        _area.AxisY.ScaleView.Zoomable = false;
    
        // Enable user selection to get the interval/rectangle of the selection for 
        // determining the interval for zooming
        _area.CursorX.IsUserSelectionEnabled = true;
        _area.CursorX.IntervalType = DateTimeIntervalType.Seconds;
        _area.CursorX.Interval = 1D;
        _area.CursorY.IsUserSelectionEnabled = true;
        _area.CursorY.Interval = 0;        
    }
    
    private void chart1_MouseDown(object sender, MouseEventArgs e)
    {
        _chartMouseDownLocation = e.Location;
    }
    
    private void chart1_MouseUp(object sender, MouseEventArgs e)
    {
        // Check if rectangle has at least 10 pixels with and hright
        if (Math.Abs(e.Location.X - _chartMouseDownLocation.X) > 10 && 
            Math.Abs(e.Location.Y - _chartMouseDownLocation.Y) > 10)
        {
            // Zoom to the Selection rectangle
            _area.AxisX.ScaleView.Zoom(
                Math.Min(_area.CursorX.SelectionStart, _area.CursorX.SelectionEnd),
                Math.Max(_area.CursorX.SelectionStart, _area.CursorX.SelectionEnd)
            );
            _area.AxisY.ScaleView.Zoom(
                Math.Min(_area.CursorY.SelectionStart, _area.CursorY.SelectionEnd),
                Math.Max(_area.CursorY.SelectionStart, _area.CursorY.SelectionEnd)
            );
        }
        // Reset/hide the selection rectangle
        _area.CursorX.SetSelectionPosition(0D, 0D);
        _area.CursorY.SetSelectionPosition(0D, 0D);
    }