ZedGraph如何显示鼠标附近的曲线的点?介绍三种方法

news/2024/11/22 20:06:12/

使用ZedGraph绘制曲线图的时候,不仅仅是看曲线的走向,也需要查看曲线上某位位置处采集到的数据是多少。下面介绍三种方法,从简单到复杂。

文章目录

      • 1、使用自带的功能显示点的坐标
      • 2、 多条曲线的坐标点同时显示
      • 3、 多条曲线的坐标点同时显示(GDI绘制)

1、使用自带的功能显示点的坐标

使用ZedGraph自带的属性IsShowPointValues,来显示曲线点坐标

注 zedGraph是控件ZedGraph的名称将IsShowPointValues设置为true
 zedGraph.IsShowPointValues = true;

在这里插入图片描述
可以显示点的坐标,但是也有个缺点,只能显示某一条曲线上的一个点,如果我想两条曲线上的点一起显示呢,想对比一下数据?

2、 多条曲线的坐标点同时显示

既然已经可以显示某个点的坐标了,那么显示多个点,也应该是可以的。
ZedGraph提供了一个PointValueEvent坐标值事件,它的返回值是一个字符串。哎巧了,这个字符串就是显示坐标点值的字符串,那就可以随便发挥了。

  private string ZedGraph_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt){string info = "";if (zedGraph.GraphPane.CurveList.Count > 0){//有曲线if (  iPt > 0){foreach (CurveItem item in zedGraph.GraphPane.CurveList){//遍历曲线info += "(X:" + item.Points[iPt].X.ToString() + " , Y:"+ item.Points[iPt].Y.ToString() + ")\r\n";}}}return info;}

在这里插入图片描述
这么看着是不是觉得还少了什么,应该是一根标识鼠标位置的竖线。点都已经显示出来了,不要再加要求了。(客户根本不会听滴~)你以为就这一个要求,太年轻。能不能把显示坐标点的背景色改改啊,加上曲线的名称啦,更过分的是还得配上对应曲线的颜色。

3、 多条曲线的坐标点同时显示(GDI绘制)

客户就是上帝,为了这碎银几两,还是得折腰。
分析一下需求:1 加上鼠标位置的竖线(游标); 2 加上曲线名称(容易);3 改背景色 4 与曲线颜色对应上。

前面两种方法ZedGraph本质上是使用ToolTip来显示曲线坐标点的,但是ZedGraph并没有提供给我们有关于ToolTip的接口。

那么有两种方案:1 、更改ZedGraph的源码; 2、在ZedGraph上重绘一个类似ToolTip的提示框。

这里使用的是第二种方法。
思路: 在鼠标移动的时候,绘制曲线点的坐标以及竖直线游标。

关键的一个点是:鼠标距离曲线上最近的点是哪个呢?幸运的是,我们所关注的这个问题,ZedGraph有提供相关接口可以访问。通过FindNearestPoint
就可以找到最接近的点了。该函数有三个重载方法,可按需使用。

  public bool FindNearestPoint(PointF mousePt, CurveList targetCurveList, out CurveItem nearestCurve, out int iNearest);public bool FindNearestPoint(PointF mousePt, CurveItem targetCurve, out CurveItem nearestCurve, out int iNearest);public bool FindNearestPoint(PointF mousePt, out CurveItem nearestCurve, out int iNearest);

来吧,自己动手丰俭由人。
记得先把前面的IsShowPointValues设置为false,接着使用ZedGraph中的MousMove事件,在鼠标移动的时候获取最近点的坐标并使用GDI绘制。

 private void ZedGraph_MouseMove(object sender, MouseEventArgs e){ShowPonitByDraw(e);}private void ShowPonitByDraw(MouseEventArgs e){if (zedGraph.GraphPane.Chart.Rect.Contains(e.Location) == false){return;}using (Graphics graphics = zedGraph.CreateGraphics()){//在zedGraph上创建画布zedGraph.Refresh();using (Pen pen = new Pen(Color.Red, 2)){//创建画笔并设置样式pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;//画竖直线graphics.DrawLine(pen, e.X, zedGraph.GraphPane.Chart.Rect.Top, e.X, zedGraph.GraphPane.Chart.Rect.Bottom);if (zedGraph.GraphPane.CurveList.Count <= 0){return;}//找最近的一个点zedGraph.GraphPane.FindNearestPoint(e.Location, out CurveItem nearCurve, out int nearIndex);if (nearCurve == null || nearIndex < 0){return;}string tempMax = "";List<string> infoList = new List<string>();foreach (CurveItem curve in zedGraph.GraphPane.CurveList){//曲线名称 + 坐标点string tmp = curve.Points[nearIndex].Y.ToString();//填充到8个长度tmp =  tmp.PadLeft(8);tmp = tmp.Insert(0, curve.Label.Text + ": " );infoList.Add(tmp);if (tmp.Length > tempMax.Length){//记录最大的长度字符串tempMax = tmp;}}//文本绘制的一些字体和画刷配置Font font = new Font("Arial", 10, System.Drawing.FontStyle.Regular, GraphicsUnit.World);//得到一个字体绘制的大小SizeF tempSizeF = graphics.MeasureString(tempMax, font, (int)font.Size);//根据字符长度计算矩形的宽度 10是颜色矩形框的宽度float rectWidth = tempSizeF.Width * tempMax.Length;//高度float rectHeight = (infoList.Count + 1) * 18 + 5;//背景颜色框的左上角点的坐标,偏移2个像素Point point = new Point(e.X + 2, e.Y + 2);#region 计算左上角坐标 让背景矩形框在曲线的矩形框范围之内if (point.X + rectWidth > zedGraph.GraphPane.Chart.Rect.Right){point.X = (int)(point.X - rectWidth - 2);}if (point.Y + rectHeight > zedGraph.GraphPane.Chart.Rect.Bottom){point.Y = (int)(point.Y - rectHeight - 2);}#endregionpen.Color = Color.White;//绘制背景矩形框Rectangle rectBg = new Rectangle(point, new Size((int)rectWidth, (int)rectHeight));graphics.DrawRectangle(pen, rectBg);graphics.FillRectangle(new SolidBrush(Color.FromArgb(70, 70, 70)), rectBg);//颜色框的大小Size colorSize = new Size(10, 10);//绘制文本的颜色SolidBrush textBrush = new SolidBrush(Color.Red);//绘制文本内容 时间int time = 0;//"时间(ms):"string timeStr = "时间: " + nearCurve[nearIndex].X.ToString();graphics.DrawString(timeStr , font, textBrush,new Point(point.X + 20, point.Y + 5 + time * 16));for (int m = 0; m < infoList.Count; m++){time++;//绘制每条曲线的颜色小矩形框 Rectangle rect1 = new Rectangle(new Point(point.X + 5, point.Y + 5 + time * 16), colorSize);graphics.DrawRectangle(new Pen(zedGraph.GraphPane.CurveList[m].Color), rect1);graphics.FillRectangle(new SolidBrush(zedGraph.GraphPane.CurveList[m].Color), rect1);//绘制文本内容graphics.DrawString(infoList[m], font, textBrush,new Point(point.X + 20, point.Y + 5 + time * 16));}}}}

在这里插入图片描述
方法总比困难多,只要敢想且敢做。如果有更好的方法,请告诉我吖。

代码已打包在git:https://github.com/GXXMei/ZedGraphShowPoint
CSDN也有资源(土豪请随意):


http://www.ppmy.cn/news/21116.html

相关文章

令人窒息的百度面试题(正值换工作季,还不收藏???)

最近去网上找了一些百度的面经&#xff0c;冥冥之中在众多的面试题中打开了下边两个面试题&#xff1a; 2021百度前端社招面经 百度前端面试题分享&#xff0c;带答案 看完之后我直呼“哇哦~”&#xff0c;全部在我的射程范围之内。我该不会如此幸运到问的全会吧。 是的&am…

Leetcode刷题Day38-------------------动态规划

Leetcode刷题Day38-------------------动态规划 1. 理论基础 文章链接&#xff1a;https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html视频链接&#xff1a;https://www.bilibili.com/video/BV13Q4y197Wg题目链接&a…

【Spring】高并发下如何提高“锁”性能?

高并发下如何提高“锁”性能&#xff1f;前言减小锁持有时间减小锁粒度读写分离锁来替换独占锁锁分离锁粗化总结前言 在项目中&#xff0c;尤其是电商或者做游戏开发的&#xff0c;高并发是必然的&#xff0c;但在高并发的环境下&#xff0c;大家会经常使用到 锁 。 “锁” 是…

数据库管理-第五十五期 DBA(20230131)

数据库管理 2023-01-32第五十五期 DBA1 数据库管理员2 数据库3 云数据库4 “列强是我自己”&#xff1f;总结第五十五期 DBA 这两天在DBA圈子里有几篇文章比较火&#xff0c;《你怎么还在招聘DBA?》&#xff0c;《云数据库是不是智商税&#xff1f;》&#xff0c;《你怎么不招…

PyQt5编程基础 2.1 GUI程序的基本框架

文章目录 创建纯代码GUI程序 创建目录 新建程序 创建GUI程序的基本过程(代码分析) 导入模块 创建应用程序 创建窗体 使用窗体类的GUI程序框架 创建项目目录 窗体设计 修改窗体的windowTitle 放一个label 放一个Push Button 保存窗体 代码设计 将QtApp中的ui文…

图例legend语法及设置

(1)设置图例位置 使用loc参数 plt.legend(loc‘lower left’) 0‘best’1‘upper right’2‘upper left’3‘lower left’4‘lower right’5‘right’6‘center left’7‘center right’8‘lower center’9‘upper center’10‘center’ (2)设置图例字体 #设置字体大小 fontsi…

如果把小程序业务和研发管理都放到一个平台

伴随着互联网在中国进程的发展&#xff0c;线上研发效能及业务应用软件也不落后于时代进步的脚步&#xff0c;中国软件行业从未停止过持续的创新。 2022年&#xff0c;业务应用开发正在简化&#xff0c;研发效能也在提升&#xff0c;其中不得不提软件在协同促进、研发一体化管…

网络攻击(Cyber Attacks,也称赛博攻击)

网络攻击&#xff08;Cyber Attacks&#xff0c;也称赛博攻击&#xff09;是指针对计算机信息系统、基础设施、计算机网络或个人计算机设备的&#xff0c;任何类型的进攻动作。对于计算机和计算机网络来说&#xff0c;破坏、揭露、修改、使软件或服务失去功能、在没有得到授权的…