1. 程式人生 > >MsChart教程系列之例項操作資料繫結(交叉表)應用

MsChart教程系列之例項操作資料繫結(交叉表)應用

在.NET 3.5下可以使用免費圖表控制元件MsChart,是微軟出品的,需要安裝到VS2008環境中使用。這工具給圖形統計和報表圖形顯示提供了很好的解決辦法,下面我們一起來分享這強大的圖形工具吧。

推薦第一篇:

本文中基本上只會寫出最簡單常用的功能,複雜的資料操作請參考微軟詳細的例程)

一.資料來源   
說到繪製圖表,可能很多人的第一反應除了是圖表呈現的方式外,更關心的便是資料 如何新增,記得在很多年前,哪時要繪製一個數據曲線圖,一直找不到好的呈現方式,後來使用了SVG的繪圖模式,不過在新增資料的時候可謂吃盡了苦頭,畢 竟,SVG只是一種描述語言,要動態的實現一個圖表的繪製,是非常困難的.對於微軟的圖表控制元件,資料新增是一件很簡單的方式,它支援多種資料新增方式, 如:

•可以在圖表的設計介面,在屬性設定視窗中的Series屬性下的Points中新增需要的資料.
•可以在圖表的設計介面中,在屬性中繫結一個數據源.
•可以在後臺程式碼中,動態新增資料.
•可以在後臺程式碼中設定一個或多個數據源,直接繫結到圖表中.
在此處,我只著重講解一下第3,4兩點.對於第3點,相對來說比較簡單,在後臺程式碼中,找到要新增程式碼的Series,通過它下面Points的Add、AddXY、AddY等方法,即可以實現資料的新增.例如:

Code [http://www.xueit.com] double t;
for(t =0; t <= (2.5* Math.PI); t
= Math.PI/6)
{
double ch1 = Math.Sin(t);
double ch2 = Math.Sin(t-Math.PI/2);
Chart1.Series[
"Channel 1"].Points.AddXY(t, ch1);
Chart1.Series[
"Channel 2"].Points.AddXY(t, ch2);
}

(注:程式碼摘自微軟的例子,上例中,Chart1為圖表的名字,Channel 1、Channel 2分別表示兩個Series資料序列)
二.繫結資料
先 來看看圖表控制元件都支援什麼型別的資料繫結,根據官方文件的說法,只要是實現了IEnumerable介面的資料型別,都可以繫結到圖表控制元件中,例 如:DataView, DataReader, DataSet, DataRow, DataColumn, Array, List, SqlCommand, OleDbCommand, SqlDataAdapter, 及OleDbDataAdapter物件。
對於開發來說,最常用的還是DataView、DataReader、DataSet、DataRow、Array、List這幾種型別了,有幾點需要注意一下:
•圖表控制元件支援多資料來源的繫結,例如:X軸繫結一個數據集ds1,Y軸可以繫結另一個數據集ds2,當然也可以是X軸繫結到一個List資料物件,Y軸繫結到一個DataView物件等等。
•圖表控制元件的繫結方式一般有兩種,常規繫結及交差表的繫結。
•圖表控制元件的Y軸資料,支援一次繫結多個值,以繪製時間、區域、使用量等之類的圖形。
繫結資料的流程如下:

大意是,繫結資料裡面是否有分組資料需要繫結,如果有,則呼叫交叉表繫結的方法。否則判斷是否時繫結X軸和Y軸(包括標籤、超連結、圖例文字等自定 義屬性),如果是,則呼叫Points.DataBind方法進行繫結操作。再判斷是否有不同的X軸或Y軸資料,如果有,則分別呼叫X,Y軸的繫結方法 Points.DataBindX,Points.DataBindY進行資料繫結。最後,再判斷是否需要進行多個Y軸值的繫結。
下面分別對幾種資料繫結的方法進行一下說明:

1.繫結一張資料表
繫結一張資料表,例如繫結一張普通的資料表,表資料如下:

REPS
ID Name RegionID Sales
1 Aaron 1 10440
2 Larry 2 17772
3 Andrew 3 23880
4 Mary 1 7663
5 Sally 4 21773
6 Nguyen 2 32294
7 Francis 4 11983
8 Jerry 3 14991

繫結方法的程式碼:

Code [http://www.xueit.com] Codestring mySelectQuery="SELECT Name, Sales FROM REPS;";
OleDbConnection myConnection
=new OleDbConnection(myConnectionString);
OleDbCommand myCommand
=new OleDbCommand(mySelectQuery, myConnection);
myCommand.Connection.Open();
OleDbDataReader myReader
= myCommand.ExecuteReader(CommandBehavior.CloseConnection)
;Chart1.DataBindTable(myReader,
"Name");
myReader.Close();
myConnection.Close();

因為資料來源中只有兩列Name和Sales,因此在呼叫Chart1.DataBindTable方法的時候,告訴了圖表X軸的名稱為Name,因此自動將Sales設定為Y軸的資料了.生成的圖形如下:



如果修改一下Sql語句為:SELECT Name,ID,RegionID FROM REPS;其它都不變化,再看看圖表是如何處理另外兩個欄位的,生成的圖表如下:


此時,圖表自動將ID,RegionID欄位當成了Y值,生成了兩個Series,因此每個使用者都有兩個值,生成的圖形也有兩個柱狀圖.
上面是一種動態繫結的方式,有人可能會問了,如果我想確定我要繫結的列,比如:X軸繫結某個欄位,Y軸繫結某個欄位如何操作呢?對於這種繫結,有幾種方法可以實現.
第一種:這種方法可能是很常見的,在原來的.NET程式設計中出現的機率非常之高,方法如下:



Code [http://www.xueit.com]

// 設定資料來源,myDv是一個取出資料集的DataView chart1.DataSource = myDv;
// 分別設定圖表的X值和Y值chart1.Series["Series1"].XValueMember ="Name";
chart1.Series[
"Series1"].YValueMembers ="Sales";
// 繫結設定的資料chart1.DataBind();

第二種:即直接呼叫點的繫結方法 



Code [http://www.xueit.com]

//myReader為取得的DataReader物件Chart1.Series["Series1"].Points.DataBindXY(myReader, "Name", myReader, "Sales");

第三種:呼叫DataBind的方法實現



Code [http://www.xueit.com]

CodeChart1.Series["Series1"].Points.DataBind(myReader, "Name", "Sales", "");

上面幾種方法得到的效果都是一樣的.當然了,上面三種方法需要自己建立Series,要顯示兩個柱狀圖,像上面的例子中的圖形,那麼得手動建立兩個Series,然後分別進行上面的繫結操作。


此處說一下Label和Tooltip的繫結方式,要在繫結的圖表中顯示標籤(Label)及提示(Tooltip),可以在繫結的時候,設定繫結
的屬性.對於上面的第一、二種方法,可以呼叫如下的方法來設定Label和Tooltip;例如,兩個資料序列名稱分別為Series1和
Series2,設定程式碼如下:



Code [http://www.xueit.com]

CodeChart1.Series["Series1"].Label ="#VAL";
Chart1.Series[
"Series1"].Points.DataBind(myDs.Tables[0].DefaultView, "Name", "ID", "");
Chart1.Series[
"Series2"].Label ="#VAL";
Chart1.Series[
"Series2"].Points.DataBind(myDs.Tables[0].DefaultView, "Name", "RegionID", "");

其中的#VAL是Label和Tooltip的萬用字元,表示取預設Y軸變數的意思。具體的詳細操作可以參考例程:Chart Features/Labels下面的內容。以後有空我也寫一篇Label的和其它變數的設定吧。
對於第三種呼叫的繫結則稍微不同,如下:



Code [http://www.xueit.com]

CodeChart1.Series["Series1"].Points.DataBind(myDs.Tables[0].DefaultView, "Name", "ID", "Label=ID,ToolTip=RegionID");
Chart1.Series[
"Series2"].Points.DataBind(myDs.Tables[0].DefaultView, "Name", "RegionID", "Label=RegionID,ToolTip=ID");

其實就是利用第三個屬性,通過格式化的字串來設定繫結屬性,Label表示標籤,ToolTip表示提示資訊,Url表示超連結等等。最後生成的圖片如下:


2.繫結一個交叉表
  微軟的圖表控制元件提供了一個交叉表資料的繫結方法DataBindCrossTable,它可以根據資料動態的生成資料序列(Series),借用官方的例子,資料庫的表資料如下:

REPSALES
Name Year Sales Commissions
John 2002 55676.55 2699.33
Mary 2002 44333 2299
Andrew 2002 64455.4 3636
John 2003 49884 2355
Mary 2003 52994 2487
Andrew 2003 66449 3794
John 2004 62994 3593
Mary 2004 54993 2599

我們先看看DataBindCrossTable的引數,它有兩個過載方法,分別是:
public void DataBindCrossTable (
 IEnumerable dataSource,
 string seriesGroupByField,
 string xField,
 string yFields,
 string otherFields,
 PointSortOrder sortingOrder
)
以及
public void DataBindCrossTable (
 IEnumerable dataSource,
 string seriesGroupByField,
 string xField,
 string yFields,
 string otherFields
)

每個引數的含義如下:
dataSource
要繫結的資料來源.
seriesGroupByField
要分組統計的資料欄位名稱,例如按姓名、日期等.
xField
X軸繫結的欄位名稱.
yFields
Y軸繫結的欄位名稱,如果需要繫結多個欄位,則用逗號將欄位名分開.
otherFields
其它資料欄位屬性,就是上面剛講的,標籤、提示、Url等屬性.
sortingOrder
設定資料是正確還是逆序排列.
此時要以統計每個使用者的年銷售曲線,那麼分組統計的欄位名應該設定為Name,如下:

Chart1.DataBindCrossTable(
                myReader,
               
"Name",
               
"Year" ,
               
"Sales",
               
"Label=Commissions{C}");

用如上的方法繫結,生成的圖形如下:

相反,如果要統計使用者每年的曲線,則將欄位反轉一下即可,如下:

Chart1.DataBindCrossTable(
                myReader,
               
"Year",
               
"Name",
               
"Sales",
               
"Label=Commissions{C}");

生成的曲線圖如下:

這次就先說到這裡咯,說幾個需要注意的地方:

  1. 在進行Y軸資料繫結的時候,如果要繫結多個欄位,預設情況會出錯,那是因為需要設定Y軸的可儲存值數量,設定為你需要儲存的數量即可,設定的地點在:Series-》YValuesPrePoint,設定為你需要顯示的個數即可。
  2. 在進行DataTable繫結的時候,Label、ToolTip等屬性的欄位格式化比較困難(otherFields 屬性),我試了半天,也就試出了一次只能繫結一個欄位,因為是和資料集繫結,如果要在標籤上增加文字的話,可以使用:Field{xxxx#xxxx},其中#會替換為相應的文字,例如:Field的值為45,那麼最後的呈現的結果就是:xxxx45XXXX.

  BTW:有很多東西我自己也在研究中,因此說得不是很完善,希望大家一起研究吧~下次再研究一下資料操作方面的東東以及標籤等的顯示。