您的位置:首页 > 编程语言 > C#

用C#绘制实时曲线图

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

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

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

实际代码如下:

[Csharp] view
plaincopy

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.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 name="height">要生成的曲线图的高度

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

{

}

/// <summary>

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

/// </summary>

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

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

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

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

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;

}

}

}

窗体关键代码:

[Csharp] view
plaincopy

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

}

}

}

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: