周公的专栏

执子之手,与子偕老

周金桥ID:zhoufoxcn
162891次访问,排名447好友146人,关注者145
6年的Java和.net开发经验。熟悉数据库及软件性能优化。
zhoufoxcn的文章
原创 141 篇
翻译 5 篇
转载 70 篇
评论 335 篇
周公的公告
说明:本博客示例代码自2007年以后所写的代码均是在Vs2005(.net2.0)下编写,在Vs2003(.net1.1)下可能编译不会通过。
做人要厚道,转载请注明来源于本博客!
最近评论
liuyunsx:你好。你知道怎么把一张图片压缩成梯形。或者说把图片填充在梯形框里。但是不能是平铺的。要拉伸的那种。
如果你有源码可以发到liuyun_84@163.com里面。非常感谢。
CaptainV:谢谢博主分享!美信私募个人所得税计算器
Airton:我试用了一下很方便,但不知道为什么我定义的菜单在运行时不见了,请问这个控件不支持菜单吗?
zhangyaoting196:

WWW.soAsp.net 编程学习网 技术+ 实例应用 讲解不错。 推荐大家!

有很多 技术资料也很好!









xuevb888:支持,思路真的很不错
文章分类
收藏
    相册
    .net
    mengyao||Andy 路鑫(RSS)
    The Code Project
    剑了(RSS)
    山西.net俱乐部
    张子阳(RSS)
    Java
    张森炜的博客(RSS)
    娱乐资源
    天下网
    天下网生活论坛(RSS)
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 用C#绘制实时曲线图收藏

    新一篇: 用C#编写网页小应用程序(Applet) | 旧一篇: C#调用Windows API详解(上)

     在实际项目中我们经常需要绘制一些实时的数据图片,比如当前各公司的用水量、用电量还有播放声音视频时实时显示当前的声频等等,在我们最熟悉的任务管理器也有这么一个功能,用来表示当前CPU的使用频率,最近笔者刚刚给朋友完成了一个类似的功能图,用曲线图来实时表示一些实际数据,由于形象直观,很受客户欢迎。
    不过由于某些原因,本人不能将实际项目中的代码拿出来给大家分享,只能模拟了一个简单的实现,代码没有过多优化,所以还存在很多可以优化的地方,希望有兴趣的朋友自己完善。

    为了操作和应付变化,所以将绘制曲线图的功能单独封装成一个类,里面的数据完全是模拟的,在横向坐标上每个像素间隔用一个点来控制(实际中可能会加大这个距离),横向是个随机生成的数(实际开发中这应该来自我们的实时数据按比率计算得来的),显示窗体中用到了一个线程来定时绘制实时曲线。

    实际代码如下:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Drawing;
    using System.Drawing.Imaging;
    
    namespace RealtimeCurve
    {
        /// 
        /// 说明:实时图片生成类,在本例中横向坐标上每个像素都会有一个控制点
        /// 实际开发中可以减少控制点,比如每5个像素用一个控制点
        /// 这样的效果或许更加逼真
        /// 作者:周公
        /// 日期:2008-07-21
        /// 首发地址:http://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspx
        /// 
        public class RealTimeImageMaker
        {
            private int width;//要生成的曲线图的宽度
            private int height;//要生成的曲线图的高度
            private Point[] pointList;//用来绘制曲线图的关键点,依次将这些点连接起来即得到曲线图
            private Random random = new Random();//用于生成随机数
            private Bitmap currentImage;//当前要绘制的图片
            private Color backColor;//图片背景色
            private Color foreColor;//图片前景色
            /// 
            /// 图片的高度
            /// 
            public int Height
            {
                get { return height; }
                set { height = value; }
            }
    	
            /// 
            /// 图片的宽度
            /// 
            public int Width
            {
                get { return width; }
                set { width = value; }
            }
            /// 
            /// 构造函数,指定生成的曲线图的宽度和高度
            /// 
            /// 要生成的曲线图的宽度
            /// 要生成的曲线图的高度
            public RealTimeImageMaker(int width, int height):this(width,height,Color.Gray,Color.Blue)
            {
                
            }
            /// 
            /// 构造函数,指定生成的曲线图的宽度、高度及背景色和前景色
            /// 
            /// 要生成的曲线图的宽度
            /// 要生成的曲线图的高度
            /// 曲线图背景色
            /// 曲线图前景色
            public RealTimeImageMaker(int width, int height, Color backColor, Color foreColor)
            {
                this.width = width;
                this.height = height;
                this.backColor = backColor;
                this.foreColor = foreColor;
                pointList = new Point[width];
                Point tempPoint;
                //初始化曲线上的所有点坐标
                for (int i = 0; i < width; i++)
                {
    
                    tempPoint = new Point();
                    //曲线的横坐标沿x轴依次递增,在横向位置上每个像素都有一个点
                    tempPoint.X = i;
                    //曲线上每个点的纵坐标随机生成,但保证在显示区域之内
                    tempPoint.Y = random.Next() % height;
                    pointList[i] = tempPoint;
                }
            }
            /// 
            /// 获取当前依次连接曲线上每个点绘制成的曲线
            /// 
            /// 
            public Image GetCurrentCurve()
            {
                //currentImage = historyImage.Clone(new Rectangle(1, 0, width - 1, height), PixelFormat.Format24bppRgb);
                currentImage = new Bitmap(width, height);
                Point p;
                //将当前定位曲线图的坐标点前移,并且将横坐标减1,
                //这样做的效果相当于移除当前第一个点
                for (int i = 0; i < width-1; i++)
                {
                    p = pointList[i + 1];
                    pointList[i] = new Point(p.X-1,p.Y);
                }
                Point tempPoint = new Point();
                //新生成曲线图定位点的最后一个点的坐标
                tempPoint.X = width;
                //曲线上每个点的纵坐标随机生成,但保证在显示区域之内
                tempPoint.Y = random.Next(DateTime.Now.Millisecond) % height;
                //在最后再添加一个新坐标点
                pointList[width-1]=tempPoint;
                Graphics g = Graphics.FromImage(currentImage);
                g.Clear(backColor);
                //绘制曲线图
                g.DrawLines(new Pen(foreColor), pointList);
                g.Dispose();
                return currentImage;
            }
        }
    }
    窗体关键代码:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace RealtimeCurve
    {
        /// 
        /// 说明:显示实时曲线图的窗体
        /// 作者:周公
        /// 日期:2008-07-21
        /// 首发地址:http://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspx
        /// 
        public partial class FormRealTime : Form
        {
            Thread thread;
            RealTimeImageMaker rti;
            Color backColor = Color.Black;//指定绘制曲线图的背景色
            public FormRealTime()
            {
                InitializeComponent();
                rti = new RealTimeImageMaker(Width, Height, backColor, Color.Green);
                thread = new Thread(new ThreadStart(Run));
                thread.Start();
            }
    
            private void Run()
            {
                while (true)
                {
                    Image image = rti.GetCurrentCurve();
                    Graphics g = CreateGraphics();
                    //用指定背景色清除当前窗体上的图象
                    g.Clear(backColor);
                    g.DrawImage(image, 0, 0);
                    g.Dispose();
                    //每秒钟刷新一次
                    Thread.Sleep(1000);
                }
            }
    
            private void FormRealTime_FormClosing(object sender, FormClosingEventArgs e)
            {
                //在窗体即将关闭之前中止线程
                thread.Abort();
            }
        }
    }

    程序最终的运行结果截图:

    全部程序代码请到http://download.csdn.net/zhoufoxcn下载。

    发表于 @ 2008年07月21日 01:05:00|评论(loading...)|收藏

    新一篇: 用C#编写网页小应用程序(Applet) | 旧一篇: C#调用Windows API详解(上)

    评论

    #xiongxuanwen 发表于2008-07-21 09:51:31  IP: 219.239.6.*
    你这是每隔1秒钟刷新一次,已经有闪烁的现象了。如果要求每隔1毫秒刷新一次,而且不能有闪烁的现象,用你的这种方法肯定不行,该怎么优化呢?
    2008-07-21 10:35:35作者回复
    方法很多:<br />比如这个程序有个特点:每次只从数组中移除第一个控制点,在最后增加一个控制点,绘制图片的时候也就是将图片向前移动一个像素,所以可以利用Clone的方式将从第二个像素到最后所有的图片复制到新图,只绘制最后新增的一个点就行了。这样速度就快一些了。另外还可以利用双缓冲机制等等,方法还是很多的,只不过今早时间有限(写这篇文章的时候已经是今天早晨2点了),今天上午还要上班,所以我没有进一步优化去。<br />我这里闪烁的原因是每次我都用背景色重新绘制控件表面,然后再绘制新图像的,所以有闪烁。
    #awanghero 发表于2008-07-21 16:18:01  IP: 59.41.8.*
    这是最笨的办法,至少要用双缓冲技术,否则这么大的屏肯定会闪屏。为了提高速度,可以直接锁定BMP数据区直写数据。
    要好性能,最好用VC+双缓冲技术,最好用dirextX来画
    2008-07-21 16:27:04作者回复
    我已经说了,由于某些方面的原因,我不能把实际项目中的代码拿出来给大家看,我只能抛砖引玉,给大家一个简单思路,大家自己尝试优化吧。
    #walkghost 发表于2008-07-21 18:13:42  IP: 222.190.5.*
    "不过由于某些原因,本人不能将实际项目中的代码拿出来给大家分享"
    ???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

    请谨记:技术无界限!你这个画曲线的功能又不是你朋友的那个项目的核心算法、主要功能。干嘛不能拿出来跟大家分享?到底是什么原因?
    #walkghost 发表于2008-07-21 18:17:04  IP: 222.190.5.*
    所以我觉得你这篇文章写得不像是分享技术,倒是在炫耀技术,况且我没发现你的代码有哪些亮点,就像说明文而非散文。
    拍得有点儿重了,纯属个人看法,不爱听的话你就删去吧。
    2008-07-21 19:14:56作者回复
    没有什么爱听不爱听,我不会删除的。我只是尽量提供一种思路而已,你说这个代码没有亮点本来就是正确的,这个代码一点亮点都没有,纯粹是把一些知识简单撮合到一起罢了。这篇文章当然是说明文了,很少见到有人写散文介绍技术的。连你都看出来了这篇文章没有亮点,所以我自然不会拿它炫耀了。<br />我这篇文章比较适合初学者和有一定基础的开发人员。
    #carefree31441 发表于2008-07-21 18:30:05  IP: 221.204.242.*
    写的不错啊 ,很有实用价值,支持ing,继续努力!
    #thezoner 发表于2008-07-22 08:55:36  IP: 117.28.163.*
    QQ留言代码
    #gougou203 发表于2008-07-22 10:06:50  IP: 221.226.124.*
    既然提到了VC+双缓冲技术,怎么不一起说说呢。这样大家也明白一点。
    #mutnike 发表于2008-07-22 19:42:10  IP: 121.32.125.*
    尊重别人的劳动成果呀,你认为自己很牛了看就别看嘛,毕竟还是很多人处在学习阶段,很需要这些知识,谢谢博主的无私贡献,继续努力……
    #strean 发表于2008-07-22 21:58:47  IP: 124.93.243.*
    谢谢。。真的
    #lujiaxing2007 发表于2008-07-22 22:39:57  IP: 221.218.217.*
    哎 哪个公司没有点商业机密呢
    原谅楼主吧
    不是哪个公司都是慈善机构的!!!!

    音乐无界限,那它还有版权呢

    佩服佩服佩服佩服
    #个性天空 发表于2008-07-23 10:26:52  IP: 60.191.201.*
    这世界 学习了!
    #xlatme 发表于2008-07-23 12:38:57  IP: 222.185.251.*
    不错,不错
    #xxrl 发表于2008-07-23 13:24:00  IP: 117.12.237.*
    貌似绘制实时曲线图的双缓冲代码不是什么机密
    2008-07-24 18:17:03作者回复
    引用别人的评论:<br /> PCI_E 发表评论 [支持:1人 反对:0人] <br />不过,这种东西最主要的是有个思路起点:)<br /><br />时间:2008-07-24 17:08:20 来自:58.246.175.*
    #Colin 发表于2008-07-23 13:27:21  IP: 58.246.80.*
    要不刷新也很简单,要用多张图拼在一起,没阁一端时间,一就的替换新的,并把所有的图片向左做位移,搞定!
    #flydreamings 发表于2008-07-23 15:47:49  IP: 218.22.34.*
    很不错,支持一下
    #flydreamings 发表于2008-07-23 15:47:58  IP: 218.22.34.*
    很不错,支持一下
    #hnczljt 发表于2008-07-24 15:05:43  IP: 211.136.253.*
    大哥,能不能导出Excel时导出图表向导啊,就是Excel里面的数据分析图
    2008-07-24 18:03:30作者回复
    尝试用OWC看看。
    #hnczljt 发表于2008-07-24 15:06:00  IP: 211.136.253.*
    大哥,能不能导出Excel时导出图表向导啊,就是Excel里面的数据分析图
    #huasn 发表于2008-07-25 14:43:35  IP: 61.144.176.*
    很好
    #xrwang 发表于2008-07-26 16:35:50  IP: 222.245.138.*
    @walkghost
    如果您觉得楼主的文章有不完善的地方,大可以自己写一篇更好的出来给大家学习,不能冷嘲热讽吧。
    我觉得楼主的奉献精神不错呀。
    #wjl_0226 发表于2008-07-27 13:10:12  IP: 61.175.135.*
    那些所谓的牛人如果觉得自己更牛逼的话就也发一个出来看看啊
    在这里拿砖乱拍算什么玩意啊!·
    #ty 发表于2008-07-27 13:56:47  IP: 218.90.74.*
    ggggggggggggggggg
    #fly_to_the_winds 发表于2008-07-28 15:14:47  IP: 219.141.23.*
    收藏起,呵呵
    #hcn5460 发表于2008-07-28 15:24:00  IP: 220.248.243.*
    不错啊,谢谢分享。
    #jialiliu 发表于2008-07-28 15:38:11  IP: 222.85.71.*
    不错.学习.
    #aoksdasd90 发表于2008-07-28 16:11:27  IP: 210.176.30.*
    我们是http://www.kingofcoders.com(编程王)网站的全队成员,我仅代表我们团队(kingofcoders全体成员)给您发了这封电子邮件!

    kingofcoders创始人Peter(张民杰)目前在香港,主要从事计算机软件和操作系统的开发,kingofcoders的合作者之一兼业务主管yatell(胡勇)目前在上海,主要从事计算机软件,特别是企业级开发(在这里http://www.kingofcoders.com/leaderTeam.php 有咱们团队的详细介绍,欢迎浏览),就这些来自五湖四海的年轻人通过Internet组合在一起,大家默认配合,将kingofcoders从心中的一个虚拟的东西变成了实物,那就是www.kingofcoders.com 站点.

    目前阶段,咱们团队的主要任务是办起一份属于kingofcoders的IT电子杂志,各位通过kingofcoders电子杂志可以了解一些行业的最新动态,了解一些国外国内的一些新技术发展,从杂志中学到一些知识和经验。

    由于受到kingofcoders初期阶段人手不够,对行业不太了解,技术,资金等方面的限制我们通过互联网召集优秀的原创文章不失为一种行之有效的方法!
    内容(目前阶段)准备征集的文章是涉及到Java体系,.net体系 web2.0体系 PHP体系,OS体系五个体系;
    当然如果您有其他计算机方面的原创优秀文章也是欢迎的!
    相信各位看到一个站点从建立到成长到壮大的过程是非常自豪和有成就感的事,因为我们每个人都注入了自己的一份力量!

    忠诚的希望您投稿给我们!我们将在kingofcoders主页和kingofcoders杂志留下您的足迹,也会给您一点微薄的稿费(50RMB整),仅代表我们kingofcoders的心意,当然如果您拒绝签收,我们将会以您的名义捐给四川灾民,衷心的希望四川灾民早日恢复生产生活!

    如果你对kingofcoders站点有什么建议和意见也希望给我们发Email,联系我们!在这里我代表kingofcoders全体成员感谢您,

    感谢您对kingofcoders的支持,感谢您对中国软件事业的支持!

    我们的联系方式是:Email:mcheung63@hotmail.com

    #aoksdasd90 发表于2008-07-28 16:14:39  IP: 210.176.30.*
    我们是http://www.kingofcoders.com(编程王)网站的全队成员,我仅代表我们团队(kingofcoders全体成员)给您发了这封电子邮件!

    kingofcoders创始人Peter(张民杰)目前在香港,主要从事计算机软件和操作系统的开发,kingofcoders的合作者之一兼业务主管yatell(胡勇)目前在上海,主要从事计算机软件,特别是企业级开发(在这里http://www.kingofcoders.com/leaderTeam.php 有咱们团队的详细介绍,欢迎浏览),就这些来自五湖四海的年轻人通过Internet组合在一起,大家默认配合,将kingofcoders从心中的一个虚拟的东西变成了实物,那就是www.kingofcoders.com 站点.

    目前阶段,咱们团队的主要任务是办起一份属于kingofcoders的IT电子杂志,各位通过kingofcoders电子杂志可以了解一些行业的最新动态,了解一些国外国内的一些新技术发展,从杂志中学到一些知识和经验。

    由于受到kingofcoders初期阶段人手不够,对行业不太了解,技术,资金等方面的限制我们通过互联网召集优秀的原创文章不失为一种行之有效的方法!
    内容(目前阶段)准备征集的文章是涉及到Java体系,.net体系 web2.0体系 PHP体系,OS体系五个体系;
    当然如果您有其他计算机方面的原创优秀文章也是欢迎的!
    相信各位看到一个站点从建立到成长到壮大的过程是非常自豪和有成就感的事,因为我们每个人都注入了自己的一份力量!

    忠诚的希望您投稿给我们!我们将在kingofcoders主页和kingofcoders杂志留下您的足迹,也会给您一点微薄的稿费(50RMB整),仅代表我们kingofcoders的心意,当然如果您拒绝签收,我们将会以您的名义捐给四川灾民,衷心的希望四川灾民早日恢复生产生活!

    如果你对kingofcoders站点有什么建议和意见也希望给我们发Email,联系我们!在这里我代表kingofcoders全体成员感谢您,

    感谢您对kingofcoders的支持,感谢您对中国软件事业的支持!

    我们的联系方式是:Email:mcheung63@hotmail.com

    #wendong 发表于2008-07-29 17:19:52  IP: 123.113.73.*
    dd
    #wendong 发表于2008-07-29 17:19:57  IP: 123.113.73.*
    dd
    #wendong 发表于2008-07-29 17:20:26  IP: 123.113.73.*
    aa
    #xky191982810 发表于2008-07-30 22:06:49  IP: 219.141.47.*
    如果我在每个控制点标注其坐标值怎么实现啊 请给思路!!!
    #bbcer314 发表于2008-07-31 08:49:24  IP: 60.176.201.*
    写的不错啊 ,很有实用价值,支持ing,继续努力!
    #bbcer314 发表于2008-07-31 08:49:52  IP: 60.176.201.*
    写的不错啊 ,很有实用价值,支持ing,继续努力!
    #jacksu19 发表于2008-07-31 10:13:00  IP: 125.33.198.*
    XXX === ***
    xiongxuanwen 发表于2008-07-21 09:51:31 IP: 219.239.6.*
    你这是每隔1秒钟刷新一次,已经有闪烁的现象了。如果要求每隔1毫秒刷新一次,而且不能有闪烁的现象
    *** XXX ===
    这个“要求每隔1毫秒刷新一次,而且不能有闪烁的现象”需求,是给谁准备的呢? 假如曲线是给人看的,哪么每秒钟能有30次的刷新就已经“够”快了。 每秒钟刷新1000次,恐怕只有超人才能够分辨了。 假设你能够分辨每秒刷新1000次的画面,你是否能够根据观察到的画面,以同样“快”的做出控制响应呢? 哎。。。 砖家提出的需求就是高!不切实际。
    #zql177 发表于2008-08-03 11:34:24  IP: 221.122.70.*
    写的不错啊 ,很有实用价值,支持ing,正在学习!
    #277894613 发表于2008-08-06 12:53:54  IP: 117.22.186.*
    开源的东西多了,不用自己写的
    #277894613 发表于2008-08-06 12:53:59  IP: 117.22.186.*
    开源的东西多了,不用自己写的
    #277894613 发表于2008-08-06 12:54:00  IP: 117.22.186.*
    开源的东西多了,不用自己写的
    #277894613 发表于2008-08-06 12:54:01  IP: 117.22.186.*
    开源的东西多了,不用自己写的
    #277894613 发表于2008-08-06 12:54:09  IP: 117.22.186.*
    开源的东西多了,不用自己写的
    2008-08-06 21:41:55作者回复
    是的,开源的东西不少,不过了解一下思路,自己写写其实也不麻烦。
    这样即使以后用开源的,也知道怎么回事。
    #277894613 发表于2008-08-06 12:54:38  IP: 117.22.186.*
    不好意思,刚网络卡,多点了几下
    #Fiction 发表于2008-08-06 13:07:42  IP: 118.26.231.*
    good,作个标记.
    #penglei 发表于2008-08-06 13:31:51  IP: 222.35.174.*
    看不懂啊 能不能教下啊
    2008-08-06 21:40:36作者回复
    建议你先看看GDI+方面的入门书籍,了解一下Pen,Brush,Font,Graphics,Rectangle,Image等相关概念。
    #QQ176527478 发表于2008-08-06 14:59:59  IP: 222.35.174.*
    LZ加我QQ好吗 我是菜鸟!急需你们这些老鸟的帮忙呀!我现在也在做一个管理软件,好多地方都不知道做!你的博客我天天都在看,主要是好多地方都看不懂啊!我想哭啊!
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 周公