c# chart控件添加边界值线条以及扩展性功能

最近一致在开发能源平台,平台中很多能耗数据都是通过使用微软的chart控件进行图形呈现的。考虑到要给用户更为直观的呈现效果,需要对原有控件的功能进行扩展。微软chart控件没有第三方样chart样式炫酷,但是胜在可定制性强,中文手册详细,很多效果能够自己写出来。

  主要实现功能:1.最大值,最小值,平均值展示   2.鼠标移动到数据点绘制竖线,用tooltip的方式展示数据

  最终呈现效果如图:

解决方案:

(1)最大值,最小值,平均值呈现

  之前在网上找了好久都没有想要的效果,第三方控件往往都能直接设置。最开始我的解决方法是在ChartArea中添加单独的series展示最值,但是呈现效果不佳:

  在看了微软的技术手册后,发现可以在ChartArea中添加Stripline实现。以插入最大值线条为例,代码如下:

 //最大线条
                        double max = ammeter.Max();
                        StripLine stripMax = new StripLine();
                        stripMax.Text = string.Format("最大:{0:F}", max);//展示文本
                        stripMax.BackColor = Color.FromArgb(208, 109, 106);//背景色
                        stripMax.Interval = 0;//间隔
                        stripMax.IntervalOffset = max;//偏移量
                        stripMax.StripWidth = 0.001;//线宽
                        stripMax.ForeColor = Color.White;//前景色
                        stripMax.TextAlignment = StringAlignment.Near;//文本对齐方式
                        chartInfo.ChartAreas["ammeter"].AxisY.StripLines.Add(stripMax);//添加到ChartAreas中

(2)实现鼠标移动到数据点绘制竖线,用tooltip的方式展示数据

  chart中可以对画图区域使用HitTest进行数据点检测,之前的方案是在鼠标移动的过程中对当前鼠标的坐标区域(x为当前坐标,y为画图区域的高 )进行数据检测,移动的过程中绘制跟随鼠标的线条。实现后发现效果并不是很好,HitTest在数据点周围的series都会判定为数据点,所以线条一直在绘制,而想要的效果鼠标移动的过程中仅在数据点时才绘制竖线。

  要在数据点位置绘制线条需要获得数据点的相对坐标,网上一直没有找到解决办法。起初通过x,y轴的偏移量,0点的坐标,绘图区域的坐标可以实现相对坐标的获取,但是发现这样有时计算会有很大的偏差。同样通过查找技术手册后,发现微软给了获取x,y轴相对坐标的方法。

  Point lastPoint = new Point();//上次点的坐标
        ToolTip tp = new ToolTip();//tooltip展示条
        //绘制竖线坐标
        Point p1 = new Point(0, 0);
        Point p2 = new Point(0, 0);
        /// <summary>
        /// 鼠标移动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chartInfo_MouseMove(object sender, MouseEventArgs e)
        {
            this.Refresh();//刷新chart,使用clear会使chart上的图形完全清空
            Pen pen = new Pen(Color.Yellow);
            Graphics g = chartInfo.CreateGraphics();
            string seriesInfo = ""; //tooltip文本
            if (e.Location != lastPoint)//如果在上次点的位置不进行操作,此处操作会引发chart控件的refresh操作造成界面闪烁
            {
                for (int y = 0; y <= chartInfo.Size.Height; y++)//线条范围进行碰撞检测
                {
                    HitTestResult result = chartInfo.HitTest(e.X, y);
                    if (result.ChartElementType == ChartElementType.DataPoint)
                    {
                        foreach (DataPoint dpp in result.Series.Points)//数据点默认样式 使用索引的方式修改偶尔会出现无法正常修改完
                        {
                            dpp.MarkerStyle = MarkerStyle.Diamond;
                            dpp.MarkerColor = Color.White;
                            dpp.MarkerSize = 5;
                        }
                        int i = result.PointIndex;
                        DataPoint dp = result.Series.Points[i];
                        dp.MarkerStyle = MarkerStyle.Star4;//捕获到数据点的样式
                        dp.MarkerColor = Color.Orange;
                        dp.MarkerSize = 15;
                        //获取数据点的相对坐标
                        p1 = new Point((int)chartInfo.ChartAreas["ammeter"].AxisX.ValueToPixelPosition(dp.XValue), 0);
                        p2 = new Point((int)chartInfo.ChartAreas["ammeter"].AxisX.ValueToPixelPosition(dp.XValue), chartInfo.Size.Height);
                        seriesInfo = string.Format("分项:{0}  时间:{1}  能耗值:{2}", result.Series.LegendText, DateTime.FromOADate(dp.XValue), dp.YValues[0]);
                        break;
                    }
                }
                tp.AutoPopDelay = 5000;//展示tooltip
                tp.ShowAlways = false;
                tp.IsBalloon = true;
                tp.SetToolTip(chartInfo, seriesInfo);
            }
            lastPoint = e.Location;//记录本次位置
            g.DrawLine(pen, p1, p2);//绘制竖线
        }

