在数字货币或者股票看盘交易软件中,为了方便准确定位K线图中的时间和买卖点,都用到了用十字交叉线来定位买卖时间和买卖点。这里利用.Net下开源的NPlot图表插件,实现了跟着鼠标移动的十字定位交叉线,并能做到根据屏幕坐标转化为时间和买卖点坐标。这里通过在K线图上双击创建交叉十字线,十字线跟着鼠标移动而移动,并且实时获取移动的位置。效果如下:
主要代码实现包括PlotSurface2D(PlotSurface2D为NPlot控件中的容器类)创建及初始化、PlotSurface2D鼠标双击及移动的事件绑定及代码实现,HorizontalLine横线、VerticalLine竖线的声明和创建。详细代码如下:
PlotSurface2D的声明及初始化:
private NPlot.Windows.PlotSurface2D KLinePS;
private void InitKLinePS()
{
KLinePS = new NPlot.Windows.PlotSurface2D();
this.KLinePS.AutoScaleAutoGeneratedAxes = true;
this.KLinePS.AutoScaleTitle = false;
this.KLinePS.DateTimeToolTip = true;
this.KLinePS.DateTimeToolTip = true;
this.KLinePS.Legend = null;
this.KLinePS.LegendZOrder = -1;
this.KLinePS.Location = new System.Drawing.Point(0, 0);
this.KLinePS.Name = "costPS";
this.KLinePS.RightMenu = null;
this.KLinePS.Padding = 1;
//鼠标tooltips 时间+价格
this.KLinePS.ShowCoordinates = true;
this.KLinePS.Size = new System.Drawing.Size(969, 595);
this.KLinePS.Width = 1300;
this.KLinePS.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
this.KLinePS.TabIndex = 2;
this.KLinePS.Title = "123";
this.KLinePS.TitleFont = new System.Drawing.Font("Arial", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
}
HorizontalLine横线、VerticalLine竖线的声明,这里只是声明,具体的创建包括在鼠标双击事件中:
VerticalLine lineCrossX;// = new VerticalLine(10);
HorizontalLine lineCrossY;// = new HorizontalLine(10);
鼠标事件的绑定:
KLinePS.MouseMove += new System.Windows.Forms.MouseEventHandler(KLinePS_MouseMove);
KLinePS.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(KLinePS_MouseDoubleClick);
鼠标双击事件的实现:
private void KLinePS_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
System.Drawing.Point here = new System.Drawing.Point(e.X, e.Y);
//屏幕坐标转化为业务坐标
double x = this.KLinePS.PhysicalXAxis1Cache.PhysicalToWorld(here, true);
double y = this.KLinePS.PhysicalYAxis1Cache.PhysicalToWorld(here, true);
DateTime dateTime = new DateTime((long)x);
//水平线创建
lineCrossY = new HorizontalLine(y);
lineCrossY.LengthScale = 0.89f;
lineCrossY.OrdinateValue = y;
lineCrossY.Pen = Pens.Green;
//line.OrdinateValue = 2;
this.KLinePS.Add(lineCrossY);
///垂直线///
lineCrossX = new VerticalLine(x);
lineCrossX.LengthScale = 0.89f;
lineCrossX.Pen = Pens.Red;
lineCrossX.AbscissaValue = x;
this.KLinePS.Add(lineCrossX);
this.KLinePS.Refresh();
}
鼠标移动事件的实现:
private void KLinePS_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (this.KLinePS.PhysicalXAxis1Cache == null || this.KLinePS.PhysicalYAxis1Cache == null)
return;
System.Drawing.Point here = new System.Drawing.Point(e.X, e.Y);
double x = this.KLinePS.PhysicalXAxis1Cache.PhysicalToWorld(here, true);
double y = this.KLinePS.PhysicalYAxis1Cache.PhysicalToWorld(here, true);
if (lineCrossY != null && lineCrossX != null)
{
lineCrossY.OrdinateValue = y;
lineCrossX.AbscissaValue = x;
}
this.KLinePS.Refresh();
}