当前位置: 首页 > news >正文

ZedGraph 可选定轴 通过鼠标移动或通过滚轮设置轴的范围

文章目录

    • 前言
    • 效果图
    • 引用的Dll
    • 确定轴的位置
      • 详细代码
    • 实现移动轴范围和滚轮设置轴范围
      • 具体实现的代码
    • 完整的代码

前言

使用的ZedGraph绘制曲线图时,轴的范围要么是根据采集到的数据自动变化,要么是在缩放平移时才能看到轴的变化。要想设置轴的范围,第一个想到的方法是,建立一个对话框,输入起始坐标,轴间隔(或坐标的最大最小值)来设置,但这样子太麻烦了。下面介绍另一个方法,可以通过鼠标滑动选中的轴,或者是在选定轴上滚动鼠标滚轮来设置轴的范围。

效果图

话不多说,先上效果图:
在这里插入图片描述

引用的Dll

我使用的是ZedGraph.Winfroms,勾选【包括预发行版】才能看到。
说明一下:
如果使用第1个ZedGraph的话,鼠标移动轴更改轴范围可以实现,但滚轮移动轴更改轴范围就实现不了,有调用的一个函数在ZedGraph.Winform中。
使用第二个ZedGraph.Winfroms的话,两种方式都能更改轴的范围。
在这里插入图片描述

确定轴的位置

这里比较难的之一就是如何确定轴的位置,我放一个图配合解说和代码,就能一清二楚的知道轴的位置应该怎么计算了。

先看看左侧的Y轴。起始绘制点在(0,0),终点绘制点在(GraphPane.Chart.Rect.Left,0)GraphPane.Chart.Rect.Left 等于GraphPane.Chart.Rect.X。可以看到左侧Y轴都在0~GraphPane.Chart.Rect.Left 的这一段范围中。

然后看看右侧的Y轴。起始绘制点在(GraphPane.Chart.Rect.Right,0),终点绘制点在(MasterPane.Rect.Right,0),即红色框的最右边到的绿色框的最右边.可以看到右侧Y轴都在GraphPane.Chart.Rect.Right~MasterPane.Chart.Rect.Left 的这一段范围中。

最后看看X轴的位置。同理,X轴绘制的区域范围的起始绘制点在(0, GraphPane.Chart.Rect.Bottom),终点绘制点在(0, MasterPane.Chart.Rect.Bottom)

每条轴所占的宽度可以通过轴的 public float CalcSpace(Graphics g, GraphPane pane, float scaleFactor, out float fixedSpace);计算出来,其中out float fixedSpace就是当前轴所占用的宽度。

当鼠标在这些区域按下或滚动时,就能从鼠标的位置来判断是不是要移动轴了,以及移动的是哪一个轴。
在这里插入图片描述

