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

news2024/11/24 2:36:59

使用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);
                    }
                    #endregion

                    pen.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.coloradmin.cn/o/189141.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

100%国产C2000,P2P替代TMS320F280049C,独立32位双核CPU,主频高达400MHz

一、特性参数 1、独立双核&#xff0c;32位CPU&#xff0c;单核主频400MHz 2、IEEE 754 单精度浮点单元 &#xff08;FPU&#xff09; 3、三角函数单元 &#xff08;TMU&#xff09; 4、1MB 的 FLASH &#xff08;ECC保护&#xff09; 5、1MB 的 SRAM &#xff08;ECC保护&…

docker基础简介

一、docker架构 二、Docker 基本命令 1、查看 Docker 版本 查看 Docker 版本包括 Docker 版本号、API 版本号、对应的 Git Commit、Containerd 和 runC的版本信息等。 # docker version Client: Docker Engine - Community Version: 20.10.4 API version: 1.40 Go version: …

新手小白做跨境电商应该从哪里入手?

想从事跨境电商先从哪里入手?米贸搜整理如下&#xff0c;希望可以帮助到你跨境电商平台&#xff0c;如&#xff1a;Amazon、eBay、aliexpress、Cdiscount、wish等。想从事跨境电商&#xff0c;你得搭建电商团队&#xff0c;先从跨境电商平台的入驻入手&#xff0c;弄清楚入驻条…

【设计模式】行为型模式·模板方法模式

学习汇总入口【23种设计模式】学习汇总(数万字讲解体系思维导图) 一.概述 定义一个操作中的算法骨架&#xff0c;而将算法的一些步骤延迟到子类中&#xff0c;使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 在面向对象程序设计过程中&#xff0c;程序员常…

HTB_Inclued_TFTP文件包含与LXD提权

文章目录信息收集TFTPLXD 提权环境安装报错信息收集 开放80端口&#xff0c;url为http://ip:port?filehome.php 测试文件包含&#xff0c;本地包含成功&#xff0c;远程失败&#xff0c;尝试上传后门木马反弹shell 根据图示&#xff0c;网站目录为var/www&#xff0c;其他功…

minio 使用docker安装和入门案例demo

minio目录1.安装2.页面web访问3.在界面上传4.使用api上传5.使用api下载目录 公司目前用到文件上传&#xff0c;考虑到费用等情况&#xff0c;可以在公司自己的服务器上搭建一下。本人记录minio的使用情况。 “前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&…

搭建 SpringBoot 项目

创建 SpringBoot 项目 配置application.properties 根据自己数据库进行配置 spring.datasource.nameexamspring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.usernameroot spring.datasource.passwordroot spring.datasource.urljdbc:mysql://1…

振弦采集模块VMTool配置工具 快速测试功能

振弦采集模块VMTool配置工具 快速测试功能 本章演示在计算机上通过 VMTool 工具读取振弦传感器数据。 假设您的计算机已经有至少一个空闲的 COM 接口。 1 检查 COM 接口名称 在操作系统桌面右键点击“ 我的电脑” &#xff0c; 选择【 属性】&#xff0c;弹出计算机属性对话框&…

X-Bogus流程分析

声明&#xff1a;本文仅限学习交流使用&#xff0c;禁止用于非法用途、商业活动等。否则后果自负。如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01;本教程也没有专门针对某个网站而编写&#xff0c;单纯的技术研究 目录 一、混淆还原 二、插桩还原 三、还原X-B…

关于Vue中Diff算法详解

一、(Diff)是什么? diff 算法是一种通过同层的树节点进行比较的高效算法 1.1. 特点&#xff1a; 比较只会在同层级进行, 不会跨层级比较在diff比较的过程中&#xff0c;循环从两边向中间比较diff 算法的在很多场景下都有应用&#xff0c;在 vue 中&#xff0c;作用于虚拟 dom…

DAMA数据管理知识体系指南之数据治理

第3章 数据治理 3.1 简介 数据治理是对数据资产管理行使权力和控制的活动集合(规划、监控和执行&#xff09;。数据治理职能指导其他数据管理职能如何执行。数据治理是在高层次上执行数据管理制度。 3.2 概念和活动 有效的数据管理&#xff0c;特别是在数据治理方面&#…

2023最新前端面试题4(持续更新)

JavaScript 59、JS的几条基本规范 1、不要在同一行声明多个变量 2、请使用/&#xff01;来比较true/false或者数值 3、使用对象字面量替代new Array这种形式 4、不要使用全局变量 5、Switch语句必须带有default分支 6、函数不应该有时候有返回值&#xff0c;有时候没有返回值 …

如何写出有效的单元测试?

如何写出有效的单元测试&#xff1f; 目录&#xff1a;导读 什么是单元测试 为什么需要单元测试 什么是有效的单元测试 为什么有效的单元测试如此重要 如何写有效的单元测试 补充单元测试应该从哪里开始 可测试的设计 单元测试与重构 做不到TDD&#xff0c;可以做到测…

LaoCat带你认识容器与镜像(四【下】)

基础概念章节是告一段落了&#xff0c;不知道各位童鞋是否阅读的顺畅&#xff0c;欢迎各位童鞋踊跃的提出意见和看法并指正。 本章内容 Dockerfile基础命令详解。 本文实操全部基于Ubuntu 20.04 宿主机 > linux服务器本身 上节粗略介绍了Dockerfile相关命令&#xff0c;这节…

国电投-风机叶片开裂故障预警比赛(记录)

1 前言 1-1 简介 DataFountain平台举办的比赛&#xff0c;赛题&#xff1a;风机叶片开裂故障预警。以下是比赛链接:风机叶片开裂故障预警 Competitions - DataFountain 1-2 任务背景 SCADA是风场设备管理、监测、和控制的重要系统&#xff0c;通过实时收集风机运行的环境参数、…

oracle direct path read等待事件处理案例

一 问题描述 收到短信告警&#xff0c;提示direct path read(110)。 直接路径读取不过SGA缓存&#xff0c;直接从磁盘上读数据&#xff0c;每次查询都会产生大量的物理读&#xff0c;导致IO比较高&#xff0c;影响数据库性能。 二 排查思路 生成AWR报告及ASH报告&#xff0…

springboot 整合mybatis-plus的自动生成代码包含service和controller

版本信息springboot&#xff1a;<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.13.RELEASE</version></parent>mybatis相关依赖版本如下&#xff1a…

压缩包文件上传导致覆盖rce

制作恶意压缩包 tgao.jsp文件内容&#xff1a; <html> <body><%out.println("zip slip getshell.");%> </body> </html>编写python脚本将jsp文件内容内容压缩至DocSystem.war中&#xff0c;并指定name为../../DocSystem/tgao.jsp&am…

ElasticSearch - RestClient查询文档

目录 查询文档-快速入门 查询文档-match查询 查询文档-精确查询 查询文档-布尔查询 查询文档-排序和分页 查询文档-高亮显示 查询文档-快速入门 文档的查询基本步骤包括&#xff1a; (1)准备Request对象(2)准备请求参数&#xff0c;构建查询条件(3)发起请求&#xff0c;得…

OpenSSL下载安装教程

OpenSSL下载 &#xff08;加急&#xff09;下载地址&#xff1a;Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 首先&#xff0c;进入官网 Shining Light Productions - Home &#xff0c;可以看到如下界面&#xff1a; 这里演示用的版本是V1.1的版…