[英]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.