详细代码

        /// <summary>/// 缩放移动轴/// </summary>/// <param name="e">鼠标事件</param>/// <param name="tempIsWheel">滚轮事件true 点击事件false</param>/// <returns>返回Y轴索引</returns>private int FindMoveAxis(MouseEventArgs e, bool tempIsWheel){this.DragAxis = null;this.IsDragXAxis = false;this.IsDragYAxis = false;//Y轴索引int tmpIndexY = -1;#region 判断是否移动左侧Y轴//初始化起始坐标点float tmpStartX = 0;//其中Rect://获取或设置包含由轴(x轴、y轴和y2轴)限定的区域的矩形。//如果手动设置此值,则IsRectAuto值将自动设置为false。//X是获取矩形区域左上角的坐标float tmpEndX = Oscillograph.GraphPane.Chart.Rect.X - 5;//缩放比例float scaleFactor = Oscillograph.GraphPane.CalcScaleFactor();Graphics g = Oscillograph.CreateGraphics();//如果鼠标落下的位置在此范围内 0到 矩形区域左上角的图标//即鼠标落点在Y轴的区域if (e.X > tmpStartX && e.X < tmpEndX){//开始拖拽时Y的坐标值 = 鼠标的Y坐标this.StartPosition = e.Y;//获取Y轴的数量int yAxisCount = Oscillograph.GraphPane.YAxisList.Count;//记录使用的Y轴索引List<int> tmpList = new List<int>();for (int i = yAxisCount - 1; i >= 0; i--){//左侧区域if (!Oscillograph.GraphPane.YAxisList[i].IsVisible){//Y轴不可见yAxisCount--;}else{//记录使用的Y轴索引tmpList.Add(i);}}//就是获取Y左边Y轴的区域除以Y轴的数量 就是每个Y轴的单位宽度float unit = (tmpEndX - tmpStartX) / yAxisCount;unit = 0;//通过循环获取自己要拖拽哪个Y轴for (int i = 0; i < yAxisCount; i++){//计算刻度轴标签的最大宽度float tmpSpecae = Oscillograph.GraphPane.YAxisList[tmpList[i]].CalcSpace(g, Oscillograph.GraphPane, scaleFactor, out float tmpFloat);//如果鼠标所在的X坐标对应Y轴的区域内if (e.X < (unit + tmpSpecae) && e.X > unit){//Y轴索引tmpIndexY = tmpList[i];if (tmpIndexY >= 0){//拖拽Y轴标识改为truethis.IsDragYAxis = true;//拖拽的Y轴的索引就是反顺序的索引this.DragAxis = Oscillograph.GraphPane.YAxisList[tmpIndexY];break;}}unit += tmpSpecae;}}#endregionif (this.IsDragYAxis){//检测选择或滚动Y轴g.Dispose();return tmpIndexY;}#region 判断是否移动右侧Y轴//右侧的X要加上矩形的宽度tmpStartX = Oscillograph.GraphPane.Chart.Rect.Right;tmpEndX = Oscillograph.MasterPane.Rect.Right - 5;if (e.X > tmpStartX && e.X < tmpEndX){//开始拖拽时Y的坐标值 = 鼠标的Y坐标this.StartPosition = e.Y;//获取Y轴的数量int yAxisCount = Oscillograph.GraphPane.Y2AxisList.Count;//就是获取Y左边Y轴的区域除以Y轴的数量 就是每个Y轴的单位宽度float unit = (tmpEndX - tmpStartX) / yAxisCount;//通过循环获取自己要拖拽哪个Y轴for (int i = 0; i < yAxisCount; i++){//如果鼠标所在的X坐标对应Y轴的区域内if (e.X < tmpStartX + unit * (i + 1) && e.X > unit * i + tmpStartX){//拖拽Y轴标识改为truethis.IsDragYAxis = true;//Y轴索引tmpIndexY = i;//拖拽的Y轴的索引就是反顺序的索引this.DragAxis = Oscillograph.GraphPane.Y2AxisList[tmpIndexY];break;}}}#endregionif (this.IsDragYAxis && tmpIndexY > -1){//检测选择或滚动Y轴return (tmpIndexY + Oscillograph.GraphPane.YAxisList.Count-1);}#region 是否拖拽X轴//sender.GraphPane.Chart.Rect.Y 获取左上角的Y坐标 再加上区域高度float tmpStartY = Oscillograph.GraphPane.Chart.Rect.Bottom;float tmpS = Oscillograph.GraphPane.XAxis.CalcSpace(g, Oscillograph.GraphPane, scaleFactor, out float tmpF);float tmpEndY = tmpStartY + tmpS * 0.8f;if (e.Y > tmpStartY && e.Y < tmpEndY){//将拖拽X轴设置为truethis.IsDragXAxis = true;this.StartPosition = e.X;this.DragAxis = Oscillograph.GraphPane.XAxis;}#endregionreturn 0;}

实现移动轴范围和滚轮设置轴范围

1 选中轴并移动,根据移动的量设置轴范围。鼠标按下MouseDown的时候判断是否要设置轴,鼠标移动MouseMove的时候设置轴范围,鼠标松开MouseUp的时候停止更新轴范围

2 鼠标滚轮放置在轴上,根据滚动的滚轮速度,设置轴范围。滚轮滚动MouseWheel的时候,判断是否要设置轴范围,如果是则设置,滚动一次就设置一次。

