C# 如何使用鼠标滚轮在 Microsoft 图表控件中启用缩放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13584061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to enable zooming in Microsoft chart control by using Mouse wheel
提问by yogendra
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?
我在我的项目中使用 Microsoft Chart 控件,我想通过使用鼠标滚轮在 Chart Control 中启用缩放功能,我该如何实现?
but user don't have to click on chart, It should be like if mouse position is on my Chart than from that point onward by mouse wheel rolling it can zoom in / out
但是用户不必单击图表,应该就像鼠标位置在我的图表上一样,而不是从该点开始通过鼠标滚轮滚动它可以放大/缩小
回答by tmwoods
You'll want to use the MouseWheelevent.
你会想要使用这个MouseWheel事件。
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.Deltaproperty tells you how many wheel "scrolls" you've done, and can be useful.
Scrolling out at all will zoom out the whole way.
该e.Delta属性会告诉您已经完成了多少轮“滚动”,并且很有用。
完全滚动将缩小整个过程。
There's probably a cleaner way of doing this, but there it is. Hope this helps!
可能有一种更清洁的方法来做到这一点,但它就是这样。希望这可以帮助!
回答by user3857680
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.
我从上面修改了代码并添加了反向缩放。因此,当您向后旋转鼠标滚轮时,图表会缩小。另外我不建议使用 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 { }
}
回答by Thimo Braker
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.
聚会迟到了,但我今天自己也遇到了这个挑战。我相信以下内容仍然可以改进,但这就是我想出的。我用 .net 4.5.2 和 4.6 对此进行了测试,所以我不确定它是否适用于旧框架。
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 { }
}
}
}