写在最后

  微软技术手册真香

原文地址:https://www.cnblogs.com/akagreen/p/10335091.html

时间: 2024-11-10 14:44:21

c# chart控件添加边界值线条以及扩展性功能的相关文章

WinForm Chart控件使用记录(由于制作饼装,柱状,折线图)

由于公司的winform项目需要用到Chart图表,抽空研究了一下,特地发上来给大家做个参考,就目前而言用到的属性说明都做了注释: 主要用到Chart控件图表区域的属性有五个属性 Annotations 批注集合(我没怎么用到,但是配置的话会在图标区域出现一些可以备注的东西吧) ChartAreas 图表区属性:主要设置图标数据的背景,比如3D或者隐藏还是显示横纵轴交叉线,分块颜色显示等 Lengends 图表图例集合 主要设置图表边说明的一些东西,这次项目没什么用到,但是觉得这个基本没啥用,有

使用Chart控件进行实时监控

Chart作为微软提供绘制图表的控件,在刚开始使用时非常的迷茫,因为功能强大,涉及到的知识多, 一开始难以接收过来,但后天经过查找资料,耐心学习,终于还是有了一定的收获. Chart相当于一个大的图纸,可以包含很多小的图纸ChartArea,一个ChartArea可以包含很多的Series, Series即Point,画在ChartArea上的数据. 主要的思想就是添加Points的同时改变X轴的显示范围,以此来达到动态显示的目的. 代码解析: Chart的相关设置 因为Chart控件是直接托入

解决 ASP.NET Chart 控件出错 为 ChartImg.axd 执行子请求时出错

    今天在做一个关于MVC的MSChart时,本以为很简单的一个东西,后面把数据什么的都绑定好后,满以为OK了,一运行就报错“ ASP.NET Chart 控件出错 为 ChartImg.axd 执行子请求时出错 ”,纠结~~后面网上搜了一下这方面的解决方案,然后结合自己的,最后做了一个小的总结: 一.在vs2008中,你需要按照如下的步骤进行配置: 1.<pages controlRenderingCompatibilityVersion="3.5" enableEvent

C#用serialPort和chart控件实现简单波形绘制

先看最终的效果图: 主要实现功能是将串口发送过来的数据按波形显示 注:本例是以串口调试助手和虚拟串口VSPD软件模拟串口发送数据的,详细说明见下文 说明: serialPort的ReadByte()方法用于从System.IO.Ports.SerialPort输入缓冲区中同步读取一个字节. chart控件的spline为曲线图,以光滑的曲线连接各点. 几个代码块说明: (1) private void SearchAndAddSerialToCombobox(SerialPort Myport,

Chart控件使用初步

学习了Chart控件的初步使用方法,生成柱形图和饼图.    <asp:Chart ID="Chart1" runat="server" Width="553px" Height="403px">             <Series>                 <asp:Series LegendText="得票数" Name="Series1" 

VS2010 Chart控件(一)Chart控件在ASP.NET网站中的应用示例详解(C#语言)

步骤如下: 1. Chart控件(一)Chart控件在ASP.NET网站中的应用示例详解(C#语言)" title="VS2010 Chart控件(一)Chart控件在ASP.NET网站中的应用示例详解(C#语言)" action-data="http%3A%2F%2Fs8.sinaimg.cn%2Fmw690%2F6988593etx6DhZWSOATc7%26690" action-type="show-slide" style=&

C# Chart控件,chart、Series、ChartArea曲线图绘制的重要属性

原文有备份,如有错误和需要改进的地方,请不吝指正会继续修改的 8个月没写博客了- -,一来是有不想继续干开发的想法,二来是赖的写,三来还是不想总结.所以为了继续坚持自己的开发和总结的信念,总结一下C# chart控件的一些基本属性,由于属性太多了,一时半会儿写不完,以后继续补充,这里总结重要的常用的属性 为避免耽误不喜欢这种曲线图效果的亲们的时间,先看一下小DEMO效果图: 先简单说一下,从图中可以看到一个chart可以绘制多个ChartArea,每个ChartArea都可以绘制多条Series

C# chart控件绘制曲线

在.NET中以前经常用GDI去绘制,虽然效果也不错,自从.NET 4.0开始,专门为绘制图表而生的Chart控件出现了,有了它,就可以轻松的绘制你所需要的曲线图.柱状图什么的了. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.C

c#给用户控件添加事件处理程序

1.首先在usercontrol后台添加如下代码: public partial class MyControl: UserControl { //添加事件代理       public event EventHandler AX; //在需要响应的事件中添加 private void MyControl_MouseClick(object sender, MouseEventArgs e)        {            if (AX != null)            {