ZedGraph在項目中的應用
??? 將數據庫數據提取出來,顯示成曲線圖(餅狀、柱狀或立體圖)是項目中最常見的需求。?網上搜索到的解決方法,大多歸為兩類,一種是利用ActiveX組件,另一種是使用.net框架自帶的畫圖的類。前者開發比較方便,但瀏覽時需要用戶下載ActiveX插件(而這個往往是忌諱的,插件帶毒)。后者,需要你自己寫繪圖、生成圖片的類庫,不過在開源社區已有不少的項目針對這個問題,做出了實現。ZedGraph是其中之一,網上的評論大多如是說:使用方便,易上手。
??? ZedGraph是c#編寫的類庫,提供了用戶控件和web控件。官網的例子提供了在windows窗體上顯示圖片的源碼,而如何將它應用到web項目中,卻沒有任何介紹(或許是我沒找到),web控件才是項目中有價值的東東。一番搜索后,摟到了一些實現,確實!它已經封裝到相當優秀的程度,舉個例子:
????我們在畫曲線圖的時候,往往為如何設計X、Y軸的坐標而頭疼,如何設置它數值范圍、設置單元間距等,才能讓我們的數據顯示得盡量完整和精確。而它的設計是,只要你提供數據,X/Y軸的問題不用管——它會找出數據范圍,然后設置合理的顯示域和單元間距。下面是一個簡單的實現,將數據庫數據生成一張曲線圖和柱狀圖,如此它便可以被這樣的方式,顯示到頁面上:
?<body>
????<img?src="Pic.aspx">
</body>?
????<img?src="Pic.aspx">
</body>?
????首先,你需要將兩個dll引用至你的工程,ZedGraph.dll和ZedGraph.web.dll。接下來,是你要生成圖片的頁面,暫且命名為pic.aspx,將它的html標簽部分去掉,添加ZEDGRAPHWEB控件:
<%@?Page?language="c#"?Codebehind="PriceTimePic.aspx.cs"?AutoEventWireup="false"?
????Inherits="Herbalife.HelpDesk.UI.ReportManage.PurchaseReport.PriceTimePic"?%>
<%@?Register?TagPrefix="zgw"?Namespace="ZedGraph.Web"?Assembly="ZedGraph.Web"%>
<ZGW:ZEDGRAPHWEB?id="ZG"?runat="server"?width="500"?Height="375"?RenderMode="RawImage"?/>
?????然后,我們到pic.aspx.cs下,添加包引用:using ZedGraph; using ZedGraph.Web;,添加控件對象的聲明:protected ZedGraph.Web.ZedGraphWeb ZG;。接下來在InitializeComponent()方法中注冊一個事件:
//?OnRenderGraph?繪圖方法
this.ZG.RenderGraph?+=?new?ZedGraph.Web.ZedGraphWebControlEventHandler(this.OnRenderGraph);
????Inherits="Herbalife.HelpDesk.UI.ReportManage.PurchaseReport.PriceTimePic"?%>
<%@?Register?TagPrefix="zgw"?Namespace="ZedGraph.Web"?Assembly="ZedGraph.Web"%>
<ZGW:ZEDGRAPHWEB?id="ZG"?runat="server"?width="500"?Height="375"?RenderMode="RawImage"?/>
?????然后,我們到pic.aspx.cs下,添加包引用:using ZedGraph; using ZedGraph.Web;,添加控件對象的聲明:protected ZedGraph.Web.ZedGraphWeb ZG;。接下來在InitializeComponent()方法中注冊一個事件:
//?OnRenderGraph?繪圖方法
this.ZG.RenderGraph?+=?new?ZedGraph.Web.ZedGraphWebControlEventHandler(this.OnRenderGraph);
????下面便是繪圖方法了:
private?void?OnRenderGraph(System.Drawing.Graphics?g,?ZedGraph.MasterPane?masterPane)
{
????GraphPane?myPane?=?masterPane[0];
????//?Title
????myPane.Title.Text?=?"供應商?價格-時間曲線圖";
????myPane.XAxis.Title.Text?=?"時間";
????myPane.YAxis.Title.Text?=?"價格";
????//?坐標對集合
????PointPairList?line?=?new?PointPairList();
????//?取數據部分
????DataTable?dt?=?GetData();
????//?將數據轉為(X,Y)坐標對
????for(int?i=0;i<dt.Rows.Count;i++)?
????{
????????/*
?????????*????添加坐標對,需要將X/Y值全部轉為double類型。原本以為他們會支持DateTime類型。
?????????*???個人覺得還是很有必要的,畢竟很多圖都是時間-**曲線圖,有需求。
?????????*/
????????string?date?=?Convert.ToDateTime(dt.Rows[i]["RecTime"]).ToString("yyyyMMdd");
????????line.Add(Convert.ToDouble(date),?Convert.ToDouble(dt.Rows[i]["Price"]));
????}
????//?繪制曲線
????LineItem?li?=?myPane.AddCurve("aaa",line,?Color.Blue);
????masterPane.AxisChange(g);
}
效果圖如下:

