我們前面所涉及的離線數據庫、離線文件的操作,會話機制的控制,以及客戶端跨域數據同步、與服務端的交互,都可以很好的讓用戶在沒有網絡或者與服務端斷開鏈接的情況下進行正常的操作。但我們的這個離線系統的客戶中包含了很多的特定群體,如財務,會計、數據抽取人員,於是需要對數據報表和數據圖表一個很強有力支持,讓他們更加直觀地表達。
目前來說,圖表的開發組件還是很多的。
有基於silverLight的 Visifire,這是我的項目在使用MVC 3.0 開發之前最喜歡用的圖表組件,喜歡的原因主要有三點(Visifire):
Open Source :相信這是很多程序員朋友最喜歡看到的。
Single API to both Silverlight & WPF:相信這也是許多客戶端應用開發程序員最喜歡看到的。
Quick Start:啟動速度很快,絕不輸給純腳本的一些輕量級圖表插件,而且基於SilverLight的開發,給人視覺上絢麗的沖擊感。
之前也在MVC 3.0下使用過Hight Charts,不得不承認這東西很好用,案例豐富,文檔齊全,學習和使用都能很快上手,因為是基於純腳本的,在項目移植上基本不存在什么問題,不像基於SilverLight的組件,你得保證服務機上面必須安裝SilverLight。
在基於HTML5 應用的開發中,因為有了 HTML5 Cavans API,提供了通過 JavaScript 繪制圖形的方法,使得數據圖表開發更加的便捷,於是涌現出了很多基於HTML5 Cavans的腳本庫。可以參考這篇文章的介紹:推薦18個基於 HTML5 Canvas 開發的圖表庫
其中我最喜歡的就是ZingChart,因為他是首個可以以Flash和HTML5 Canvas兩種方案呈現圖表的圖表庫,Flash版本,基本在所有的瀏覽器都是支持的。
我們關注一下這個ZingChart的HTML5版本,因為公司的其他同事也要用,所以稍微小做了下二級封裝,這邊的封裝主要是提取了方法,分離了對數據的綁定,用傳參的方式來調用,這樣做的原因是我們頁面上的數據主要是用二維數組來保存數據,然后用表格來呈現,這個二維數組傳值進來正好對應了橫軸,縱軸的數據。js庫代碼如下:

//Ben HTML5 1.0 //Create By Ben 2012.5.25 //基於zingchart圖表插件的二級封裝 function BenCharts() { /*餅圖*/ /*title:標題*/ /*fields:域*/ /*values:值*/ this.makePieChart = function(title, fields, values) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values": [' + values[i] + '],"text": "' + fields[i] + '"}'; } var jsonConfigPie = '{' + '"graphset": [' + '{' + '"type": "pie",' + '"legend": {' + '"visible": true' + '},' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"plot": {' + '"tooltip-text": "%t<br/>值: %v<br/>百分比: %npv",' + '"animate":true,' + '"speed":1,' + '"effect":5,' + '"value-box": {' + '"visible": true' + '}' + '},' + '"series": [' + content.join(',') + ']' + '}]' + '}'; return jsonConfigPie; } /*線形圖*/ /*title:標題*/ /*xTitle:橫軸標題*/ /*yTitle:縱軸標題*/ /*xValue:橫軸節點*/ /*fields:縱軸節點*/ /*values:橫縱軸二維數組*/ this.makeLineChart = function(title, xTitle, yTitle, fields, values, xValue) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values": [' + values[i].join(',') + '],"text": "' + fields[i] + '","line-width": 2,"animate": 1,"effect": 1,"marker": {"size": "3px"}}'; } if (!xValue) { xValue = '"1:' + values[0].length + ':1"'; //橫軸:(初始,總量,增量值) } else xValue = '["' + xValue.join('","') + '"]'; //橫軸:由開發人員自定義 var jsonConfigLine = '{' + '"graphset": [' + '{' + '"type": "line",' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"legend": {' + '"visible": true' + '},' + '"scale-x": {' + '"values": ' + xValue + ',' + '"label": {' + '"text": "' + xTitle + '"' + '},' + '"zooming": 1' + '},' + '"scale-y": {' + '"max-items": 8,' + '"label": {' + '"text": "' + yTitle + '"' + '}' + '},' + '"plot": {' + '"tooltip-text": "%t, 值 %v"' + '},' + '"series": [' + content.join(',') + ']' + '}]' + '}'; return jsonConfigLine; } /*柱狀圖圖*/ /*title:標題*/ /*xTitle:橫軸標題*/ /*yTitle:縱軸標題*/ /*xValue:橫軸節點*/ /*fields:縱軸節點*/ /*values:橫縱軸二維數組*/ this.makeBarChart = function(title, xTitle, yTitle, fields, values, xValue) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values": [' + values[i].join(',') + '],"text": "' + fields[i] + '","animate": 1,"effect": 5}'; } if (!xValue) { xValue = '"1:' + values[0].length + ':1"'; //橫軸:(初始,總量,增量值) } else xValue = '["' + xValue.join('","') + '"]'; //橫軸:由開發人員自定義 var jsonConfigBar = '{' + '"graphset": [' + '{' + '"type": "bar",' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"legend": {' + '"visible": true' + '},' + '"scale-x": {' + '"values": ' + xValue + ',' + '"label": {' + '"text": "' + xTitle + '"' + '},' + '"zooming": 1' + '},' + '"scale-y": {' + '"label": {' + '"text": "' + yTitle + '"' + '}' + '},' + '"plot": {' + '"tooltip-text": " %t, 值: %v"' + '},' + '"series": [' + content.join(',') + ']' + '}' + ']' + '}'; return jsonConfigBar; } /*線形擴展區域圖*/ /*title:標題*/ /*xTitle:橫軸標題*/ /*yTitle:縱軸標題*/ /*xValue:橫軸節點*/ /*fields:縱軸節點*/ /*values:橫縱軸二維數組*/ this.makeAreaChart = function(title, xTitle, yTitle, fields, values, xValue) { var content = new Array(); for (var i = 0; i < fields.length; i++) { content[i] = '{"values":[' + values[i].join(',') + '],"text":"' + fields[i] + '","line-width":"2px","animate":1,"effect":1,"marker":{"size":"3px"}}'; } if (!xValue) { xValue = '"1:' + values[0].length + ':1"'; //橫軸:(初始,總量,增量值) } else xValue = '["' + xValue.join('","') + '"]'; //橫軸:由開發人員自定義 var jsonConfigArea = '{' + '"graphset": [' + '{' + '"type":"area",' + '"legend": {' + '"visible": true' + '},' + '"title":{' + '"text":"' + title + '",' + '"font-family":"helvetica",' + '"font-size":"12px",' + '"background-color":"none",' + '"font-weight":"bold",' + '"font-color":"#000",' + '"text-align":"center"' + '},' + '"scale-x":{' + '"values": ' + xValue + ',' + '"label":{' + '"text":"' + xTitle + '"' + '},' + '"zooming":1' + '},' + '"scale-y":{' + '"label":{' + '"text":"' + yTitle + '"' + '},' + '"zooming":1' + '},' + '"plot":{' + '"tooltip-text":"%t, 值: %v"' + '},' + '"series":[' + content.join(',') + ']' + '}]' + '}'; return jsonConfigArea; } } var BC = new BenCharts();
頁面調用示例如下:

