簡體   English   中英

如何使用鼠標滾輪在 Microsoft 圖表控件中啟用縮放

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

我在我的項目中使用 Microsoft Chart 控件,我想通過使用鼠標滾輪在 Chart Control 中啟用縮放功能,我該如何實現?

但是用戶不必單擊圖表,應該就像鼠標位置在我的圖表上一樣,而不是從該點開始通過鼠標滾輪滾動它可以放大/縮小

您將需要使用MouseWheel事件。

首先使圖表的兩個軸均可縮放:

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

並分配事件:

chart1.MouseWheel += chart1_MouseWheel;

然后在事件處理程序中:

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 { }            
}

e.Delta屬性會告訴您已經完成了多少輪“滾動”,並且很有用。
完全滾動將縮小整個過程。

可能有一種更清潔的方法來做到這一點,但它就是這樣。 希望這可以幫助!

我從上面修改了代碼並添加了反向縮放。 因此,當您向后旋轉鼠標滾輪時,圖表會縮小。 另外我不建議使用 2^n 作為間隔的分隔符,因為它會導致滯后。

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 { }
    }

聚會遲到了,但我今天自己也遇到了這個挑戰。 我相信以下內容仍然可以改進,但這是我想出的。 我用 .net 4.5.2 和 4.6 對此進行了測試,所以我不確定它是否適用於舊框架。

我結合了過去的幾個答案,並提出了以下幾點:

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 { }
        }
    }
}

我修改了上面的代碼並使用 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 { }         
}

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM