我在项目中使用Microsoft Chart控件,我想通过使用鼠标滚轮在Chart Control中启用缩放功能,我该如何实现?
但是用户不必点击图表,就像鼠标位置在我的图表上而不是从鼠标滚轮滚动它可以放大/缩小
答案 0 :(得分:25)
您需要使用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
属性告诉您已经完成了多少轮“滚动”,并且可以使用。
向外滚动将缩小整个过程。
这可能是一种更清洁的方式,但事实确实如此。 希望这有帮助!
答案 1 :(得分:2)
我从上面修改了代码,并添加了反向缩放。因此,当您向后旋转鼠标滚轮时,图表将缩小。我也不建议使用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 { }
}
答案 2 :(得分:0)
Waaaay参加聚会很晚,但今天我自己也面临这个挑战。 我确信以下内容仍可以改进,但这就是我想出的。 我使用.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 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 { }
}
}
}
答案 3 :(得分:0)
我从上面修改了代码,并使用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 { }
}
希望这会有所帮助!