具体实现的代码

         /// <summary>/// 鼠标按下/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <returns>true:不会往下继续执行基类的MouseDown功能; false会往下继续执行基类的MouseDown功能</returns>private bool Oscillograph_MouseDownEvent(ZedGraphControl sender, MouseEventArgs e){//判断鼠标按下的位置,是否在轴的位置,以及选中的是哪一个轴this.FindMoveAxis(e, false);if((this.IsDragXAxis || this.IsDragYAxis) && this.DragAxis != null){//不让基类的MouseDown事件继续往下执行return true;}return false;}/// <summary>/// 鼠标移动/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <returns></returns>private bool Oscillograph_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e){//如果是拖动Y轴if (this.IsDragYAxis && DragAxis!=null){//速度(占的比例)float rate = (e.Y - this.StartPosition) / Oscillograph.GraphPane.Chart.Rect.Height;//距离float diff = rate * (float)(this.DragAxis.Scale.Max - this.DragAxis.Scale.Min);if (Math.Abs(rate) >= 0.01){//Y轴的刻度最大值加上距离this.DragAxis.Scale.Max += diff;//Y轴刻度的最小值加上距离this.DragAxis.Scale.Min += diff;this.StartPosition = e.Y;//刷新曲线图Oscillograph.AxisChange();Oscillograph.Refresh();}}//拖拽X轴if (this.IsDragXAxis && DragAxis != null){float rate = (e.X - this.StartPosition) / Oscillograph.GraphPane.Chart.Rect.Width;float diff = rate * (float)(this.DragAxis.Scale.Max - this.DragAxis.Scale.Min);if (Math.Abs(rate) >= 0.01){this.DragAxis.Scale.Max -= diff;this.DragAxis.Scale.Min -= diff;this.StartPosition = e.X;Oscillograph.AxisChange();Oscillograph.Refresh();}}if ((this.IsDragYAxis || this.IsDragXAxis) &&  DragAxis != null){return true;}return false;}/// <summary>/// 松开鼠标(释放)/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <returns></returns>private bool Oscillograph_MouseUpEvent(ZedGraphControl sender, MouseEventArgs e){this.DragAxis = null;this.IsDragXAxis = false;this.IsDragYAxis = false;return false;}/// <summary>/// 鼠标滚轮滚动/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Oscillograph_MouseWheel(object sender, MouseEventArgs e){//判断鼠标按下的位置,是否在轴的位置,以及选中的是哪一个轴int tmpIndexY = this.FindMoveAxis(e, false);if ((this.IsDragXAxis || this.IsDragYAxis) && this.DragAxis != null){//不让基类的MouseDown事件继续往下执行if (tmpIndexY == -1 || !this.DragAxis.IsVisible){//轴不可见return;}//鼠标的坐标PointF centerPoint = new PointF(e.X, e.Y);//缩放灵敏度double zoomFraction = (1 + (e.Delta < 0 ? 1.0 : -1.0)* 0.1);//刻度轴自适应this.ResetAutoScale(this.DragAxis.Scale);//缩放轴this.ZoomAxis(Oscillograph.GraphPane, zoomFraction,centerPoint, this.DragAxis, this.IsDragYAxis, tmpIndexY);this.DragAxis = null;this.IsDragXAxis = false;this.IsDragYAxis = false;return;}}

完整的代码

