Update: 沒想到這篇居然變成Google搜尋ZedGraph第一篇中文網頁,不過還是誠心建議用Windows上的C#先看一下免費的圖表元件:Microsoft Chart Controls,除非你非得用.Net 2.0(Windows 2000)或是用Mono。 BTW,我並不想成為微軟MVP,所以本Blog並不是有問必答的喲^_^
才剛貼完上一篇,馬上就有位朋友丟過來一個LGPL Open Source元件的網址:ZedGraph。
參考:A flexible charting library for .NET
基本上,照著Use RenderMode.RawImage in a web page,應該可以做出來,只要注意把ZedGraph.dll和ZedGraph.Web.dll都複製到bin下即可。我是偷懶直接下載zedgraph_web_sample_v5.1.2.zip,用檔案系統網站開啟,再把那2個dll丟到bin下測試。
範例裏有三個目錄,我們只關注ImageTagCS和RawModeCS。原來以為ImageTagCS做成WebControl,只要一個檔案即時render比較好,但我發現錯了:會不斷產生暫存影像檔。
所以比較好的做法與ProEssentials一樣,必須用另一支aspx產生影像,也就是RawModeCS裏的做法。
從頭來做一次好了,先開一個新的Asp.Net檔案系統網站,再開bin目錄,將ZedGraph.dll和ZedGraph.Web.dll都複製到bin下。
接著加入一個新WebForm,叫zedgraph.aspx
在Default.aspx裏拉進一個button和一個Image物件,在button上double click,在form標籤內應該是
在Default.aspx.cs裏
打開zedgraph.aspx,刪除原有內容,輸入
在zedgraph.aspx.cs裏加入
再執行 Default.aspx,執行結果:
重點在於把值利用Session傳入,以及zedgraph的事件
如果像鳥毅一樣運氣太好,遇到browser cache圖怎麼辦?尤其是放在UpdatePanel內更容易發生,最簡單的方法就是在每次查詢(button click)事件處理內加上一條:
才剛貼完上一篇,馬上就有位朋友丟過來一個LGPL Open Source元件的網址:ZedGraph。
參考:A flexible charting library for .NET
基本上,照著Use RenderMode.RawImage in a web page,應該可以做出來,只要注意把ZedGraph.dll和ZedGraph.Web.dll都複製到bin下即可。我是偷懶直接下載zedgraph_web_sample_v5.1.2.zip,用檔案系統網站開啟,再把那2個dll丟到bin下測試。
範例裏有三個目錄,我們只關注ImageTagCS和RawModeCS。原來以為ImageTagCS做成WebControl,只要一個檔案即時render比較好,但我發現錯了:會不斷產生暫存影像檔。
所以比較好的做法與ProEssentials一樣,必須用另一支aspx產生影像,也就是RawModeCS裏的做法。
從頭來做一次好了,先開一個新的Asp.Net檔案系統網站,再開bin目錄,將ZedGraph.dll和ZedGraph.Web.dll都複製到bin下。
接著加入一個新WebForm,叫zedgraph.aspx
在Default.aspx裏拉進一個button和一個Image物件,在button上double click,在form標籤內應該是
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="查詢" /> <asp:Image ID="Image1" runat="server" ImageUrl="zedgraph.aspx" />
在Default.aspx.cs裏
protected void Button1_Click(object sender, EventArgs e) { PointPairList list1 = new PointPairList(); PointPairList list2 = new PointPairList(); PointPairList list3 = new PointPairList(); Random rand = new Random(); for ( double x=0; x<5; x+=1.0 ) { double y = rand.NextDouble() * 1000; double y2 = rand.NextDouble() * 1000; double y3 = rand.NextDouble() * 1000; list.Add( x, y ); list2.Add( x, y2 ); list3.Add( x, y3 ); } Session["list1"] = list1; Session["list2"] = list2; Session["list3"] = list3; //為避免cache,若使用AJAX一定要加 Image1.ImageUrl = "zedgraph.aspx?xxx="+DateTime.Now.Millisecond; }
打開zedgraph.aspx,刪除原有內容,輸入
<%@ Page Language="c#" Inherits="ZG1.zedgraph" CodeFile="zedgraph.aspx.cs" %> <%@ Register TagPrefix="zgw" Namespace="ZedGraph.Web" Assembly="ZedGraph.Web" %> <zgw:zedgraphweb id="ZedGraphWeb1" runat="server" width="800" height="450" rendermode="RawImage" onrendergraph="OnRenderGraph"></zgw:zedgraphweb>
在zedgraph.aspx.cs裏加入
protected void OnRenderGraph(ZedGraphWeb zgw, Graphics g, MasterPane masterPane) { // Get the GraphPane so we can work with it GraphPane myPane = masterPane[0]; myPane.Title.Text = "電腦統計圖"; myPane.XAxis.Title.Text = "部門"; myPane.YAxis.Title.Text = "台數"; // 這裏可視情況改成由DataTable讀入資料, // 將DataTable從前一頁利用Session傳入 PointPairList list1 = (PointPairList)Session["list1"]; PointPairList list2 = (PointPairList)Session["list2"]; PointPairList list3 = (PointPairList)Session["list3"]; BarItem myCurve = myPane.AddBar("桌機", list1, Color.Blue); myCurve.Bar.Fill = new Fill(Color.Blue, Color.White, Color.Blue); BarItem myCurve2 = myPane.AddBar("筆電", list2, Color.Red); myCurve2.Bar.Fill = new Fill(Color.Red, Color.White, Color.Red); BarItem myCurve3 = myPane.AddBar("印表機", list3, Color.Green); myCurve3.Bar.Fill = new Fill(Color.Green, Color.White, Color.Green); myPane.XAxis.MajorTic.IsBetweenLabels = true; string[] labels = { "行政部", "會計部", "資訊部", "業務部", "研發部" }; 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); //產生每個Bar上的數量(Label),原範例沒有喲 BarItem.CreateBarLabels(myPane, false, "f0"); }
再執行 Default.aspx,執行結果:
重點在於把值利用Session傳入,以及zedgraph的事件
如果像鳥毅一樣運氣太好,遇到browser cache圖怎麼辦?尤其是放在UpdatePanel內更容易發生,最簡單的方法就是在每次查詢(button click)事件處理內加上一條:
Image1.ImageUrl = "zedgraph.aspx?xxx="+DateTime.Now.Millisecond;這樣應該就沒問題了。
留言
我現在想只作一個BAR 寬度約佔整個圖表的80%,可是我找不到怎麼去修改BarWidth的方法
方便的話可以指點迷津嗎? 先謝謝了~~~
就是我利用大大的方法,但是抓不到資料
在default.aspx中
我是想利用點選一個按鈕後,將現存label.text的資料抓出來,然後
在default.aspx.vb中
將這些抓取道的資料寫到list1,2,3中
最後再在zedgraph.aspx中利用session
這邊的方法與大大的相同
但最後都抓不到資料值 所以圖都是空的
能否請大大指導一下?
2. 看不到程式很難除錯耶...不過我建議你先把target指向另一支aspx程式,確定list 1, 2, 3都有值之後,才對zedgraph.aspx除錯。
我剛剛又將程式寫了一下
可否請您幫我看一下呢..真的蠻困擾的
在Default.aspx內有兩個TextBox及兩個Label 有兩個Button分別取出TextBox的値到Label,以及產生圖形
在Default.aspx.vb內:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = TextBox1.Text
Label2.Text = TextBox2.Text
End Sub
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim list1 As New PointPairList()
Dim list2 As New PointPairList()
Dim list3 As New PointPairList()
Dim i As Integer, rand As New Random()
Dim y As Integer, x1 As Integer, x2 As Integer, x3 As Integer
For i = 1 To 5
y = i
x1 = 100.0 + rand.NextDouble() * 100.0
x2 = 100.0 + rand.NextDouble() * 100.0
x3 = 100.0 + rand.NextDouble() * 100.0
list1.Add(x1, y)
list2.Add(x2, y)
list3.Add(x3, y)
Next i
End Sub
在z_graph.aspx.vb內:
Protected Sub OnRenderGraph1(ByVal zgw As ZedGraphWeb, ByVal g As System.Drawing.Graphics, _
ByVal masterPane As zedgraph.MasterPane) Handles ZedGraphWeb1.RenderGraph
' Get a reference to the GraphPane instance in the ZedGraphControl
Dim myPane As GraphPane = masterPane(0)
'Dim sessionData As New Sequence
' Set the title and axis labels
myPane.Title.Text = "Stacked Bars with Value Labels Inside Each Bar"
myPane.XAxis.Title.Text = "Position Number"
myPane.YAxis.Title.Text = "Some Random Thing"
Dim list1 As New PointPairList()
Dim list2 As New PointPairList()
Dim list3 As New PointPairList()
list1 = CType(Session("list1"), PointPairList)
list2 = CType(Session("list2"), PointPairList)
list3 = CType(Session("list3"), PointPairList)
' Create the three BarItems, change the fill properties so the angle is at 90
' degrees for horizontal bars
Dim bar1 As BarItem = myPane.AddBar("Bar 1", list1, Color.Red)
bar1.Bar.Fill = New Fill(Color.Red, Color.White, Color.Red, 90)
Dim bar2 As BarItem = myPane.AddBar("Bar 2", list2, Color.Blue)
bar2.Bar.Fill = New Fill(Color.Blue, Color.White, Color.Blue, 90)
Dim bar3 As BarItem = myPane.AddBar("Bar 3", list3, Color.Green)
bar3.Bar.Fill = New Fill(Color.Green, Color.White, Color.Green, 90)
' Set BarBase to the YAxis for horizontal bars
myPane.BarSettings.Base = BarBase.Y
' Make the bars stack instead of cluster
myPane.BarSettings.Type = BarType.Stack
' Fill the axis background with a color gradient
myPane.Chart.Fill = New Fill(Color.White, _
Color.FromArgb(255, 255, 166), 45.0F)
masterPane.AxisChange(g)
End Sub
現在的問題是似乎連隨機取的值都抓不到因此跑不出圖形.我是希望能讀取label的値進而產生圖
程式碼似乎過長,不知是否會過亂,真的非常抱歉,請教你這時該怎麼辦呢
首先要向您道歉,小弟在貼code時,因為html碼不吃角刮號,所以某些code被blogger的編輯器吃掉了:P
問題很簡單呀,您在Button2_Click那裏並沒有把list1,2,3加到Session(就是我被吃掉的code,等會就補上),所以在next i與end sub中間加上
Session("list1") = list1 等3行,就傳得到 z_graph.aspx
另一點,您在z_graph.aspx.vb裏的是OnRenderGraph1而不是OnRenderGraph,請確認aspx裏呼叫的事件名稱是否一致。
我已經成功的讀到label的資料了
在大哥您的最後一行有說到
遇到brower cache圖的問題是什麼意思呢?
是說遇到讀取到的圖是舊的嗎?
我有大概爬了一下文
是否是Browser快取(Cache)起來,除非主動清除這些快取資料,或人工將頁面重新整理才能讀到新的資料的意思。
希望大哥能夠為小弟稍稍講解一番
還有就是解決方法,能否向小弟講解一下,
因為不太了解C#,非常感謝你
Image1.ImageUrl = "zedgraph.aspx?xxx="+DateTime.Now.Millisecond;
xxx是固定的xxx還是某個變數呢?
希望大哥能為小弟稍稍講解,讓小弟可以順利的轉成VB
因此,最簡單的方法就是改變url,所以我那行用VB.Net寫就是
Image1.ImageUrl = "zedgraph.aspx?xxx=" & DateTime.Now.Millisecond
其中 xxx 只要你爽寫成什麼都可以:P
最後再請教一下
Image1.ImageUrl = "zedgraph.aspx?xxx=" & DateTime.Now.Millisecond
是寫到Button1_Click內對吧
非常感謝大哥解決我的問題,因為ZedGraph的資料真的不多,除了官方網站..
感謝!! :D
CodeFile="zedgraph.aspx.cs"
上面這一句害我不淺,我的project編譯發佈到遠端後,就只剩dll跟aspx檔,CodeFile好像是asp.net 1.1的屬性,發佈到遠端後,iis就一直找不到"zedgraph.aspx.cs",除非我手動copy過去,在vs2005中測試倒是正常得很,因為cs檔就在身邊,看一看官方範例就是寫成CodeFile,範例中竟然還寫(This file uses the newer syntax for the .Net 2.0 version.) = =。後來把CodeFile改成2.0的CodeBehind,好像就解決這個問題了,整整找了兩天,希望不要有人在遇到這問題了,不用vs2005自帶的開發網頁伺服器,叫vs2005用iis運行,好像也會遇到。
要刮別人的鬍子前,先刮自己的鬍子。
要怎麼寫?? 上面標示每個Bar的字型不知道可以改嗎?? 因為我覺得滿小的....
因為我做的是動態的Bar,我需要在每個Bar上註明數量,不過因為動態的原因,那些數字都會留下之前顯示果的數量,找了好久都不知道怎麼解決...
可以請大大幫幫忙嗎?? 謝謝喔!!
而ZedGraph我也只有稍微玩一下,請再加油或找高手協助吧!我不過是個肉腳半吊子兩光網管呀!
不知道原因,本人照用回大大的code卻出下以問題。
----------------------------------
編譯器錯誤訊息: CS0246: 找不到型別或命名空間名稱 'PointPairList' (您是否遺漏 using 指示詞或組件參考?)
{
行 17: PointPairList list1 = new PointPairList();
行 18: PointPairList list2 = new PointPairList();
行 19: PointPairList list3 = new PointPairList();
----------------------------------
感謝大大的解答~!!
請下載文中的 sample project zip file。遺漏 using 指示詞或組件參考表示你沒有引用,完全不懂asp.net引用組件的方式;恕我直言,請從基礎開始學。
ZedGraph不適合你,請看免費的圖表元件:Microsoft Chart Controls。
目前ZedGraph沒什發展了,你可以考慮Microsoft Chart Controls