在大多數情況下,我們的Web程式不僅僅需要給使用者提供具體資料,在一些情況下,我們還需要給進階的使用者或管理者提供資料匯總和分析圖表之類的功能。
如果我們不想顯示一大堆煩心的資料,希望通過餅圖或橫條圖來直觀地顯示資料,這是我們可以考慮使用圖表控制項顯示。
在接下來的文章中,我們將向大家介紹資料儀表板程式的實現。
之前有一篇文章關於StackOverflow上的編程趨勢,它通過條形和地區圖,向我們展示了Stackoverflow上的熱門的問題標籤。
圖1 Stackoverflow的熱門標籤
通過上圖,我們可以直觀地瞭解Stackoverflow上的熱門標籤的變化趨勢,現在,我們通過儀錶程式實現同樣的功能。
在儀錶程式介面中,我們會通過餅狀圖、地區圖和橫條圖顯示資料,這裡我們使用Google Charts控制項來顯示餅狀圖、地區圖和橫條圖資料圖。
Google Charts通過Javascript實現動態圖片的繪製,它的使用非常簡便,我們只需給相應的繪圖函數傳遞相應的資料,就可以產生相應的資料圖表了。
UI設計
圖2 Dashboard介面
現在,我們要在主介面(Dashboard)中,顯示資料的餅狀圖、地區圖和橫條圖,那麼我們使用Google Charts控制項動態地把三種圖形載入到Index.cshtml頁面中,下面是Index.cshtml頁面代碼:
<!-- Dashboard UI START --><body> <div> @{ Html.RenderAction("Dashboard_Pie", "DashBoard"); } </div> <div> @{ Html.RenderAction("Dashboard_AreaChart", "DashBoard"); } </div> <div> @{ Html.RenderAction("Dashboard_ColumnChart", "DashBoard"); } </div></body><!-- Dashboard UI END -->
上面,我們定義了三個div元素,Index.cshtml頁面動態地載入Dashboard_Pie、Dashboard_AreaChart以及Dashboard_ColumnChart的內容。
接下來,我們要定義Dashboard_Pie(餅狀圖)、Dashboard_AreaChart(地區圖)和Dashboard_ColumnChart(橫條圖)頁面,在定義資料圖介面之前,首先讓我們介紹Google Charts的使用。
Javascript
前面我們提到Google Charts的使用十分方便,首先我們需要引用jsapi庫,在頁面代碼中添加如下代碼:
<!-- Adds Google js api reference.--><script type="text/javascript" src="https://www.google.com/jsapi"></script>
Google的JSAPI,不僅可以載入Google自身提供的AJAX API(如:Google Map API、Google Search API和Google Earth API),它還可以載入各種常用的JS庫(如:jQuery、jQuery UI、Prototype、MooTools和Dojo等)。
現在,我們在頁面中添加如下Javascript代碼,引用Google的visualization庫:
<script type="text/javascript"> google.load("visualization", "1", { packages: ["corechart"] }); google.setOnLoadCallback(drawPieChart);</script>
上面,我們使用google的load()方法載入了visualization庫,並且定義了載入成功後的回呼函數為drawPieChart()。
也許有人會問:“為什麼不直接用Google CDN中提供Javascript庫呢?”有兩個原因,首先我們在Google CDN中沒有找到和visualization庫相關的引用地址(如有請告訴一下),其次,google的load()方法會載入一系列相關的資源(如:Javascript和CSS),這樣我們就無需一個個引用了。
前面,我們定義了回呼函數drawPieChart(),但還沒有實現該方法,接下來,我們需要實現回呼函數drawPieChart(),它負責獲繪製資料圖,具體實現如下:
/*** Draws the pie chart.**/function drawPieChart() { // Gets data from GetLanguageRank(). $.ajax({ type: 'GET', dataType: 'json', url: '<%= Url.Content("") %>', data: {}, success: function(data) { var dt = new google.visualization.DataTable(); dt.addColumn('string', 'Language'); dt.addColumn('number', 'Question'); // Adds data. for (var i = 0; i < data.length; i++) { dt.addRow([data[i].Name, data[i].Question]); } var options = { title: "Top 25 programming language" }; // Draws pie implemention. var chart = new google.visualization.PieChart(document.getElementById('pieChart')); chart.draw(dt, options); }, error: function(xhr, textStatus, e) { console.log('Status: ' + textStatus + ' Error: ' + e.toString()); }, complete: function() { } });}
上面,我們實現了回呼函數drawPieChart(),它通過調用$.ajax()方法從後端中擷取資料,如果資料擷取成功,就把資料傳遞給draw()方法繪製資料圖表。
接著,我們實現Dashboard_Pie資料圖介面,具體代碼如下:
<!-- Pie chart page --><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head id="Head1" runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title></head><body> <form id="form2" runat="server"> <div id="pieChart"> </div> </form></body></html>
上面,我們在form元素中添加了一個div元素,由於我們在回呼函數drawPieChart()中,指定了餅狀圖的載入位置,所以我們需要在頁面中添加餅狀圖的div元素。
前面,我們提到回呼函數drawPieChart(),通過$.ajax()方法從後端中擷取資料,現在,我們需要提供API方法,讓用戶端通過調用API擷取相應的資料。
這裡,我們使用Stackoverflow Jan/01/2010到July/01/2013的熱門標籤資料。
由於資料是CSV格式的,所以我們可以使用Excel查看資料。
圖3 熱門標籤資料
通過上圖中的資料,我們定義Language類,它包含四個欄位分別是Id、Name、Question和CreateOn,具體定義如下:
圖4 Language類
/// <summary>/// The language model./// </summary>public class QuestionTag{ public int Id { get; set; } public string Name { get; set; } public int Question { get; set; } public DateTime CreateOn { get; set; }}
上面,我們定義了QuestionTag類,接下來,我們需要定義控制器類,它負責返回後端資料,所以我們在Controllers檔案中建立DashboardController類,並且我們添加GetLanguageRank()方法,具體實現如下:
圖5 DashboardController類
/// <summary>/// Gets language rank data./// </summary>/// <returns>JSON arrary.</returns>public JsonResult GetLanguageRank(){ // Gets data from database.}
匯入資料
上面,我們定義了DashboardController類,它包含GetLanguageRank()方法,接下來我們把CSV資料儲存到資料庫中。首先,我們在資料庫中建立資料表,具體SQL代碼如下:
-- =============================================-- Description: Table for storing question tag data-- =============================================SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[QuestionTags]( [Name] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL, [Question] [int] NOT NULL, [CreateOn] [datetime] NOT NULL) ON [PRIMARY]GOSET ANSI_PADDING OFF
接著,我們CSV資料匯入到SQL Server中,具體實現如下:
-- =============================================-- Description: Imports csv data into database.-- =============================================BULK INSERT QuestionTagsFROM 'C:\Users\Administrator\Desktop\Stackoverflow Tags Data.csv'WITH( FIRSTROW = 2, -- Start row excludes header. FIELDTERMINATOR = ',', --CSV field delimiter ROWTERMINATOR = '\n', --Use to shift the control to next row ERRORFILE = 'C:\Users\Administrator\Desktop\ErrorLog.csv',? TABLOCK)
上面,我們直接使用SQL語句把CSV資料匯入到資料庫中,其中,我們定義了匯入資料的源檔案和資料格式,並且定義了ErrorLog檔案記錄匯入失敗的資料,最後,我們在表QuestionTags中添加自增型的Id主鍵。
圖6 匯入CSV資料
ASP.NET控制器
現在,我們已經把資料儲存到資料庫中了,接下來我們將使用EF擷取資料庫中的資料,接觸過EF的應該都知道EF的編程模型有3種:
- Database First:資料庫先行
- Model First:模型先行
- Code First:代碼先行
由於,前面我們已經把資料表定義好了,所以我們將使用資料庫先行(Database First)模型對資料庫進行訪問。
接下來,讓我們實現GetLanguageRank()方法,具體代碼如下:
/// <summary>/// Gets language rank data./// </summary>/// <param name="index">Specifies the range of data,/// for instance, when index is 0, then get the data range from Jan/1/2010 till Feb/2/2010./// </param>/// <returns>JSON Array</returns>public JsonResult GetLanguageRank(int index = 0){ using (var db = new DashboardDbContext()) { var result = (from tags in db.QuestionTags orderby tags.CreateOn ascending select new { tags.Id, tags.Name, tags.Question, tags.CreateOn }).Skip((index % 42) * 25).Take(25).ToList(); return Json(result, JsonRequestBehavior.AllowGet); } }
我們實現了GetLanguageRank()方法,它根據index值擷取指定時間的資料,然後通過JSON資料格式返回給用戶端。
現在,我們已經實現了餅狀圖(Dashboard_Pie)了,接下來,讓我們運行Index.cshtml頁面查看啟動並執行效果吧!
圖7 餅狀圖
我們注意到圖1是一個動態圖,它直觀的展示了Stackoverflow熱門標籤的變化趨勢,如果我們也要實現動態產生資料圖該如何?呢?
其實,問題轉化為即時擷取資料,然後產生資料圖就OK了,如果要實現即時擷取時間,我們想到的方法有:
- 1.Timer()
- 2.方法二資料庫即時方法資料(SqlDependency)
- 3.Other(請大家分享好方法)
接下來,我們將使用Javascript中Timer()函數來定時訪問GetLanguageRank()方法,所以我們需要修改Javascript代碼,通過Timer()函數定時調用drawColumnChart()方法,具體實現如下:
<script type="text/javascript"> google.load("visualization", "1", { packages: ["corechart"] }); google.setOnLoadCallback(timerStart); var cnt = 0, t; function timerStart() { t = window.setInterval(drawColumnChart, 1000); } function timerStop() { clearTimeout(t); } function drawColumnChart() { $.ajax({ type: 'GET', dataType: 'json', url: '<%= Url.Content("~/Dashboard/GetLanguageRank") %>', data: { index: cnt }, success: function(data) { var dt = new google.visualization.DataTable(); dt.addColumn('string', 'Language'); dt.addColumn('number', 'Question'); for (var i = 0; i < data.length; i++) { dt.addRow([data[i].Name, data[i].Question]); } var dateTime = new Date(parseInt(data[0].CreateOn.substr(6))); var options = { title: "Top 25 programming language on " + (dateTime.getMonth() + 1) + '/' + dateTime.getDate() + '/' + dateTime.getFullYear(), //width: 600, height: 500 }; var chart = new google.visualization.ColumnChart(document.getElementById('columnChart')); chart.draw(dt, options); }, error: function(xhr, textStatus, e) { timerStop(); console.log('Status: ' + textStatus + ' Error: ' + e.toString()); }, complete: function() { cnt = cnt + 1; } }); }</script>
當Google的visualization庫載入完畢後,訪問回呼函數timerStart(),然後使用setInterval()方法每隔1s就調用drawColumnChart()繪製新的柱狀圖。
圖8 柱狀圖
現在,我們通過Timer()函數即時的訪問API介面,資料通過柱狀圖動態地顯示出來。
頁面樣式
現在,我們已經完成了餅狀圖和柱狀圖,接下來,我們需要給儀錶程式添加一些簡單的CSS效果,具體代碼如下:
/*Dashboard APP CSS*/.pageHeader{ height: 20px; background-color: #2C2C2C; padding: 10px 10px; margin-bottom: 10px; color: White; position: relative;} .pageHeader h1 { font: normal 1.2em Arial; color: White; margin: 0; padding: 0; } .pageHeader .platformular { position: absolute; top: 10px; right: 10px; }.pageBody{ margin: 0 10px;}.pageFooter{ clear: both; padding-top: 10px; width: 100%; text-align: center; font-size: 0.8em; color: #686868; margin: 25px 0 0 0; border-top: solid 1px #e7e7e7;}
現在,我們重新運行程式查看頁面效果。
圖10儀錶程式
在本文中,我們通過使用ASP.NET MVC和EF的Database First實現了簡單的儀錶程式,使用Google Charts控制項來顯示資料圖,這隻是一個簡單的程式,我們還有很大的改善空間,提供一個內容豐富和功能強大的程式是每個程式員的目標。
以上就是本文的全部內容,希望對大家的學習有所協助。