ZedGraph图形控件在Web开发中的应用介绍
ZedGraph是一个功能强大图形控件,可以根据任意数据集创建2D曲线,bar,和pie图,同时我们既可以Windows Form中,也可以在ASP.NET Web Form中使用它。ZedGraph具有高度的灵活性,我们几乎可以定制图形的每个方面,同时又为所有
介绍
ZedGraph是一个功能强大图形控件,可以根据任意数据集创建2D曲线,bar,和pie图,同时我们既可以Windows Form中,也可以在ASP.NET Web Form中使用它。ZedGraph具有高度的灵活性,我们几乎可以定制图形的每个方面,同时又为所有的特性提供了默认值,因此可以快速上手。ZedGraph与.NET 2.0和Visual Studio 2005兼容。在本文中我们介绍如何在Visual Studio 2005中使用UpdatePanel,ZedGraph控件以及Web服务技术开发一个简单的实时监控Web应用程序,我们会将模拟的数据实时的呈现给用户。同时我们将使用Web服务而不是整页回传对某些参数进行控制,以提高用户体验。
使用Visual Studio 2005创建一个新的网站
选择Visual Studio 2005中的File->New Web Site,弹出图1所示的对话框,选中ASP.NET AJAX-Enabled Web Site模板(注意,在Visual Studio 2005中你需要下载ASPAJAXExtSetup包才会出现此模板),在这里我们使用File System,并将网站命名为ZedGraphDemo,单击Ok。
图1 新建一个ASP.NET AJAX-Enabled网站
在Toolbox中添加ZedGraph控件
在Toolbox面板的空白处单击鼠标右键,选择Choose Items…,在弹出的Choose Toolbox Items对话框中单击Browse按钮,定位到ZedGraph.Web.dll程序集文件(本文中使用的是zedgraph_dll_v5.1.2.880)。切换到Default.aspx的Design视图,从工具箱中拖拽添加UpdatPanel,Timer(注意Timer控件也必须放在UpdatePanel控件内部,否则它会引起整页回传,而不是我们希望的部分回传)和ZedGraphWeb控件,此时的Design视图看起来应该是图2这个样子。同时将Timer1的Interval属性设置为1000,即每秒钟刷新一次。

图2 设计视图
ZedGraph控件属性设置
ZedGraph允许你使用多种方法修改图形的属性。或者使用Visual Studio的属性面板进行可视化的修改,或者通过编程的方式在源代码中修改。表格1中列出的属性都是通过Visual Studio属性面板进行设置的。 Height
300

Width
400

RenderedImagePath
~/ZedGraphImages/

ChartFill.Color
Black

ChartFill.Type
Solid

