how to enable zooming in Microsoft chart control by using Mouse wheel

后端 未结 4 1332
长情又很酷
长情又很酷 2020-12-29 23:11

I am using Microsoft Chart control in my project and I want to enable zooming feature in Chart Control by using Mouse Wheel, how can I achieve this?

but user don\'t

相关标签:
4条回答
  • 2020-12-29 23:15

    I modificated code from above and added a reverse zooming. So when you rotate a mouse wheel back the chart zoom out. Also i don't recommend use 2^n as divider of the interval because it cause lag.

    numberOfZoom - counter of Zooming
    private void Chart1_MouseWheel(object sender, MouseEventArgs e)
        {
            var chart = (Chart)sender;
            var xAxis = chart.ChartAreas[0].AxisX;
            var yAxis = chart.ChartAreas[0].AxisY;
    
            var xMin = xAxis.ScaleView.ViewMinimum;
            var xMax = xAxis.ScaleView.ViewMaximum;
            var yMin = yAxis.ScaleView.ViewMinimum;
            var yMax = yAxis.ScaleView.ViewMaximum;
    
            int IntervalX = 3;
            int IntervalY = 3;
            try
            {
                if (e.Delta < 0 && numberOfZoom > 0) // Scrolled down.
                {
                    var posXStart = xAxis.PixelPositionToValue(e.Location.X) - IntervalX *2/ Math.Pow(2, numberOfZoom);
                    var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + IntervalX *2/ Math.Pow(2, numberOfZoom);
                    var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - IntervalY*2 / Math.Pow(2, numberOfZoom);
                    var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + IntervalY*2 / Math.Pow(2, numberOfZoom);
    
                    if (posXStart < 0) posXStart = 0;
                    if (posYStart < 0) posYStart = 0;
                    if (posYFinish > yAxis.Maximum) posYFinish = yAxis.Maximum;
                    if (posXFinish > xAxis.Maximum) posYFinish = xAxis.Maximum;
                    xAxis.ScaleView.Zoom(posXStart, posXFinish);
                    yAxis.ScaleView.Zoom(posYStart, posYFinish);
                    numberOfZoom--;
                }else if (e.Delta < 0 && numberOfZoom == 0) //Last scrolled dowm
                {
                    yAxis.ScaleView.ZoomReset();
                    xAxis.ScaleView.ZoomReset();
                }
                else if (e.Delta > 0) // Scrolled up.
                {
    
                    var posXStart = xAxis.PixelPositionToValue(e.Location.X) - IntervalX  / Math.Pow(2, numberOfZoom);
                    var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + IntervalX / Math.Pow(2, numberOfZoom);
                    var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - IntervalY  / Math.Pow(2, numberOfZoom);
                    var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + IntervalY  / Math.Pow(2, numberOfZoom);
    
                    xAxis.ScaleView.Zoom(posXStart, posXFinish);
                    yAxis.ScaleView.Zoom(posYStart, posYFinish);
                    numberOfZoom++;
                }
    
                if (numberOfZoom < 0) numberOfZoom = 0;
            }
            catch { }
        }
    
    0 讨论(0)
  • 2020-12-29 23:19

    You'll want to use the MouseWheel event.

    First make both axes of your chart zoomable:

    chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
    chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
    

    And assign the event:

    chart1.MouseWheel += chart1_MouseWheel;
    

    Then in the event handler:

    private void chart1_MouseWheel(object sender, MouseEventArgs e)
    {
        var chart = (Chart)sender;
        var xAxis = chart.ChartAreas[0].AxisX;
        var yAxis = chart.ChartAreas[0].AxisY;
    
        try
        {
            if (e.Delta < 0) // Scrolled down.
            {
                xAxis.ScaleView.ZoomReset();
                yAxis.ScaleView.ZoomReset();
            }
            else if (e.Delta > 0) // Scrolled up.
            {
                var xMin = xAxis.ScaleView.ViewMinimum;
                var xMax = xAxis.ScaleView.ViewMaximum;
                var yMin = yAxis.ScaleView.ViewMinimum;
                var yMax = yAxis.ScaleView.ViewMaximum;
    
                var posXStart = xAxis.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 4;
                var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 4;
                var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 4;
                var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 4;
    
                xAxis.ScaleView.Zoom(posXStart, posXFinish);
                yAxis.ScaleView.Zoom(posYStart, posYFinish);
            }
        }
        catch { }            
    }
    

    The e.Delta property tells you how many wheel "scrolls" you've done, and can be useful.
    Scrolling out at all will zoom out the whole way.

    There's probably a cleaner way of doing this, but there it is. Hope this helps!

    0 讨论(0)
  • 2020-12-29 23:24

    I modificated code from above and added a reverse zooming using Stack.

    private class ZoomFrame
    {
        public double XStart { get; set; }
        public double XFinish { get; set; }
        public double YStart { get; set; }
        public double YFinish { get; set; }
    }
    
    private readonly Stack<ZoomFrame> _zoomFrames = new Stack<ZoomFrame>();
    private void chart1_MouseWheel(object sender, MouseEventArgs e)
    {
        var chart = (Chart)sender;
        var xAxis = chart.ChartAreas[0].AxisX;
        var yAxis = chart.ChartAreas[0].AxisY;
    
        try
        {
            if (e.Delta < 0)
            {
                if (0 < _zoomFrames.Count)
                {
                    var frame = _zoomFrames.Pop();
                    if (_zoomFrames.Count == 0)
                    {
                        xAxis.ScaleView.ZoomReset();
                        yAxis.ScaleView.ZoomReset();
                    }
                    else
                    {
                        xAxis.ScaleView.Zoom(frame.XStart, frame.XFinish);
                        yAxis.ScaleView.Zoom(frame.YStart, frame.YFinish);
                    }
                }
            }
            else if (e.Delta > 0)
            {
                var xMin = xAxis.ScaleView.ViewMinimum;
                var xMax = xAxis.ScaleView.ViewMaximum;
                var yMin = yAxis.ScaleView.ViewMinimum;
                var yMax = yAxis.ScaleView.ViewMaximum;
    
                _zoomFrames.Push(new ZoomFrame { XStart = xMin, XFinish = xMax, YStart = yMin, YFinish = yMax });
    
                var posXStart = xAxis.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 4;
                var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 4;
                var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 4;
                var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 4;
    
                xAxis.ScaleView.Zoom(posXStart, posXFinish);
                yAxis.ScaleView.Zoom(posYStart, posYFinish);
            }
        }
        catch { }         
    }
    

    Hope this helps!

    0 讨论(0)
  • 2020-12-29 23:32

    Waaaay late to the party, but I had this challenge myself today. I am sure the following can be improved, still, but it's what I came up with. I tested this with .net 4.5.2 and 4.6, so I am not sure if it works with older frameworks.

    I've combined a couple of answers from way in the past and made the following:

    using System;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;
    
    namespace ExampleApp
    {
        public partial class Form1 : Form
        {
            private const float CZoomScale = 4f;
            private int FZoomLevel = 0;
    
            public Form1()
            {
                InitializeComponent();
                chart1.MouseWheel += Chart1_MouseWheel;
            }
    
            private void Chart1_MouseEnter(object sender, EventArgs e)
            {
                if (!chart1.Focused)
                    chart1.Focus();
            }
    
            private void Chart1_MouseLeave(object sender, EventArgs e)
            {
                if (chart1.Focused)
                    chart1.Parent.Focus();
            }
    
            private void Chart1_MouseWheel(object sender, MouseEventArgs e)
            {
                try {
                    Axis xAxis = chart1.ChartAreas[0].AxisX;
                    double xMin = xAxis.ScaleView.ViewMinimum;
                    double xMax = xAxis.ScaleView.ViewMaximum;
                    double xPixelPos = xAxis.PixelPositionToValue(e.Location.X);
    
                    if (e.Delta < 0 && FZoomLevel > 0) {
                        // Scrolled down, meaning zoom out
                        if (--FZoomLevel <= 0) {
                            FZoomLevel = 0;
                            xAxis.ScaleView.ZoomReset();
                        } else {
                            double xStartPos = Math.Max(xPixelPos - (xPixelPos - xMin) * CZoomScale, 0);
                            double xEndPos = Math.Min(xStartPos + (xMax - xMin) * CZoomScale, xAxis.Maximum);
                            xAxis.ScaleView.Zoom(xStartPos, xEndPos);
                        }
                    } else if (e.Delta > 0) {
                        // Scrolled up, meaning zoom in
                        double xStartPos = Math.Max(xPixelPos - (xPixelPos - xMin) / CZoomScale, 0);
                        double xEndPos = Math.Min(xStartPos + (xMax - xMin) / CZoomScale, xAxis.Maximum);
                        xAxis.ScaleView.Zoom(xStartPos, xEndPos);
                        FZoomLevel++;
                    }
                } catch { }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题