基於百度地圖SDK和Elasticsearch GEO查詢的地理圍欄分析系統(3)-前端實現
轉載自:http://www.cnblogs.com/Auyuer/p/8086975.html
MoonLight可視化訂單需求區域分析系統實現功能:
在現實生活中,計算機和互聯網迅速發展,人們越來越趨向於網絡,於是我們就有了各種各樣的系統,來幫助我們更好地生活。比如對於打車來說,我們也可以通過網上叫車,那麽我們就會產生大量的用戶訂單,特別是對於一些固定時間、固定地點,叫車用戶的訂單量會非常大,那麽我們同樣也要很好的管理這些訂單。那麽我們便要采取某些策略來統計分析,比如我們可以使用區域化的管理方式,根據ES中的數據進行圈選定位,將所圈選出的部分訂單再進行處理統計信息。那麽為了能夠更好地看到這些分析結果,我們對此提出了可視化的訂單管理系統,結合ES索引,便可完成訂單的可視化數據分析。
實現步驟:
為了安全將所有數據以及url接口隱去
- 首頁展示如下圖所示:
- 由於我們要在地圖上做一定區域的圈選操作,首先我們應該引入百度地圖:
代碼如下:
- 首先百度地圖有自己的API註冊秘鑰,使用之前登錄官方網站自行申請即可
- 引入百度地圖API註冊秘鑰、加載鼠標繪制工具、加載檢索信息窗口、加載熱力圖圖層等所需要的js (可查看百度地圖官網)
1 <!-- 百度地圖api註冊秘鑰 --> 2 <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak= "></script> 3 <!-- 加載鼠標繪制工具 --> 4 <script type="text/javascript" src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script> 5 <!-- 加載檢索信息窗口 --> 6 <script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.4/src/SearchInfoWindow_min.js"></script> 7 <!-- 加載熱力圖圖層 --> 8 <script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
- 相關js代碼如下:
1 var map = new BMap.Map(‘map_canvas‘);// 創建地圖實例 2 var point = new BMap.Point(116.404, 39.915); // 天安門 3 map.centerAndZoom(point, 12);// 初始化地圖,設置中心點坐標和地圖級別 4 map.enableScrollWheelZoom();// 允許drawingManager.open()滾輪縮放
-
創建地圖實例,設置地圖中心位置,在這裏我們以天安門為中心
- 同時我們允許鼠標滾輪縮放
- 頁面繪制功能
首頁左邊欄為繪制功能區域以及熱力圖的開啟關閉控制按鈕區域:
繪制功能包括如下:畫點、畫圓、畫折線、畫多邊形、畫矩形,相應的控制右上角的繪制功能
熱力圖的開啟和關閉:第一次點擊時向後臺發送請求,關閉按鈕為紅色,開啟按鈕為綠色,熱力圖主要分布於北京市
- 圈選操作
圈選操作由於主要有圓形圈選、矩形圈選、多邊形圈選和折線圈選幾種情況,那麽對此我們應該分情況討論:
代碼如下:
1 var overlays = []; 2 //回調獲得覆蓋物信息 overlay是覆蓋物的抽象基類 3 var overlaycomplete = function(e) { 4 overlays.push(e.overlay); 5 var result = ""; 6 result = "<p>"; 7 result += e.drawingMode + ":"; 8 if (e.drawingMode == BMAP_DRAWING_MARKER) { 9 result += ‘ 坐標:‘ + e.overlay.getPosition().lng + ‘,‘ + e.overlay.getPosition().lat; 10 11 //getPosition() 獲取標簽的經緯度坐標 lng lat 12 if ($(‘isInfowindow‘).checked) { 13 searchInfoWindow.open(e.overlay); 14 } 15 } 16 if (e.drawingMode == BMAP_DRAWING_CIRCLE) {
//圓形圈選,獲得經緯度和半徑 , 然後拼接到跳轉向圖標展示頁面的url後面, 如 url_toPic所示,即可實現不同頁面之間的參數傳遞
17 result += ‘ 半徑:‘ + e.overlay.getRadius(); 18 result += ‘ 中心點:‘ + e.overlay.getCenter().lng + "," + e.overlay.getCenter().lat; 19 var circle_r = e.overlay.getRadius(); 20 var circle_lng = e.overlay.getCenter().lng; 21 var circle_lat = e.overlay.getCenter().lat; 22 var url_toPic = "url?point=" + circle_lat + "," + circle_lng + "&radius=" + circle_r; 23 24 /* 向後臺發送post請求 地理圍欄數據*/ 25 // 圈選之後會自動跳出一個彈窗,用於可以自行保存相應的數據,自行設置名稱和分組,而地理圍欄geo和類型則是根據用戶全選情況而自動添加。
26 // jQuery("#fence_name").val(name); 27 jQuery("#geo_data").css({ 28 "display":"block" 29 }); //彈窗顯示 30 /*中間層*/ 31 jQuery("#cover").css({ 32 "display":"block" 33 }); //中間禁止點擊層顯示 34 var fence_circle_data; 35 fence_circle_data=‘{"circle":"‘+circle_r+‘","circle_lat":"‘+circle_lat+‘","circle_lng":"‘+circle_lng+‘"}‘; 36 //地理圍欄geo數據拼接和填充 37 jQuery("#fence_geo").val(fence_circle_data); 38 /*圓形1*/ 39 40 jQuery("#fence_type").val("1"); 41 42 //當點擊彈窗的保存按鈕時,則會將此次圈選信息保存起來,並存儲在地理圍欄中,方便後續查詢,然後自動跳轉到圖表展示頁面,圖表展示頁面主要是對訂單量、日盈裏和取消率的數據的具體展示 43 //從中,我們能夠看到整個月份的訂單量、日盈裏和取消率的折線趨向,同時下方表格中也將所展示的具體數據填入。如果在彈窗頁面出現時,用戶沒有填入名稱和分組,那麽我們就會給其名稱設定為當前的時間戳加上三位隨機數,而默認分組設為default。 44 jQuery("#btn_yes").click(function(){ 45 /*獲取當前時間戳*/ 46 var data_time = new Date().getTime(); 47 /*獲取0-1000之間的隨機數*/ 48 var data_random = Math.ceil(Math.random()*1000); 49 /*拼接默認彈窗名稱*/ 50 var name = "fence-"+data_time+data_random; 51 /*控制name group的默認傳參*/ 52 var name_send; 53 var group_send ; 54 56 if(jQuery("#fence_name").val() != ""){ 57 name_send = jQuery("#fence_name").val(); 58 }else{ 59 name_send = name; 60 }; 61 if(jQuery("#fence_group").val() != ""){ 62 group_send = jQuery("#fence_group").val(); 63 }else{ 64 group_send = "default"; 65 } 66 67 68 var post_data =new Object; 69 post_data.name=name_send; 70 post_data.group=group_send; 71 post_data.type=jQuery("#fence_type").val(); 72 post_data.geo=jQuery("#fence_geo").val(); 73 var saveData = JSON.stringify(post_data); 74 75 send_post("url",saveData); 76 window.open(url_toPic,"_self"); 77 }); //如果用戶點擊了取消按鈕沒有保存數據,那麽彈窗隱藏之後便會直接跳轉至圖表展示頁面而不會存儲本地圈選信息至地理圍欄數據中。 78 jQuery("#btn_no").click(function(){ 79 jQuery("#geo_data").css({ 80 "display":"none" 81 }); 82 jQuery("#cover").css({ 83 "display":"none" 84 }); 85 window.open(url_toPic,"_self"); 86 }) 87 } 88 89 if (e.drawingMode == BMAP_DRAWING_POLYLINE || e.drawingMode == BMAP_DRAWING_POLYGON || e.drawingMode == BMAP_DRAWING_RECTANGLE) { 90 //在這裏為折線、多邊形、矩形等多點圈選,將所畫出的點依次拼接到Url後面 方法同圓形圈選 91 166 }); 167 176 177 } 178 179 };
- 保存地理圍欄數據彈窗:
- 圖表展示頁面為echarts表格和折線圖 (為了安全將實際數據隱去)
4.圖表展示頁面前端實現相關代碼如下:
1 //將所傳遞過來的url後的參數解析繪制圖表 2 /*獲取url參數*/ 3 function getUrlParam(){ 4 /*拿到url地址*/ 5 var url=window.location.search; 6 /*截取?後的所有數據*/ 7 var params = url.substring(url.indexOf("?")+1); 8 /*如果url中有弧度的數據*/ 9 var str=‘radius‘; 10 var json_data; 11 /*獲取圓形圈選的經緯度和弧度*/ 12 if(url.indexOf(str)!=-1){ 13 var paramArr=params.split("&"); 14 var param_first=paramArr[0].split("="); 15 var param_lng_lat=param_first[1].split(","); 16 var circle_lat = param_lng_lat[0]; 17 var circle_lng = param_lng_lat[1]; 18 var param_second = paramArr[1].split("="); 19 var circle_r = param_second[1]; 20 21 /*請求後端接口*/ 22 json_data=send_get("url?point=" + circle_lat + "," + circle_lng + "&radius=" + circle_r); 23 24 }else{ 25 /*截取url中等號右邊的參數*/ 26 var paramSqual=params.split("="); 27 var paramSqual_lng_lat; 28 var url_getSqual; 29 url_getSqual="url?"; 30 /*參數列表為用;分割開的經緯度數據*/ 31 var paramSqual_Arr = paramSqual[1].split(";"); 32 for(var i=0;i<paramSqual_Arr.length;i++){ 33 paramSqual_lng_lat=paramSqual_Arr[i].split(","); 34 url_getSqual+="point"+i+"="+paramSqual_lng_lat[0]+‘,‘+paramSqual_lng_lat[1]+‘&‘; 37 } 38 url_getSqual=url_getSqual.substring(0,url_getSqual.length-1); 39 json_data=send_get(url_getSqual); 40 41 }
相關圖表echarts代碼展示如下:
以訂單量為例,其他折線圖代碼類似。 具體使用方法建議查看Echarts官方網站
1 /*渲染圖表*/ 2 3 /*日訂單量圖表展示區*/ 4 var chartName_total = echarts.init(document.getElementById("chart_total")); 5 var adata_total=json_data.data; 6 var option_total = { 7 title: { 8 text: ‘訂單量分析‘ 9 }, 10 tooltip: { 11 trigger: ‘axis‘ 12 }, 13 legend: { 14 data:[‘訂單量‘] 15 }, 16 grid: { 17 left: ‘3%‘, 18 right: ‘4%‘, 19 bottom: ‘3%‘, 20 containLabel: true 21 }, 22 toolbox: { 23 feature: { 24 saveAsImage: {} 25 } 26 }, 27 xAxis: { 28 type: ‘category‘, 29 boundaryGap: false, 30 data:adata_total["xAxis"] 31 }, 32 yAxis: { 33 type: ‘value‘ 34 }, 35 series: [ 36 { 37 name: ‘訂單數量‘, 38 type: ‘line‘, 39 stack: ‘總量‘, 40 data: adata_total["total"] 41 } 42 ] 43 }; 44 chartName_total.setOption(option_total);
表格中的數據展示代碼: 也可使用其他方式渲染
/*表格中的數據*/ var tableData =json_data.data.detail; var tableSource="<table id=‘example‘ class=‘table table-striped table-bordered‘>"
+ "<thead><tr><th>日期</th> <th>訂單總量</th> <th>日盈利</th> <th>取消率</th></tr></thead><tbody>"; for(var j=0;j<tableData.length;j++){ tableSource+="<tr><th style=‘font-weight:normal‘>"
+tableData[j].date
+"</th><th style=‘font-weight:normal‘>"
+tableData[j].total
+"</th><th style=‘font-weight:normal‘>"
+tableData[j].profit
+"</th><th style=‘font-weight:normal‘>"
+tableData[j].cancelRatio; } tableSource +="</tbody><tfoot><tr> <th>日期</th> <th>訂單總量</th> <th>日盈利</th> <th>取消率</th> </tr> </tfoot></table>"; $("#container").append(tableSource);
5.地理圍欄數據存儲頁面
所有被圈選的數據都會在這裏進行存儲,當我們點擊查看按鈕時,則可再次查看相應地理圍欄信息數據的圖表展示,而點擊刪除並且確認刪除之後,則會直接將此條數據刪除。
查詢按鈕即可根據相應的條件篩選而取得符合條件的數據。
(1)查看和刪除按鈕的代碼如下:
1 //刪除和查看數據代碼 2 //點擊刪除按鈕時,將該行數據刪除,並且調用後端接口,刪除後端數據 3 function delete_data(){ 4 $(".btn_delete").click(function(){ 5 if(confirm("是否確認刪除?")){ 6 $(this).parents("tr").remove(); 7 var delete_id=$(this).parents("tr").children("th.delete_id").text(); //先找到父元素,再找父元素中需要的子元素 8 var url_delete; 9 url_delete="url?id="; 10 url_delete+=delete_id; 11 var delete_data=send_get(url_delete); 12 alert(delete_data.message); 13 }else{ 14 return false; 15 } 16 }); 17 18 //點擊查看按鈕時,將url拼接對應經緯度數據等,然後跳轉到圖表展示頁面並且進行利用所傳遞的參數進行圖表繪制,圓形圈選需要的是中心點和半徑,而其他都是將各個點的經緯度依次拼接即可。 19 $(".btn_look").click(function(){ 20 var jsonStr=$(this).parents("tr").children("th.tabData_geo").text(); 21 console.log($(this).parents("tr").children("th.tabData_geo").text()); 22 var json=$.parseJSON(String(jsonStr)); 23 console.log(json); 24 var look_url; 25 var num=0; 26 var jsonType=$(this).parents("tr").children("th#fence_type").text(); 27 if(jsonType == "環形") { 28 look_url= "url?point=" + json.circle_lat + "," + json.circle_lng + "&radius=" + json.circle; 29 window.open(look_url,"_self") 30 }else { 31 look_url= "url?point="; 32 for(var i=0;i<json.length;i++){ 33 for(var j in json[i]) { 34 num++; 35 look_url+=json[i][j]; 36 if(num%2==0) { 37 look_url+=";"; 38 }else { 39 look_url+=","; 40 } 41 } 42 } //根據自己的需要拼接字符串url 43 look_url=look_url.substring(0,look_url.length-1); 44 window.open(look_url , "_self") 45 } 46 }); 47 }
(2)表格繪制部分代碼:
1 //該表格繪制部分分為不同情況,比如我們剛一打開頁面時, 2 //要向後端默認傳遞頁碼為1,而所拿到的數據是全部數據。 3 //而當我們點擊了查詢按鈕之後,所拿到的數據多少又會發生變化 4 //向後端傳遞的字段為page_json ,代碼中即可看到具體的內容 5 function tabData_show(){ 6 7 var json_data; 8 var page_json = { 9 "name": null, 10 "group": null, 11 "type": null, 12 "startTime": null, 13 "endTime": null, 14 "pageSize": 10||null, 15 "pageNum": 1||null 16 }; 17 page_json = JSON.stringify(page_json); 18 json_data = send_post("url",page_json); 19 var tabData = json_data.data.data; 20 21 var totle_Page = Math.ceil(json_data.data.total/10); 22 var now_Page = json_data.data.nowPage; 23 var page_Limit = Math.min(9 , totle_Page); 24 //nowPage=now_Page; 25 //maxPage=totle_Page; 26 page(now_Page,totle_Page , page_Limit); 27 /*地理圍欄表格*/ 28 …… 29 //接下來根據數據自行渲染表格即可
}
(3)查詢部分代碼:
1 /*search按鈕點擊時的搜索功能*/ 2 //查詢按鈕點擊的時候,沒有添加過濾條件時默認返回所有數據進行渲染 3 //而如果有過濾條件時則根據篩選條件返回相應的數據 4 $(".search").click(function () { 5 $("#page-item a.page-link").remove(); 6 var search_type; 7 if($("#btn_search_type").val() == "環形") { 8 search_type = 1; 9 }else if($("#btn_search_type").val() == "矩形") { 10 search_type = 2; 11 }else{ 12 search_type = 3; 13 } 14 var search_json = { 15 "name": $("#btn_search_name").val() || null, 16 "group": $("#btn_search_group").val() || null, 17 "type": search_type || null, 18 "startTime": $("#btn_search_start").val() || null, 19 "endTime": $("#btn_search_end").val() || null, 20 "pageSize": 10 || null, 21 "pageNum": 1 || null 22 }; 23 search_json = JSON.stringify(search_json); 24 25 var data_Json = send_post("url", search_json); 26 var dataJson = data_Json.data.data; 27 var totle_search = Math.ceil(data_Json.data.total / 10); 28 var search_Page = data_Json.data.nowPage; 29 var search_Limit = Math.min(9, totle_search); 30 page(search_Page, totle_search, search_Limit); 31 32 //然後再根據新拿到的不同數據渲染表格 49 });
到此 地理圍欄的前端實現方法基本結束,後續不斷改進中。
基於百度地圖SDK和Elasticsearch GEO查詢的地理圍欄分析系統(3)-前端實現