由于日期類型轉換成double型,結果X軸還是比較難看的。目前正在研究它的類庫,應該可以更改的。
餅狀圖,則需要修改OnRenderGraph方法:
private?void?OnRenderGraph(System.Drawing.Graphics?g,?ZedGraph.MasterPane?masterPane)
{
????GraphPane?myPane?=?masterPane[0];
????//?Title
????myPane.Title.Text?=?"供應商?價格-時間曲線圖";
????myPane.XAxis.Title.Text?=?"時間";
????myPane.YAxis.Title.Text?=?"價格";
????//?坐標對集
????PointPairList?line?=?new?PointPairList();
????DataTable?dt?=?GetData();
????for(int?i=0;i<dt.Rows.Count;i++)?
????{
????????string?date?=?Convert.ToDateTime(dt.Rows[i]["RecTime"]).ToString("yyyyMMdd");
????????line.Add(Convert.ToDouble(date),?Convert.ToDouble(dt.Rows[i]["Price"]));
????}
????BarItem?myCurve?=?myPane.AddBar("aaa",?line,?Color.Blue);
????myCurve.Bar.Fill?=?new?Fill(Color.Blue,?Color.White,?Color.Blue);
????myPane.XAxis.MajorTic.IsBetweenLabels?=?true;
?????//?X軸Label
????string[]?labels?=?new?string[dt.Rows.Count];
????for(int?i=0;i<dt.Rows.Count;i++)
????????ls[i]?=?Convert.ToDateTime(dt.Rows[i]["RecTime"]).ToString("yyyy/MM/dd");
????myPane.XAxis.Scale.TextLabels?=?labels;
????myPane.XAxis.Type?=?AxisType.Text;
????//?顏色填充
????myPane.Fill?=?new?Fill(Color.White,?Color.FromArgb(200,?200,?255),?45.0f);
????myPane.Chart.Fill?=?new?Fill(Color.White,?Color.LightGoldenrodYellow,?45.0f);
?
????masterPane.AxisChange(g);
}
{
????GraphPane?myPane?=?masterPane[0];
????//?Title
????myPane.Title.Text?=?"供應商?價格-時間曲線圖";
????myPane.XAxis.Title.Text?=?"時間";
????myPane.YAxis.Title.Text?=?"價格";
????//?坐標對集
????PointPairList?line?=?new?PointPairList();
????DataTable?dt?=?GetData();
????for(int?i=0;i<dt.Rows.Count;i++)?
????{
????????string?date?=?Convert.ToDateTime(dt.Rows[i]["RecTime"]).ToString("yyyyMMdd");
????????line.Add(Convert.ToDouble(date),?Convert.ToDouble(dt.Rows[i]["Price"]));
????}
????BarItem?myCurve?=?myPane.AddBar("aaa",?line,?Color.Blue);
????myCurve.Bar.Fill?=?new?Fill(Color.Blue,?Color.White,?Color.Blue);
????myPane.XAxis.MajorTic.IsBetweenLabels?=?true;
?????//?X軸Label
????string[]?labels?=?new?string[dt.Rows.Count];
????for(int?i=0;i<dt.Rows.Count;i++)
????????ls[i]?=?Convert.ToDateTime(dt.Rows[i]["RecTime"]).ToString("yyyy/MM/dd");
????myPane.XAxis.Scale.TextLabels?=?labels;
????myPane.XAxis.Type?=?AxisType.Text;
????//?顏色填充
????myPane.Fill?=?new?Fill(Color.White,?Color.FromArgb(200,?200,?255),?45.0f);
????myPane.Chart.Fill?=?new?Fill(Color.White,?Color.LightGoldenrodYellow,?45.0f);
?
????masterPane.AxisChange(g);
}
效果圖:

本文轉自 qianshao 51CTO博客,原文鏈接:http://blog.51cto.com/qianshao/202155,如需轉載請自行聯系原作者