上面的步骤介绍了整体的思路,下面贴的是Demo的全都代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
namespace ZedgraphMulY
{/// <summary>/// 移动示波器的轴/// </summary>public partial class MoveOscAxisForm : Form{private ZedGraphControl Oscillograph;private GraphPane MyPane;        //示波器界面控件public MoveOscAxisForm(){InitializeComponent();this.AddCenterControls();this.RegisterOscEvent();}//中间private void AddCenterControls(){//曲线图Oscillograph = new ZedGraphControl();Oscillograph.Name = "Oscillograph";OscillographInit();   //初始化示波器//iniOscCurve();        //初始化通道数据Oscillograph.Dock = DockStyle.Fill;this.Controls.Add(Oscillograph);}#region 初始化示波器private void OscillographInit(){this.Oscillograph.BorderStyle = BorderStyle.None;MyPane = this.Oscillograph.GraphPane;MyPane.Legend.IsVisible = false;MyPane.Title.IsVisible = false;//背景色MyPane.Chart.Fill.Type = FillType.Solid;this.Oscillograph.MasterPane.Border.IsVisible = false;MyPane.Border.IsVisible = false;MyPane.Margin.Top = 22;MyPane.Margin.Right = 22;MyPane.Margin.Left = 10;MyPane.Margin.Bottom = 10;#region  X轴网格线MyPane.XAxis.MajorGrid.IsVisible = true;MyPane.XAxis.MajorGrid.IsZeroLine = false;MyPane.XAxis.MajorGrid.Color = Color.FromArgb(120, 120, 120);MyPane.XAxis.MajorGrid.DashOff = 4f;MyPane.XAxis.MajorGrid.DashOn = 4f;MyPane.XAxis.MajorGrid.PenWidth = 0.1f;MyPane.XAxis.MinorGrid.Color = Color.FromArgb(120, 120, 120);MyPane.XAxis.MinorGrid.DashOff = 4f;MyPane.XAxis.MinorGrid.DashOn = 4f;MyPane.XAxis.MinorGrid.PenWidth = 0.1f;MyPane.XAxis.MajorTic.IsAllTics = false;MyPane.XAxis.MinorTic.IsAllTics = false;MyPane.XAxis.Scale.FontSpec.FontColor = Color.FromArgb(150, 150, 150);MyPane.XAxis.Scale.FontSpec.Size = 10;MyPane.XAxis.Scale.Max = 100;MyPane.XAxis.Scale.Min = 0;MyPane.XAxis.Scale.MajorStep = 10;MyPane.XAxis.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);MyPane.XAxis.Title.FontSpec.Size = 10;MyPane.XAxis.Title.Text = "(ms)";MyPane.XAxis.Type = AxisType.Linear;#endregion//背景颜色ChangeBackColorForm();#region  左侧第一条Y轴 Y轴网格线MyPane.YAxis.MajorGrid.IsVisible = true;MyPane.YAxis.MajorGrid.IsZeroLine = false;MyPane.YAxis.MajorGrid.PenWidth = 0.1f;MyPane.YAxis.MajorGrid.DashOn = 4f;MyPane.YAxis.MajorGrid.DashOff = 4f;MyPane.YAxis.MajorGrid.Color = Color.FromArgb(120, 120, 120);MyPane.YAxis.MinorGrid.IsVisible = false;MyPane.YAxis.MajorTic.Color = Color.FromArgb(150, 150, 150);MyPane.YAxis.MajorTic.IsAllTics = false;MyPane.YAxis.MajorTic.IsOpposite = false;          //隐藏对面的刻度-主刻度MyPane.YAxis.MinorTic.IsAllTics = false;MyPane.YAxis.MinorTic.IsOpposite = false;          //隐藏对面的刻度-小刻度MyPane.YAxis.Scale.MaxAuto = false;MyPane.YAxis.Scale.MinAuto = false;MyPane.YAxis.Scale.MajorStepAuto = false;MyPane.YAxis.Scale.MinorStepAuto = false;MyPane.YAxis.Scale.FontSpec.FontColor = Color.Yellow;MyPane.YAxis.Scale.FontSpec.Size = 8;MyPane.YAxis.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);MyPane.YAxis.Title.FontSpec.Size = 10;MyPane.YAxis.Title.IsVisible = false;MyPane.YAxis.IsVisible = true;#endregion#region 左侧第二条Y轴  Y轴网格线YAxis yAxis1 = new YAxis("");// yAxis1.IsAxisSegmentVisible = false;  //Y轴长线是否可见yAxis1.MajorGrid.IsVisible = true;yAxis1.MajorGrid.IsZeroLine = false;yAxis1.MajorGrid.PenWidth = 0.1f;yAxis1.MajorGrid.DashOn = 4f;yAxis1.MajorGrid.DashOff = 4f;yAxis1.MajorGrid.Color = Color.FromArgb(120, 120, 120);yAxis1.MinorGrid.IsVisible = false;yAxis1.MajorTic.Color = Color.FromArgb(150, 150, 150);yAxis1.MajorTic.IsAllTics = false;yAxis1.MajorTic.IsOpposite = false;          //隐藏对面的刻度-主刻度yAxis1.MinorTic.IsAllTics = false;yAxis1.MinorTic.IsOpposite = false;          //隐藏对面的刻度-小刻度yAxis1.Scale.MaxAuto = false;yAxis1.Scale.MinAuto = false;yAxis1.Scale.MinorStepAuto = false;yAxis1.Scale.MajorStepAuto = false;yAxis1.Scale.FontSpec.FontColor = Color.Lime;yAxis1.Scale.FontSpec.Size = 8;yAxis1.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);yAxis1.Title.FontSpec.Size = 10;yAxis1.IsVisible = true;MyPane.YAxisList.Add(yAxis1);#endregion#region  左侧第三条Y轴 Y轴网格线YAxis yAxis2 = new YAxis("");yAxis2.MajorGrid.IsVisible = true;yAxis2.MajorGrid.IsZeroLine = false;yAxis2.MajorGrid.PenWidth = 0.1f;yAxis2.MajorGrid.DashOn = 4f;yAxis2.MajorGrid.DashOff = 4f;yAxis2.MajorGrid.Color = Color.FromArgb(120, 120, 120);yAxis2.MinorGrid.IsVisible = false;yAxis2.MajorTic.Color = Color.FromArgb(150, 150, 150);yAxis2.MajorTic.IsAllTics = false;yAxis2.MajorTic.IsOpposite = false;          //隐藏对面的刻度-主刻度yAxis2.MinorTic.IsAllTics = false;yAxis2.MinorTic.IsOpposite = false;          //隐藏对面的刻度-小刻度yAxis2.Scale.MaxAuto = false;yAxis2.Scale.MinAuto = false;yAxis2.Scale.MinorStepAuto = false;yAxis2.Scale.MajorStepAuto = false;yAxis2.Scale.FontSpec.FontColor = Color.CornflowerBlue;yAxis2.Scale.FontSpec.Size = 8;yAxis2.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);yAxis2.Title.FontSpec.Size = 10;yAxis2.IsVisible = true;MyPane.YAxisList.Add(yAxis2);#endregion#region 右侧的第一条Y轴MyPane.Y2Axis.MajorGrid.IsVisible = true;MyPane.Y2Axis.MajorGrid.IsZeroLine = false;MyPane.Y2Axis.MajorGrid.PenWidth = 0.1f;MyPane.Y2Axis.MajorGrid.DashOn = 4f;MyPane.Y2Axis.MajorGrid.DashOff = 4f;MyPane.Y2Axis.MajorGrid.Color = Color.FromArgb(120, 120, 120);MyPane.Y2Axis.MinorGrid.IsVisible = false;MyPane.Y2Axis.MajorTic.Color = Color.FromArgb(150, 150, 150);MyPane.YAxis.MajorTic.IsAllTics = false;MyPane.Y2Axis.MajorTic.IsOpposite = false;          //隐藏对面的刻度-主刻度MyPane.Y2Axis.MinorTic.IsAllTics = false;MyPane.Y2Axis.MinorTic.IsOpposite = false;          //隐藏对面的刻度-小刻度MyPane.Y2Axis.Scale.MaxAuto = false;MyPane.Y2Axis.Scale.MinAuto = false;MyPane.Y2Axis.Scale.MinorStepAuto = false;MyPane.Y2Axis.Scale.MajorStepAuto = false;MyPane.Y2Axis.Scale.FontSpec.FontColor = Color.Cyan;MyPane.Y2Axis.Scale.FontSpec.Size = 8;MyPane.Y2Axis.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);MyPane.Y2Axis.Title.FontSpec.Size = 10;MyPane.Y2Axis.IsVisible = true;#endregion#region 右侧第二条Y轴Y2Axis yAxis3 = new Y2Axis("");//Y轴网格线yAxis3.MajorGrid.IsVisible = true;yAxis3.MajorGrid.IsZeroLine = false;yAxis3.MajorGrid.PenWidth = 0.1f;yAxis3.MajorGrid.DashOn = 4f;yAxis3.MajorGrid.DashOff = 4f;yAxis3.MajorGrid.Color = Color.FromArgb(120, 120, 120);yAxis3.MinorGrid.IsVisible = false;yAxis3.MajorTic.Color = Color.FromArgb(150, 150, 150);yAxis3.MajorTic.IsAllTics = false;yAxis3.MajorTic.IsOpposite = false;          //隐藏对面的刻度-主刻度yAxis3.MinorTic.IsAllTics = false;yAxis3.MinorTic.IsOpposite = false;          //隐藏对面的刻度-小刻度yAxis3.Scale.MaxAuto = false;yAxis3.Scale.MinAuto = false;yAxis3.Scale.MinorStepAuto = false;yAxis3.Scale.MajorStepAuto = false;yAxis3.Scale.FontSpec.FontColor = Color.Fuchsia;yAxis3.Scale.FontSpec.Size = 8;yAxis3.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);yAxis3.Title.FontSpec.Size = 10;yAxis3.IsVisible = true;MyPane.Y2AxisList.Add(yAxis3);   //添加到Y2AxisList中#endregion#region 右侧第三条Y轴Y2Axis yAxis4 = new Y2Axis("");//Y轴网格线yAxis4.MajorGrid.IsVisible = true;yAxis4.MajorGrid.IsZeroLine = false;yAxis4.MajorGrid.PenWidth = 0.1f;yAxis4.MajorGrid.DashOn = 4f;yAxis4.MajorGrid.DashOff = 4f;yAxis4.MajorGrid.Color = Color.FromArgb(120, 120, 120);yAxis4.MinorGrid.IsVisible = false;yAxis4.MajorTic.Color = Color.FromArgb(150, 150, 150);yAxis4.MajorTic.IsAllTics = false;yAxis4.MajorTic.IsOpposite = false;          //隐藏对面的刻度-主刻度yAxis4.MinorTic.IsAllTics = false;yAxis4.MinorTic.IsOpposite = false;          //隐藏对面的刻度-小刻度yAxis4.Scale.MaxAuto = false;yAxis4.Scale.MinAuto = false;yAxis4.Scale.MinorStepAuto = false;yAxis4.Scale.MajorStepAuto = false;yAxis4.Scale.FontSpec.FontColor = Color.Red;yAxis4.Scale.FontSpec.Size = 8;yAxis4.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);yAxis4.Title.FontSpec.Size = 10;yAxis4.IsVisible = true;         //隐藏MyPane.Y2AxisList.Add(yAxis4);    //添加到Y2AxisList中#endregion/* Oscillograph.PanModifierKeys = Keys.Shift;  //平移按键,若none,则屏蔽矩形缩放Oscillograph.IsShowContextMenu = false;  //显示右键菜单Oscillograph.IsEnableZoom = false;      //允许缩放Oscillograph.IsEnableHZoom = false;     //允许横向缩放Oscillograph.IsEnableVZoom = false;     //允许纵向缩放Oscillograph.IsEnableVPan = false;       //允许纵向平移Oscillograph.IsEnableHPan = false;       //允许横向平移Oscillograph.IsShowPointValues = false;    //显示点的值Oscillograph.IsEnableWheelZoom = false;    //禁止鼠标滚动缩放*/Oscillograph.IsShowHScrollBar = true;     //水平滚动条Oscillograph.IsAutoScrollRange = true;    //滚动范围Oscillograph.IsEnableWheelZoom = true;//   Oscillograph.RestoreScale(MyPane);Oscillograph.AxisChange();}#endregionprivate void ChangeBackColorForm(){{MyPane.Chart.Fill.Color = Color.Black;MyPane.Fill.Color = Color.Black;MyPane.Chart.Border.Color = Color.FromArgb(150, 150, 150);MyPane.XAxis.MajorGrid.Color = Color.FromArgb(120, 120, 120);MyPane.XAxis.MinorGrid.Color = Color.FromArgb(120, 120, 120);MyPane.XAxis.MajorTic.Color = Color.FromArgb(150, 150, 150);MyPane.XAxis.MinorTic.Color = Color.FromArgb(150, 150, 150);MyPane.XAxis.Scale.FontSpec.FontColor = Color.FromArgb(150, 150, 150);MyPane.XAxis.Title.FontSpec.FontColor = Color.FromArgb(150, 150, 150);}Oscillograph.Refresh();}#region  轴移动的变量/// <summary>/// 是否移动Y轴/// </summary>private bool IsDragYAxis = false;/// <summary>/// 是否移动X轴/// </summary>private bool IsDragXAxis = false;/// <summary>/// XY轴起始点/// </summary>private int StartPosition = 0;/// <summary>/// 拖拽的XY轴/// </summary>private Axis DragAxis = null;#endregion/// <summary>/// 示波器控件事件注册/// </summary>private void RegisterOscEvent(){//鼠标按下Oscillograph.MouseDownEvent += Oscillograph_MouseDownEvent;//鼠标移动Oscillograph.MouseMoveEvent += Oscillograph_MouseMoveEvent;//松开鼠标(释放)Oscillograph.MouseUpEvent += Oscillograph_MouseUpEvent;//鼠标滚轮滚动Oscillograph.MouseWheel += Oscillograph_MouseWheel;}/// <summary>/// 鼠标按下/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <returns>true:不会往下继续执行基类的MouseDown功能; false会往下继续执行基类的MouseDown功能</returns>private bool Oscillograph_MouseDownEvent(ZedGraphControl sender, MouseEventArgs e){//判断鼠标按下的位置,是否在轴的位置,以及选中的是哪一个轴this.FindMoveAxis(e, false);if((this.IsDragXAxis || this.IsDragYAxis) && this.DragAxis != null){//不让基类的MouseDown事件继续往下执行return true;}return false;}/// <summary>/// 鼠标移动/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <returns></returns>private bool Oscillograph_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e){//如果是拖动Y轴if (this.IsDragYAxis && DragAxis!=null){//速度(占的比例)float rate = (e.Y - this.StartPosition) / Oscillograph.GraphPane.Chart.Rect.Height;//距离float diff = rate * (float)(this.DragAxis.Scale.Max - this.DragAxis.Scale.Min);if (Math.Abs(rate) >= 0.01){//Y轴的刻度最大值加上距离this.DragAxis.Scale.Max += diff;//Y轴刻度的最小值加上距离this.DragAxis.Scale.Min += diff;this.StartPosition = e.Y;//刷新曲线图Oscillograph.AxisChange();Oscillograph.Refresh();}}//拖拽X轴if (this.IsDragXAxis && DragAxis != null){float rate = (e.X - this.StartPosition) / Oscillograph.GraphPane.Chart.Rect.Width;float diff = rate * (float)(this.DragAxis.Scale.Max - this.DragAxis.Scale.Min);if (Math.Abs(rate) >= 0.01){this.DragAxis.Scale.Max -= diff;this.DragAxis.Scale.Min -= diff;this.StartPosition = e.X;Oscillograph.AxisChange();Oscillograph.Refresh();}}if ((this.IsDragYAxis || this.IsDragXAxis) &&  DragAxis != null){return true;}return false;}/// <summary>/// 松开鼠标(释放)/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// <returns></returns>private bool Oscillograph_MouseUpEvent(ZedGraphControl sender, MouseEventArgs e){this.DragAxis = null;this.IsDragXAxis = false;this.IsDragYAxis = false;return false;}/// <summary>/// 鼠标滚轮滚动/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Oscillograph_MouseWheel(object sender, MouseEventArgs e){//判断鼠标按下的位置,是否在轴的位置,以及选中的是哪一个轴int tmpIndexY = this.FindMoveAxis(e, false);if ((this.IsDragXAxis || this.IsDragYAxis) && this.DragAxis != null){//不让基类的MouseDown事件继续往下执行if (tmpIndexY == -1 || !this.DragAxis.IsVisible){//轴不可见return;}//鼠标的坐标PointF centerPoint = new PointF(e.X, e.Y);//缩放灵敏度double zoomFraction = (1 + (e.Delta < 0 ? 1.0 : -1.0)* 0.1);//刻度轴自适应this.ResetAutoScale(this.DragAxis.Scale);//缩放轴this.ZoomAxis(Oscillograph.GraphPane, zoomFraction,centerPoint, this.DragAxis, this.IsDragYAxis, tmpIndexY);this.DragAxis = null;this.IsDragXAxis = false;this.IsDragYAxis = false;return;}}/// <summary>/// 缩放移动轴/// </summary>/// <param name="e">鼠标事件</param>/// <param name="tempIsWheel">滚轮事件true 点击事件false</param>/// <returns>返回Y轴索引</returns>private int FindMoveAxis(MouseEventArgs e, bool tempIsWheel){this.DragAxis = null;this.IsDragXAxis = false;this.IsDragYAxis = false;//Y轴索引int tmpIndexY = -1;#region 判断是否移动左侧Y轴//初始化起始坐标点float tmpStartX = 0;//其中Rect://获取或设置包含由轴(x轴、y轴和y2轴)限定的区域的矩形。//如果手动设置此值,则IsRectAuto值将自动设置为false。//X是获取矩形区域左上角的坐标float tmpEndX = Oscillograph.GraphPane.Chart.Rect.X - 5;//缩放比例float scaleFactor = Oscillograph.GraphPane.CalcScaleFactor();Graphics g = Oscillograph.CreateGraphics();//如果鼠标落下的位置在此范围内 0到 矩形区域左上角的图标//即鼠标落点在Y轴的区域if (e.X > tmpStartX && e.X < tmpEndX){//开始拖拽时Y的坐标值 = 鼠标的Y坐标this.StartPosition = e.Y;//获取Y轴的数量int yAxisCount = Oscillograph.GraphPane.YAxisList.Count;//记录使用的Y轴索引List<int> tmpList = new List<int>();for (int i = yAxisCount - 1; i >= 0; i--){//左侧区域if (!Oscillograph.GraphPane.YAxisList[i].IsVisible){//Y轴不可见yAxisCount--;}else{//记录使用的Y轴索引tmpList.Add(i);}}//就是获取Y左边Y轴的区域除以Y轴的数量 就是每个Y轴的单位宽度float unit = (tmpEndX - tmpStartX) / yAxisCount;unit = 0;//通过循环获取自己要拖拽哪个Y轴for (int i = 0; i < yAxisCount; i++){//计算刻度轴标签的最大宽度float tmpSpecae = Oscillograph.GraphPane.YAxisList[tmpList[i]].CalcSpace(g, Oscillograph.GraphPane, scaleFactor, out float tmpFloat);//如果鼠标所在的X坐标对应Y轴的区域内if (e.X < (unit + tmpSpecae) && e.X > unit){//Y轴索引tmpIndexY = tmpList[i];if (tmpIndexY >= 0){//拖拽Y轴标识改为truethis.IsDragYAxis = true;//拖拽的Y轴的索引就是反顺序的索引this.DragAxis = Oscillograph.GraphPane.YAxisList[tmpIndexY];break;}}unit += tmpSpecae;}}#endregionif (this.IsDragYAxis){//检测选择或滚动Y轴g.Dispose();return tmpIndexY;}#region 判断是否移动右侧Y轴//右侧的X要加上矩形的宽度tmpStartX = Oscillograph.GraphPane.Chart.Rect.Right;tmpEndX = Oscillograph.MasterPane.Rect.Right - 5;if (e.X > tmpStartX && e.X < tmpEndX){//开始拖拽时Y的坐标值 = 鼠标的Y坐标this.StartPosition = e.Y;//获取Y轴的数量int yAxisCount = Oscillograph.GraphPane.Y2AxisList.Count;//就是获取Y左边Y轴的区域除以Y轴的数量 就是每个Y轴的单位宽度float unit = (tmpEndX - tmpStartX) / yAxisCount;//通过循环获取自己要拖拽哪个Y轴for (int i = 0; i < yAxisCount; i++){//如果鼠标所在的X坐标对应Y轴的区域内if (e.X < tmpStartX + unit * (i + 1) && e.X > unit * i + tmpStartX){//拖拽Y轴标识改为truethis.IsDragYAxis = true;//Y轴索引tmpIndexY = i;//拖拽的Y轴的索引就是反顺序的索引this.DragAxis = Oscillograph.GraphPane.Y2AxisList[tmpIndexY];break;}}}#endregionif (this.IsDragYAxis && tmpIndexY > -1){//检测选择或滚动Y轴return (tmpIndexY + Oscillograph.GraphPane.YAxisList.Count-1);}#region 是否拖拽X轴//sender.GraphPane.Chart.Rect.Y 获取左上角的Y坐标 再加上区域高度float tmpStartY = Oscillograph.GraphPane.Chart.Rect.Bottom;float tmpS = Oscillograph.GraphPane.XAxis.CalcSpace(g, Oscillograph.GraphPane, scaleFactor, out float tmpF);float tmpEndY = tmpStartY + tmpS * 0.8f;if (e.Y > tmpStartY && e.Y < tmpEndY){//将拖拽X轴设置为truethis.IsDragXAxis = true;this.StartPosition = e.X;this.DragAxis = Oscillograph.GraphPane.XAxis;}#endregionreturn 0;}/// <summary>/// 缩放轴/// </summary>/// <param name="pane">面板</param>/// <param name="zoomFraction">缩放灵敏度</param>/// <param name="centerPt">鼠标点</param>/// <param name="axis">要缩放的轴</param>/// <param name="IsVertical">垂直true  水平false</param>/// <param name="indexY">y轴索引</param>protected void ZoomAxis(GraphPane pane, double zoomFraction, PointF centerPt,Axis axis, bool IsVertical, int indexY){//在每个轴下对应的数值double x;double x2;double[] y;double[] y2;//将鼠标点坐标转换为 图形内的坐标pane.ReverseTransform(centerPt, out x, out x2, out y, out y2);if (IsVertical){//Y轴if (indexY >= 2){//右侧的axis.Scale.Zoom(zoomFraction, y2[indexY - 2], true);}else{//左侧的axis.Scale.Zoom(zoomFraction, y[indexY], true);}}else{//X轴axis.Scale.Zoom(zoomFraction, x, true);}using (Graphics g = this.CreateGraphics()){pane.AxisChange(g);//g.Dispose();}Oscillograph.Refresh();}/// <summary>/// 单个轴的自适应/// </summary>/// <param name="scale"></param>private void ResetAutoScale(Scale scale){scale.MaxAuto = true;scale.MinAuto = true;scale.MajorStepAuto = true;scale.MinorStepAuto = true;}}
}
http://www.dtcms.com/a/297822.html

