日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

百度数据可视化图表套件echart实战

發(fā)布時(shí)間:2024/9/20 编程问答 108 豆豆
生活随笔 收集整理的這篇文章主要介紹了 百度数据可视化图表套件echart实战 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近我一直在做數(shù)據(jù)可視化的前端工作,我用的最多的繪圖工具是d3。d3有點(diǎn)像photoshop,功能很強(qiáng)大,例子也很多,但是學(xué)習(xí)成本也不低,做項(xiàng)目是需要較大人力投入的。3月底由在亞馬遜工作的同學(xué)介紹下使用了一下echart,一個(gè)由百度前端發(fā)起的canvas國(guó)產(chǎn)類庫(kù)(官網(wǎng):http://echarts.baidu.com/index.html)。這個(gè)echart其實(shí)是在canvas類庫(kù)zrender的基礎(chǔ)上做的主題圖庫(kù),優(yōu)點(diǎn)有數(shù)據(jù)驅(qū)動(dòng),圖例豐富,功能強(qiáng)大,支持?jǐn)?shù)據(jù)拖拽重計(jì)算,數(shù)據(jù)區(qū)域漫游,全中文文檔非常過(guò)癮。跟同樣是國(guó)產(chǎn)的前端腳手架fis一樣(官網(wǎng)http://fis.baidu.com/),都是誠(chéng)意滿滿的國(guó)產(chǎn)套餐,體現(xiàn)了現(xiàn)今國(guó)內(nèi)不俗的前端開發(fā)實(shí)力。使用它們的感覺就像想自己做個(gè)平板電腦,去華強(qiáng)北一轉(zhuǎn),主板、CPU、屏幕等各種套餐一訂購(gòu),東西就嘩嘩地組裝起來(lái)了。極其高效,非常適合商業(yè)項(xiàng)目開發(fā)。而且,即使是為了研究,用這些也可以打一個(gè)很好的基礎(chǔ)。

Echart圖表庫(kù)層次關(guān)系

1.引入目錄

廢話不多說(shuō)了,看到好東西,第一步是從github上把相關(guān)文件全下下來(lái),然后到build目錄翻箱倒柜把東西找齊。新建目錄如下:

echarts-1.3.8
—-zrender ? //zrender是echart依賴的繪圖庫(kù),官網(wǎng)要求下載,但是目前我的程序中并沒有直接引用它,可以說(shuō)普通情況下echart可以自己獨(dú)立運(yùn)行
——–zrender.js
—-excanvas_r3 //excanvas是實(shí)現(xiàn)IE7,8兼容canvas繪圖的利器,實(shí)現(xiàn)了大部分canvas的API,在繪圖方面其核心是通過(guò)IE的VML去實(shí)現(xiàn)的,效率較低
——–excanvas.js
—-echarts.js ?//echarts主程序,包含除map以外所有的主題圖庫(kù)。注意這個(gè)是壓縮過(guò)的,并且只能通過(guò)requirejs或者esl.js模塊化加載;想用標(biāo)簽或sea.js加載請(qǐng)用echarts-plain.js
—-echarts-orginal.js ?//沒有壓縮過(guò)的echarts.js
—-echarts-map.js ?//echarts的map主題圖庫(kù)

2.在自己的項(xiàng)目中實(shí)現(xiàn)其demo

這個(gè)echart是百度前端做的,他們推薦使用模塊式開發(fā)。好在我之前的項(xiàng)目,就是采用requirejs + angularjs開發(fā)的。所以引入比較容易。

首先,在requirejs的入口配置文件main.js里加上echart:

require.config({baseUrl:'application/views/frontEnd/build/',paths:{//這里省略若干配置信息...//echart及其組件,echarts: 'lib/echarts-1.3.8/echarts',"echarts/chart/line": 'lib/echarts-1.3.8/echarts',"echarts/chart/bar": 'lib/echarts-1.3.8/echarts','echarts/chart/scatter': 'lib/echarts-1.3.8/echarts','echarts/chart/k': 'lib/echarts-1.3.8/echarts','echarts/chart/pie': 'lib/echarts-1.3.8/echarts','echarts/chart/radar': 'lib/echarts-1.3.8/echarts','echarts/chart/map': 'lib/echarts-1.3.8/echarts','echarts/chart/chord': 'lib/echarts-1.3.8/echarts','echarts/chart/force': 'lib/echarts-1.3.8/echarts',zrender: 'lib/echarts-1.3.8/zrender/zrender'},priority:['angular']//,urlArgs:'v=1.1' });

然后,在要引入echart的具體頁(yè)面控制js文件里,加載相關(guān)依賴。

define(['echarts','echarts/chart/pie','d3'], function (ec) {function common_chart_staff_assess_ctrl($http, $scope) {// angularjs的控制器....}}return common_chart_staff_assess_ctrl; });

以上兩步,熟悉dojo或者requirejs的朋友應(yīng)該都毫無(wú)壓力,但是還是有很多朋友沒用過(guò)這些,所以還是有必要說(shuō)一下的。

接著就是把官網(wǎng)的例子放在自己的頁(yè)面里實(shí)現(xiàn)。這里我選取了一個(gè)特別的千層餅圖,點(diǎn)擊這里去官網(wǎng)查看原圖。

那么我們把例子里的靜態(tài)數(shù)據(jù)(option對(duì)象)搬運(yùn)到我們自己的JS文件中,然后仿照官網(wǎng)的例子寫一個(gè)渲染&刷新函數(shù)

//渲染&刷新函數(shù)$scope.refresh = function(option,isBtnRefresh){if (isBtnRefresh) {needRefresh = true;if (needRefresh) {myChart.showLoading();setTimeout($scope.refresh(option), 500);}return;}needRefresh = false;if (myChart && myChart.dispose) {myChart.dispose();}myChart = ec.init(domMain);window.onresize = myChart.resize;myChart.setOption(option, true);domMessage.innerHTML = '';};//測(cè)試數(shù)據(jù) $scope.option = {title : {text: '瀏覽器占比變化',subtext: '純屬虛構(gòu)',x:'right',y:'bottom'},tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} (ozvdkddzhkzd%)"},legend: {orient : 'vertical',x : 'left',data:['Chrome','Firefox','Safari','IE9+','IE8-']},toolbox: {show : true,feature : {mark : {show: true},dataView : {show: true, readOnly: false},restore : {show: true},saveAsImage : {show: true}}},calculable : false,series : (function(){var series = [];for (var i = 0; i < 30; i++) {series.push({name:'瀏覽器(數(shù)據(jù)純屬虛構(gòu))',type:'pie',itemStyle : {normal : {label : {show : i > 28},labelLine : {show : i > 28, length:20}}},radius : [i * 4 + 40, i * 4 + 43],data:[{value: i * 128 + 80, name:'Chrome'},{value: i * 64 + 160, name:'Firefox'},{value: i * 32 + 320, name:'Safari'},{value: i * 16 + 640, name:'IE9+'},{value: i * 8 + 1280, name:'IE8-'}]})}series[0].markPoint = {symbol:'emptyCircle',symbolSize:series[0].radius[0],effect:{show:true,scaleSize:12,color:'rgba(250,225,50,0.8)',shadowBlur:10,period:30},data:[{x:'50%',y:'50%'}]};return series;})() }; setTimeout(function(){var _ZR = myChart.getZrender();// 補(bǔ)充千層餅_ZR.addShape({shape : 'text',style : {x : _ZR.getWidth() / 2,y : _ZR.getHeight() / 2,color: '#666',text : '惡夢(mèng)的過(guò)去',textAlign : 'center'}});_ZR.addShape({shape : 'text',style : {x : _ZR.getWidth() / 2 + 200,y : _ZR.getHeight() / 2,brushType:'fill',color: 'orange',text : '美好的未來(lái)',textAlign : 'left',textFont:'normal 20px 微軟雅黑'}});_ZR.refresh(); }, 2000);

然后在頁(yè)面上找個(gè)div,顯示echart就可以了。

不過(guò)請(qǐng)注意一定要給這個(gè)div設(shè)置寬度高度,否則圖顯示不出來(lái)不要怪我。

<section class="span12"> <div id="graph" class="graph chart-area" style="height:500px"></div> </section> 我這里用了bootstrap,寬度是按柵格系統(tǒng)的百分比值變化的,所以上面的代碼中沒有指定寬度。最后調(diào)試調(diào)試,沒有問(wèn)題我這里也可以顯示。

3.定制

當(dāng)然,僅僅停留在引用別人的例子是不能讓我滿意的。

首先,要進(jìn)行數(shù)據(jù)綁定。

這里細(xì)分為3步:

  • 分析數(shù)據(jù)格式(就是分析option對(duì)象,這一步需要注意把后臺(tái)獲取的數(shù)據(jù)和樣式信息分開。故而我在代碼里設(shè)置了$scope.option對(duì)象存儲(chǔ)默認(rèn)的樣式配置信息,之后ajax獲取數(shù)據(jù)后將二者再extend即可。)
  • 在后臺(tái)組裝相應(yīng)的數(shù)據(jù)(根據(jù)不同需求而異,我這里只取數(shù)值信息,不多言)
  • 前臺(tái)ajax獲取真實(shí)數(shù)據(jù)(這一點(diǎn)相信大家都很純熟,不過(guò)我的代碼里是使用angularjs封裝過(guò)的$.post對(duì)象來(lái)做到這一點(diǎn)的)
  • //設(shè)置真實(shí)數(shù)據(jù)格式 $scope.default_option = {title : {text: '故障類型時(shí)序變化年輪圖',subtext: '本圖由內(nèi)向外展示了各種故障類型的出現(xiàn)頻率所占百分比,及其隨時(shí)間變化的規(guī)律',x:'right',y:'bottom'},tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} (ozvdkddzhkzd%)"},legend: {orient : 'vertical',x : 'left',selected: $scope.faultnameSelected,data:$scope.faultname},toolbox: {show : true,feature : {mark : true,dataView : {readOnly: false},restore : true,saveAsImage : true}},calculable : false,series : {} };$scope.ajaxChartData = function(dataname){ myChart.showLoading({text: '正在努力的讀取數(shù)據(jù)中...', //loading話術(shù)}); $http.post("index.php/main/readfaultnum", null).success(function(alldata){console.log(alldata);var option = $scope.default_option;option.series = $scope.setData(alldata);$scope.refresh(option,true);$scope.order = dataname;myChart.hideLoading(); }).error(function(){domMessage.innerHTML = '網(wǎng)絡(luò)故障,獲取數(shù)據(jù)失敗';});};
  • 5.進(jìn)一步定制

    雖然我使用了官網(wǎng)的例子實(shí)現(xiàn)了需求,但是我還有些自己的想法。

    官網(wǎng)的千層餅圖中,代表時(shí)間的年輪寬度是固定的。但是我們從后臺(tái)讀取的數(shù)據(jù)(以月為顆粒度)在時(shí)間上是變化的,隨著系統(tǒng)使用時(shí)間增長(zhǎng)而增長(zhǎng)。這就導(dǎo)致一個(gè)問(wèn)題,就是在只有一個(gè)月時(shí),年輪只有小小一個(gè),有50個(gè)月時(shí),年輪多到超過(guò)了顯示范圍。這樣很不美觀,并且喪失了一定的可用性。

    我決定要對(duì)其進(jìn)行優(yōu)化。當(dāng)使用月份很少導(dǎo)致數(shù)據(jù)很少的時(shí)候,年輪會(huì)很寬;當(dāng)使用月份很多導(dǎo)致數(shù)據(jù)很多的時(shí)候,年輪會(huì)很細(xì)——這樣就可以同時(shí)避免數(shù)據(jù)量小的時(shí)候不美觀和數(shù)據(jù)量大的時(shí)候喪失可用性的問(wèn)題了。當(dāng)然,如果數(shù)據(jù)量過(guò)大,年輪就會(huì)過(guò)細(xì),同樣會(huì)喪失可用性。因此我們要設(shè)置一個(gè)最大數(shù)據(jù)量的閾值,把超過(guò)的部分砍掉。

    解決方案就是要對(duì)根據(jù)數(shù)據(jù)量對(duì)年輪寬度進(jìn)行縮放,也就是使用比例尺函數(shù)。在echart里我暫時(shí)沒有找到這樣的比例尺函數(shù)。當(dāng)然,線性比例尺很簡(jiǎn)單,函數(shù)可以自己寫。但是其他類型的比例尺縮放就稍微要一些技巧了。好在之前我一直是使用d3類庫(kù)來(lái)做可視化的,我知道d3里有這樣的比例尺函數(shù)可以很容易地解決我的問(wèn)題。那就是d3.scale對(duì)象,其中包含線性比例尺、平方比例尺、指數(shù)比例尺、集合比例尺,完全可以滿足需要。我可以從開源的d3庫(kù)中把比例尺函數(shù)抽取出來(lái),也引入到這個(gè)頁(yè)面。根據(jù)實(shí)際數(shù)據(jù)的測(cè)試結(jié)果,我選擇了平方比例尺。那么接下來(lái)就很好寫了:

    var maxTime = 36; //本千層餅圖最多顯示60個(gè)月的數(shù)據(jù)(最多顯示60個(gè)圈) //原始數(shù)據(jù)的加工工廠函數(shù) $scope.setData = function(data){//這是D3的平方比例尺函數(shù),用于根據(jù)數(shù)據(jù)大小縮放環(huán)的寬度var rScale = d3.scale.sqrt().domain([maxTime, 1]).range([3, 30]).nice();console.log(rScale(1), rScale(12), rScale(36))//如果數(shù)據(jù)量超過(guò)60(即有60個(gè)月),則刪除60個(gè)月之前的數(shù)據(jù),只顯示最近60個(gè)月的內(nèi)容if(data.length > maxTime){data.splice(0, maxTime);}//經(jīng)過(guò)D3比例尺計(jì)算的環(huán)的寬度var R = rScale(data.length);console.log(R);for(var i=0; i<data.length; i++){data[i]['type'] = 'pie';data[i]['radius'] = [i * R + 40, i * R + 40 + R]; //if(typeof($scope.times[i])!= null)data[i]['name'] = $scope.times[i];data[i]['itemStyle'] = {normal : {label : {show : i > (data.length-2)},labelLine : {show : i > (data.length-2), length:40,color : '#f0f',width : 10,type : 'dotted'}}}; }//顯示中央文字setTimeout(function(){var myDate = new Date();var myMouth = myDate.getMonth()+1;var myYear = myDate.getFullYear(); //獲取完整的年份(4位,1970-????)// 補(bǔ)充千層餅中央的說(shuō)明文字var _ZR = myChart.getZrender();_ZR.addShape({shape : 'text',style : {x : _ZR.getWidth() / 2,y : _ZR.getHeight() / 2,color: 'orange',text : data.length + '個(gè)月前',textAlign : 'center'}});_ZR.addShape({shape : 'text',style : {x : _ZR.getWidth() / 2 + data.length * R +50,y : _ZR.getHeight() / 2,color: 'orange',strokeColor: 'pink',text : '今日 ' + myYear + "年" + myMouth + "月" ,textAlign : 'left',textFont:'normal 14px 微軟雅黑'}});_ZR.refresh();}, 500);return data; }; 這樣,無(wú)論數(shù)據(jù)量大小,年輪圖都有可用性:

    只有4個(gè)月數(shù)據(jù)時(shí)的年輪圖

    30個(gè)月的測(cè)試數(shù)據(jù)的年輪圖

    當(dāng)然,做到這一步,雖然實(shí)現(xiàn)了需求,但畢竟是照著別人的例子修改,沒有自己創(chuàng)作來(lái)的有深度。不過(guò)如何自己創(chuàng)作,就超過(guò)了本文的范疇,并且也不是這一篇博客所能包含得了的,日后再議。

    5.瀏覽器兼容性:

    最后必須一提瀏覽器兼容性問(wèn)題。IE8、IE7瀏覽器不兼容canvas繪圖(IE6請(qǐng)?jiān)试S我直接無(wú)視),為了實(shí)現(xiàn)兼容需要引入excanvas_r3庫(kù)。

    1 2 3 4 5 <!--Le?HTML5?shim,forIE6-8supportofHTML5elements--> ????<!--[ifltIE9]> ??????<script?src="application/views/frontEnd/build/lib/html5shiv.js"></script> ??????<script?src="application/views/frontEnd/build/lib/echarts-1.3.8/excanvas/excanvas.js"></script> ????<![endif]-->

    有時(shí)IE8中繪圖錯(cuò)位,加入以下代碼啟用IE7兼容模式即可解決:

    1 2 3 4 <!--解決IE8中canvas繪圖錯(cuò)位--> ????<!--[iflt?IE9]> ????<meta?http-equiv="X-UA-Compatible"content="IE=7"/> ????<![endif]-->

    總結(jié)

    以上是生活随笔為你收集整理的百度数据可视化图表套件echart实战的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。