场景
在使用ZedGraph绘制曲线图时,将鼠标悬浮时内容闪烁,且频率很高。
找到其源码,发现不论鼠标移动的范围大小,甚至乎不论鼠标是否移动,都要刷新一次Tooltip。
注:
关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。
实现
首先来到ZedGraph的官网
https://sourceforge.net/projects/zedgraph/
然后点击File下的zedgraph source
选择对应版本,这里是5.1.5
下载成功后,将zip解压
找到source下的工程文件,双击使用VS打开
然后找到ZedGraphControl.Events.cs
找到其ZedGraphControl_MouseMove方法此方法是鼠标移动时的事件处理
可以看到其对两个方法的处理,一个是HandlePointValues,这是对显示线上的点的坐标时的处理,一个是HandleCursorValues这是对获取最近曲线上的点的坐标时的处理。
这样看你的ZedGraph是开启的哪样设置。
假如是设置经过线上点时才显示
zgc.IsShowPointValues = true;那么就要修改
HandlePointValues( mousePt );
这个方法
首先声明一个类变量
private object lastObj;用来存储上一次使用的对象,然后找到其判断条件,添加当前是否与上一次是同一对象
然后在最后方法返回时将当前对象赋值给上一次对象。
lastObj = nearestObj;完整参考代码
private Point HandlePointValues( Point mousePt ) { int iPt; GraphPane pane; object nearestObj; using ( Graphics g = this.CreateGraphics() ) { if ( _masterPane.FindNearestPaneObject( mousePt, g, out pane, out nearestObj, out iPt ) ) { if (nearestObj is CurveItem && iPt >= 0 && !object.Equals(nearestObj, lastObj)) { CurveItem curve = (CurveItem)nearestObj; // Provide Callback for User to customize the tooltips if ( this.PointValueEvent != null ) { string label = this.PointValueEvent( this, pane, curve, iPt ); if ( label != null && label.Length > 0 ) { this.pointToolTip.SetToolTip( this, label ); this.pointToolTip.Active = true; } else this.pointToolTip.Active = false; } else { if ( curve is PieItem ) { this.pointToolTip.SetToolTip( this, ( (PieItem)curve ).Value.ToString( _pointValueFormat ) ); } // else if ( curve is OHLCBarItem || curve is JapaneseCandleStickItem ) // { // StockPt spt = (StockPt)curve.Points[iPt]; // this.pointToolTip.SetToolTip( this, ( (XDate) spt.Date ).ToString( "MM/dd/yyyy" ) + "\nOpen: $" + // spt.Open.ToString( "N2" ) + // "\nHigh: $" + // spt.High.ToString( "N2" ) + "\nLow: $" + // spt.Low.ToString( "N2" ) + "\nClose: $" + // spt.Close.ToString // ( "N2" ) ); // } else { PointPair pt = curve.Points[iPt]; if ( pt.Tag is string ) this.pointToolTip.SetToolTip( this, (string)pt.Tag ); else { double xVal, yVal, lowVal; ValueHandler valueHandler = new ValueHandler( pane, false ); if ( ( curve is BarItem || curve is ErrorBarItem || curve is HiLowBarItem ) && pane.BarSettings.Base != BarBase.X ) valueHandler.GetValues( curve, iPt, out yVal, out lowVal, out xVal ); else valueHandler.GetValues( curve, iPt, out xVal, out lowVal, out yVal ); string xStr = MakeValueLabel( curve.GetXAxis( pane ), xVal, iPt, curve.IsOverrideOrdinal ); string yStr = MakeValueLabel( curve.GetYAxis( pane ), yVal, iPt, curve.IsOverrideOrdinal ); this.pointToolTip.SetToolTip( this, "( " + xStr + ", " + yStr + " )" ); //this.pointToolTip.SetToolTip( this, // curve.Points[iPt].ToString( this.pointValueFormat ) ); } } this.pointToolTip.Active = true; } } else this.pointToolTip.Active = false; } else this.pointToolTip.Active = false; //g.Dispose(); } lastObj = nearestObj; return mousePt; }具体其他优化与功能修改可自行发掘。
如果在ZedGraph中设置的是显示最近曲线上的点的坐标,即
zgc.IsShowCursorValues = true;那么就要修改源码的HandleCursorValues方法
同样声明一个类变量存储上次获得的点
private Point lastMovedPoint;然后在方法中加上判断并通过
this.pointToolTip.AutomaticDelay = 1000;设置提示延迟1秒。最后再将当前点赋值给类变量。
lastMovedPoint = mousePt;完整示例代码
private Point HandleCursorValues( Point mousePt ) { GraphPane pane = _masterPane.FindPane(mousePt); if (pane != null && pane.Chart._rect.Contains(mousePt) && !mousePt.Equals(lastMovedPoint)) { // Provide Callback for User to customize the tooltips if (this.CursorValueEvent != null) { string label = this.CursorValueEvent(this, pane, mousePt); if (label != null && label.Length > 0) { this.pointToolTip.AutomaticDelay = 1000; this.pointToolTip.SetToolTip(this, label); this.pointToolTip.Active = true; } else { this.pointToolTip.Active = false; } lastMovedPoint = mousePt; } else { double x, x2, y, y2; pane.ReverseTransform(mousePt, out x, out x2, out y, out y2); string xStr = MakeValueLabel(pane.XAxis, x, -1, true); string yStr = MakeValueLabel(pane.YAxis, y, -1, true); string y2Str = MakeValueLabel(pane.Y2Axis, y2, -1, true); this.pointToolTip.AutomaticDelay = 1000; this.pointToolTip.SetToolTip(this, "( " + xStr + ", " + yStr + ", " + y2Str + " )"); this.pointToolTip.Active = true; } } else this.pointToolTip.Active = false; return mousePt; }注:
这里只着重修改当用户重写此事件的情况下,即this.CursorValueEvent != null时,具体情况可跟据自己需要进行修改。
ZedGraph5.1.5源码与修改版源码下载
关注公众号:
霸道的程序猿
回复:
ZedGraph源码修改