分享
 
 
 

用C#绘制实时曲线图

王朝c#·作者佚名  2008-07-26
窄屏简体版  字體: |||超大  

在实际项目中我们经常需要绘制一些实时的数据图片,比如当前各公司的用水量、用电量还有播放声音视频时实时显示当前的声频等等,在我们最熟悉的任务管理器也有这么一个功能,用来表示当前CPU的使用频率,最近笔者刚刚给朋友完成了一个类似的功能图,用曲线图来实时表示一些实际数据,由于形象直观,很受客户欢迎。

不过由于某些原因,本人不能将实际项目中的代码拿出来给大家分享,只能模拟了一个简单的实现,代码没有过多优化,所以还存在很多可以优化的地方,希望有兴趣的朋友自己完善。

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

实际代码如下:

view plaincopy to clipboardprint?

using System;

using System.Collections.Generic;

using System.Text;

using System.Drawing;

using System.Drawing.Imaging;

namespace RealtimeCurve

{

/// <SUMMARY>

/// 说明:实时图片生成类,在本例中横向坐标上每个像素都会有一个控制点

/// 实际开发中可以减少控制点,比如每5个像素用一个控制点

/// 这样的效果或许更加逼真

/// 作者:周公

/// 日期:2008-07-21

/// 首发地址:<A href="http://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspxhttp://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspx">http://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspx</A>

/// </SUMMARY>

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;//图片前景色

/// <SUMMARY>

/// 图片的高度

/// </SUMMARY>

public int Height

{

get { return height; }

set { height = value; }

}

/// <SUMMARY>

/// 图片的宽度

/// </SUMMARY>

public int Width

{

get { return width; }

set { width = value; }

}

/// <SUMMARY>

/// 构造函数,指定生成的曲线图的宽度和高度

/// </SUMMARY>

/// <PARAM name="width">要生成的曲线图的宽度</PARAM>

/// <PARAM name="height">要生成的曲线图的高度</PARAM>

public RealTimeImageMaker(int width, int height):this(width,height,Color.Gray,Color.Blue)

{

}

/// <SUMMARY>

/// 构造函数,指定生成的曲线图的宽度、高度及背景色和前景色

/// </SUMMARY>

/// <PARAM name="width">要生成的曲线图的宽度</PARAM>

/// <PARAM name="height">要生成的曲线图的高度</PARAM>

/// <PARAM name="backColor">曲线图背景色</PARAM>

/// <PARAM name="foreColor">曲线图前景色</PARAM>

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;

}

}

/// <SUMMARY>

/// 获取当前依次连接曲线上每个点绘制成的曲线

/// </SUMMARY>

/// <RETURNS></RETURNS>

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.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;

}

}

}窗体关键代码:

view plaincopy to clipboardprint?

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

{

/// <SUMMARY>

/// 说明:显示实时曲线图的窗体

/// 作者:周公

/// 日期:2008-07-21

/// 首发地址:<A href="http://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspxhttp://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspx">http://blog.csdn.net/zhoufoxcn/archive/2008/07/21/2682027.aspx</A>

/// </SUMMARY>

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();

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有