/*使用餅圖*/ var fields = new Array("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"); var values = new Array("100", "120", "35", "88", "66", "56", "79", "115", "42", "100", "110", "80"); var datas = BC.makePieChart("月數據報表", fields, values); zingchart.render({ 'id': 'g1', 'width': 500, 'height': 300, 'data': datas });

/*使用線形圖*/ var title = "月數據線形圖"; var xTitle = "2012各月份數據報表"; var yTitle = "上報數據"; var fields = new Array('東區', '西區', '南區', '北區'); var xValue = new Array('1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'); var value1 = [12, 15, 55, 14, 22, 23, 64, 32, 27, 0, 0, 0]; var value2 = [23, 17, 35, 19, 28, 32, 12, 59, 75, 45, 28, 72]; var value3 = [35, 45, 25, 29, 33, 49, 42, 42, 12, 36, 45, 58]; var value4 = [17, 16, 55, 65, 22, 46, 64, 32, 47, 12, 38, 40]; var values = new Array(value1, value2, value3, value4); zingchart.render({ 'id': 'g2', 'width': 600, 'height': 250, 'data': BC.makeLineChart(title, xTitle, yTitle, fields, values, xValue) //'data': makeLineChart(title, xTitle, yTitle, fields, values) //不寫入xValue,則會自動生成橫軸值 });

/*使用柱狀圖*/ var title = "月數據柱狀圖"; var xTitle = "2012各月份"; var yTitle = "上報件"; var fields = new Array('東區', '西區', '南區', '北區'); var xValue = new Array('1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'); var value1 = [12, 15, 55, 14, 22, 23, 64, 32, 47, 2, 2, 2]; var value2 = [23, 17, 35, 19, 28, 32, 12, 59, 75, 45, 28, 72]; var value3 = [35, 45, 25, 29, 33, 49, 42, 42, 12, 36, 45, 58]; var value4 = [17, 16, 55, 65, 22, 46, 64, 32, 47, 12, 38, 40]; var values = new Array(value1, value2, value3, value4); zingchart.render({ 'id': 'g3', 'width': 860, 'height': 300, 'data': BC.makeBarChart(title, xTitle, yTitle, fields, values, xValue) // 'data': makeBarChart(title, xTitle, yTitle, fields, values) //不寫入xValue,則會自動生成橫軸值 });
其實后來發現挺不合理,因為這個圖表的數據本身就是json格式構成的,所以應該直接把相應格式的json字符串傳進來比較好,而我們為了在頁面上顯示數據表格,把之前的json數據轉成二維數組,然后又轉成json串,裝箱拆箱的,無端耗費性能。
還有一個需要注意的,這個ZingChart是不能用於商業用途的,如果你要用於商業用途,那需要付一定的費用。這個挺坑的,我們公司是買了,如果是自己做研究,也可以去下試用版。這個想破解也容易,其實就是一堆腳本,里面有個license.js,接下來,你懂的,嘻嘻...
因為我用的時候是英文版本的,還不支持中文,所以我這邊做了本地化,右鍵菜單現在顯示的是中文。
源碼下載:HTML5_Charts