相关文章:

  • linux-开机启动流程
  • 解密国密 SSL 证书:SM2、SM3、SM4 算法的协同安全效应
  • 物联网技术:起源、发展、重点技术、应用场景与未来演进
  • [RPA] Excel中的字典处理
  • Y1第4课题解(A~E)
  • Kubernetes深度解析:企业级容器编排平台的核心实践
  • 在OpenMP中,#pragma omp的使用
  • JAVA_FourTEEN_常见算法
  • Python爬虫实战:研究flanker相关技术
  • 通过 Web3 区块链安全评估,领先应对网络威胁
  • Java零基础入门学习知识点2-JDK安装配置+Maven
  • k8s常用基础命令总结
  • P1106 删数问题 - 洛谷
  • 深度学习day02--神经网络(前三节)
  • 使用 Dijkstra 算法 和 旅行商问题(TSP) 规划快递员配送路线(python)
  • Qwen3-235B-A22B-Thinking-2507 - 开源思维推理模型的新标杆
  • ClickHouse 常用的使用场景
  • Java学习第七十四部分——Elasticsearch(ES)
  • 订单数据解密:从数据来源到状态分析的SQL实战指南
  • 【Python】一些PEP提案(四):scandir、类型约束,异步asyncawait
  • 工业缺陷检测的计算机视觉方法总结
  • Linux文件系统权限
  • 【基于CKF的IMM】MATLAB例程,CV和CT两个模型下的IMM,二维,滤波使用CKF(容积卡尔曼滤波),附下载链接
  • 基于ENMeval包的MaxEnt模型参数优化总结
  • C#索引器、接口、泛型
  • 构建跨平台远程医疗系统中的视频通路技术方案探究
  • Java 反射机制详解:从基础到实战,彻底掌握 Class、Method、Field 的动态操作
  • 免模型控制
  • 解决笔记本合盖开盖DPI缩放大小变 (异于网传方法,Win11 24H2)
  • TCP模型,mqtt协议01 day41