TmpImageDuration(Gets or sets a value that determines the duration (in hours) of a temporary file generated by control in mode "ImageTag")
0注意这里的单位是小时,如果不小心会在服务器端产生很多的垃圾文件。
表1 利用Visual Studio属性面板对ZedGraph控件进行设置
在解决方案浏览器中右击项目,选择New Folder,命名为ZedGraphImages,ZedGraph使用此文件夹存放呈现到客户端的图片,必须添加这个文件夹。
数据模型
添加一个DataSource.cs文件,我们使用它来模拟显示的数据,添加源文件的时候Visual Studio会提示我们是否创建App_Code文件夹,选择“是”即可。此文件夹专门用来存放源文件,在构建网站应用程序时,Visual Studio会自动编译其中的源文件。注意由于我们使用了PointPairList 类型,因此需要使用using ZedGraph;引入ZedGraph名字空间。源代码如下所示:在这里我们只是使用一些随机数进行模拟。
namespace DataModal
{
public class DataSource
{
private DataSource() { dataPoints = 101; }
public static readonly DataSource Instance = new DataSource();
private Random ran = new Random();
//存储采样数据
public PointPairList DataBuffer = new PointPairList();
/// <summary>
/// 触发一次采样,并获取采样数据
/// </summary>
/// <param name="datas"></param>
public void GetData()
{
double[] yData = new double[DataPoints];
//获取采样数据
for (int i = 0; i < DataPoints; i++)
{
yData[i] = 100 * ran.NextDouble();
}
//填充缓冲区
double[] xData = new double[DataPoints];
for (int i = 0; i < DataPoints; i++)
{
xData[i] = i;
}
DataBuffer = new PointPairList(xData, yData);
}
/// <summary>
/// 采样点数
/// </summary>
private UInt32 dataPoints;
public UInt32 DataPoints
{
get { return dataPoints; }
set { dataPoints = value; }
}
}
}
绘制图形
1. 引入名字空间在Default.aspx.cs文件中,为了使用ZedGraph和数据源提供的服务,需要引入它们的名字控件,包括using System.Drawing;using ZedGraph;using ZedGraph.Web;。
2. 添加静态域
为_Default类添加两个静态成员,分别代表曲线和数据源对象,之所以使用静态变量,是因为我们希望所有的客户看到的都是同样的数据。
static LineItem myCurve;
static DataModal.DataSource osc = DataSource.Instance;
3. 订阅ZedGraph控件RenderGraph事件
至此我们已经准备好了数据源,如何利用ZedGraph显示它们呢?其实很简单,只需要订阅它的RenderGraph事件就可以了。在ZedGraph控件的属性面板中,选择“事件”选项,双击RenderGraph条目,Visual Studio会自动为我们创建事件处理器。打开Default.aspx.cs文件,可以看到一个空的
protected void ZedGraphWeb1_RenderGraph(ZedGraph.Web.ZedGraphWeb webObject, System.Drawing.Graphics g, ZedGraph.MasterPane pane){}
已经在那里等着我们了。ZedGraph为你提供了一个MasterPane实例,默认情况下,它包含一个MasterPane实例,我们可以通过pane[0]访问它。在设置曲线的各种属性之前,首先来看一下ZedGraph为我们提供了哪些属性以更好控制曲线的显示(注:本段解释来自Visifire图形控件(一个开源的Silverlight控件)帮助文档,起初为了弄明白这些参数的意义,费了好大劲查看ZedGraph的帮助文档,如果ZedGraph也能附上这么一幅说明图该多好呀。对于Web应用程序来说,Visifire的性能应该要比ZedGraph优异的多。在ZedGraph中,我们是在服务器端获取数据并显示在图形中,然后将图片发送到客户端呈现在浏览器中,服务器的负载比较大。如果我们能通过调用Web服务的方法获取数据,然后在客户端对数据进行分析处理并呈现给用户,那么无疑会大大减轻服务器的负载。具体选择哪种方法要具体问题具体分析,在服务器和客户之间作出权衡。)
图3展示了Visifire中的各种图形控制属性,虽然它们是Visifire中表示方法,但是ZedGraph基本上也提供了这些属性。表2对属性的意思进行了简单的说明,注意X和Y轴的属性值可以分别设置。

图3 各种坐标轴控制属性 Scale.Max
最大刻度值

Scale.Min
最小刻度值

MajorStep
the scale step size for this Scale (the increment between labeled axis values)刻度的步进值,即每隔多少值进行标记
如果刻度为0,1,2,…100,而你想显示10个主tic(major tic),那么可以设置MajorStep为10,即每10个数据显示一个主刻度。

Scale.BaseTic
the scale value at which the first major tic label will appear指明第一个主刻度标签标记的位置

MajorGrid.IsVisible
栅格线是否可见

MajorGrid.Color
栅格线颜色

MajorGrid.DashOff
The dash off length is defined in points (1/72 inch)将它设置为0,以展现实线效果。

Scale.Mag
刻度乘法因子,即如果坐标轴上的读数为x,那么它代表的实际值为x*10Mag
表2 各个坐标轴属性的意思
在ZedGraphWeb1_RenderGraph方法中,首先对各种属性进行设置,然后将曲线添加到myPane中,ZedGraph会帮我们完成剩下的绘制工作。
protected void ZedGraphWeb1_RenderGraph(ZedGraph.Web.ZedGraphWeb webObject, System.Drawing.Graphics g, ZedGraph.MasterPane pane)
{
GraphPane myPane = pane[0];
//开始X轴刻度设置
//X轴坐标的范围
myPane.XAxis.Scale.Max = DataSource.Instance.DataPoints - 1;
myPane.XAxis.Scale.Min = 0;
//第一个主刻度从哪里开始
myPane.XAxis.Scale.BaseTic = 0;
//X轴主步进值
myPane.XAxis.Scale.MajorStep = (DataSource.Instance.DataPoints - 1) / 10;
//X轴读数是否可见
myPane.XAxis.Scale.IsVisible = true;
//设置横坐标的乘法因子,例如^1,
//myPane.XAxis.Scale.Mag = 1;
//开始Y轴坐标设置
//设置Y轴坐标的范围
myPane.YAxis.Scale.Max = 110;
myPane.YAxis.Scale.Min = 0;
//第一个主刻度从哪里开始
myPane.YAxis.Scale.BaseTic = 0;
//X轴主步进值
myPane.YAxis.Scale.MajorStep = 10;
//X轴读数是否可见
myPane.YAxis.Scale.IsVisible = true;

//添加栅格线myPane.XAxis.MajorGrid.IsVisible = true;
myPane.YAxis.MajorGrid.IsVisible = true;
myPane.XAxis.MajorGrid.Color = Color.LightGray;
myPane.YAxis.MajorGrid.Color = Color.LightGray;
myPane.YAxis.MajorGrid.DashOff = 0;
myPane.XAxis.MajorGrid.DashOff = 0;
//添加曲线
myCurve = myPane.AddCurve("曲线图", osc.DataBuffer, Color.Yellow, SymbolType.None);
}
4. 订阅Timer控件的Tick事件
在Tick事件处理器中,我们只需要获取数据,然后触发图形绘制事件就可以了,至于怎么绘制交给ZedGraph去处理吧,是不是很简单。
protected void Timer1_Tick(object sender, EventArgs e)
{
//获取并填充数据
DataSource.Instance.GetData();
//触发图形绘制事件
this.ZedGraphWeb1.AxisChanged = true;
}
5. 验证
现在试着运行一下你的ZedGraphDemo网站应用程序,它看起来应该与图4类似:

图4 第一次尝试后的运行效果
使用Web服务控制数据源
首先添加一个Web Service条目,打开图5所示的对话框,选中Web Service模板,命名为WebControlService。
图5 添加一个Web Service条目
在WebControlService.cs文件中添加两个方法,分别获取和设置采样点数。为了能够操作DataSource,需要引入名字控件DataModal。为了能够在客户端使用JavaScript脚本调用我们的Web服务,需要为WebControlService类应用[ScriptService]特性,还需要添加using System.Web.Script.Services;。另外我们还需要在ScriptManager中注册我们的Web服务,最终的ScriptManager如下所示:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebControlService.asmx" />
</Services>
</asp:ScriptManager>
[WebMethod]
[ScriptMethod]
public void SetPoints(string points)
{
DataSource.Instance.DataPoints = Convert.ToUInt32(points);
}
[WebMethod]
[ScriptMethod]
public UInt32 GetPoints()
{
return DataSource.Instance.DataPoints;
}
在Defualt.aspx文件中添加一个标签和文本框,供用户输入采样点设置值。
<asp:Literal ID="Literal1" runat="server" Text="采样点数"></asp:Literal><br />
<input id="txtPoints" type="text" οnchange="ontxtPointsValueChange()" />
为了响应用户的输入,我们需要添加一个JavaScript脚本文件Script.js,并在Default.aspx中引入它(在<head />节中添加如下代码即可
<script type="text/javascript" src="Script.js"></script>)。再次运行ZedGraphDemo应用程序,这次它看起来应该是图6这个样子了:

图6 最终运行效果
此时,你可以在文本框中输入采样点数,例如120(没有添加输入校验功能,因此不要自找麻烦哟),然后在别处单击一下鼠标让文本框失去输入焦点,此时再观察一下图形,它的采样点数是不是变成了120?
当然,这只是一个很简单的演示程序,在此基础上,你可以为它添加其它的有趣的功能。我在这里只是解释了ZedGraph中几个比较重要的曲线配置参数,当然你也可以利用ZedGraph其它数以百计的属性让图形显示的更加漂亮美观。
后记
在这里我们使用UpdatePanel控件来获得部分刷新的效果,但是如果想在实际项目中使用它必须首先对其进行评估后再决定是否使用。利用JavaScript脚本调用Web服务在大多数情况下应该能够作为UpdatePanel的另一个选择。