百度地圖、ECharts整合HT for Web網(wǎng)絡(luò)拓?fù)鋱D應(yīng)用
來(lái)源:易賢網(wǎng) 閱讀:1889 次 日期:2015-08-24 14:25:07
溫馨提示:易賢網(wǎng)小編為您整理了“百度地圖、ECharts整合HT for Web網(wǎng)絡(luò)拓?fù)鋱D應(yīng)用”,方便廣大網(wǎng)友查閱!

前一篇談及到了ECharts整合HT for Web的網(wǎng)絡(luò)拓?fù)鋱D應(yīng)用,后來(lái)在ECharts的Demo中看到了有關(guān)空氣質(zhì)量的相關(guān)報(bào)表應(yīng)用,就想將百度地圖、ECharts和HT for Web三者結(jié)合起來(lái)也做一個(gè)類似空氣質(zhì)量報(bào)告的報(bào)表+拓?fù)鋱D應(yīng)用,于是有了下面的Demo:

名單

在這個(gè)Demo中,將GraphView拓?fù)鋱D組件添加到百度地圖組件中,覆蓋在百度地圖組件之上,并且在百度地圖組件上和GraphView拓?fù)鋱D組件上分別添加事件監(jiān)聽(tīng),相互同步經(jīng)緯度和屏幕位置信息,從而來(lái)控制拓?fù)鋱D上的組件位置固定在地圖上,并在節(jié)點(diǎn)和節(jié)點(diǎn)之間的連線上加上了流動(dòng)屬性。右下角的圖標(biāo)框是采用HT for Web的Panel面板組件結(jié)合ECharts圖表組件完成的。

接下來(lái)我們來(lái)看看具體的代碼實(shí)現(xiàn):

1.百度地圖是如何與HT for Web組件結(jié)合的;

map = new BMap.Map("map"); var view = graphView.getView(); view.className = 'graphView'; var mapDiv = document.getElementById('map'); mapDiv.firstChild.firstChild.appendChild(view);

首先需要在body中存在id為map的div,再通過(guò)百度地圖的api來(lái)創(chuàng)建一個(gè)map地圖對(duì)象,然后創(chuàng)建GraphView拓?fù)鋱D組件,并獲取GraphView組件中的view,最后將view添加到id為map的div的第二代孩子節(jié)點(diǎn)中。這時(shí)候問(wèn)題就來(lái)了,為什么要將view添加到map的第二代孩子節(jié)點(diǎn)中呢,當(dāng)你審查元素時(shí)你會(huì)發(fā)現(xiàn)這個(gè)div是百度地圖的遮罩層,將view添加到上面,會(huì)使view會(huì)是在地圖的頂層可見(jiàn),不會(huì)被地圖所遮擋。

2.百度地圖和GraphView的事件監(jiān)聽(tīng);

map.addEventListener('moveend', function(e){ resetPosition(); }); map.addEventListener('dragend', function(e){ resetPosition(); }); map.addEventListener('zoomend', function(e){ resetPosition(); }); graphView.handleScroll = function(){}; graphView.handlePinch = function(){}; function resetPosition(e){ graphView.tx(0); graphView.ty(0); dataModel.each(function(data){ var lonLat, position; if(data instanceof ht.HtmlNode){ if(data.getId() != 'chartTotal') { position = data.getHost().getPosition(); position = {x: position.x + 168, y: position.y + 158}; data.setPosition(position.x, position.y); } } else if(data instanceof ht.Node){ lonLat = data.lonLat; position = map.pointToPixel(lonLat); data.setPosition(position.x,position.y); } }); }

首先監(jiān)聽(tīng)map的三個(gè)事件:moveend、 dragend、 zoomend,這三個(gè)事件做了同一件事--修改DataModel中所有data的position屬性,讓其在屏幕上的坐標(biāo)與地圖同步,然后將GraphView的Scroll和Pinch兩個(gè)事件的執(zhí)行函數(shù)設(shè)置為空函數(shù),就是當(dāng)監(jiān)聽(tīng)到Scroll或者Pinch事件時(shí)不做任何的處理,將這兩個(gè)事件交給map來(lái)處理。

在resetPosition函數(shù)中,做的事情很簡(jiǎn)單:遍歷DataModel中的data,根據(jù)它們各自在地圖上的經(jīng)緯度來(lái)?yè)Q算成屏幕坐標(biāo),并將坐標(biāo)設(shè)置到相應(yīng)的data中,從而達(dá)到GraphView中的節(jié)點(diǎn)能夠固定在地圖上的效果。

名單

3.創(chuàng)建右下角的圖表組件:

ht.Chart = function(option){ var self = this, view = self._view = document.createElement('div'); view.style.position = 'absolute'; view.style.setProperty('box-sizing', 'border-box', null); self._option = option; self._chart = echarts.init(self.getView()); if(option) self._chart.setOption(option); self._FIRST = true; }; ht.Default.def('ht.Chart', Object, { ms_v: 1, ms_fire: 1, ms_ac: ['chart', 'option', 'isFirst', 'view'], validateImpl: function(){ var self = this, chart = self._chart; chart.resize(); if(self._FIRST){ self._FIRST = false; chart.restore(); } }, setSize: function(w, h){ var view = this._view; view.style.width = w + 'px'; view.style.height = h + 'px'; } }); function createPanel(title, width, height){ chart = new ht.Chart(option); var c = chart.getChart(); c.on(echarts.config.EVENT.LEGEND_SELECTED, legendSelectedFun); var chartPanel = new ht.widget.Panel({ title: title, restoreToolTip: "Overview", width: width, contentHeight: height, narrowWhenCollapse: true, content: chart, expanded: true }); chartPanel.setPositionRelativeTo("rightBottom"); chartPanel.setPosition(0, 0); chartPanel.getView().style.margin = '10px'; document.body.appendChild(chartPanel.getView()); }

首先定義了ht.Chart類,并實(shí)現(xiàn)了validateImpl方法,方法中處理的邏輯也很簡(jiǎn)單:在每次方法執(zhí)行的時(shí)候調(diào)用圖表的reset方法重新設(shè)定圖標(biāo)的展示大小,如果該方法是第一次執(zhí)行的話,就調(diào)用圖表的restore方法將圖表還原為最原始的狀態(tài)。會(huì)有這樣的設(shè)計(jì)是因?yàn)閔t.Chart類中的view是動(dòng)態(tài)創(chuàng)建的,在沒(méi)有添加到dom之前將一直存在于內(nèi)存中,在內(nèi)存中因?yàn)椴](méi)有瀏覽器寬高信息,所以div的實(shí)際寬高均為0,因此chart將option內(nèi)容繪制在寬高為0的div中,即使你resize了chart,如果沒(méi)用重置圖表狀態(tài)的話,圖表狀態(tài)將無(wú)法在圖表上正常顯示。

接下來(lái)就是創(chuàng)建panel圖表組件了,這是HT for Web的Panel組件的基本用法,其中content屬性的值可以是HT for Web的任何組件或div元素,如果是HT fro Web組件的話,該組件必須實(shí)現(xiàn)了validateImpl方法,因?yàn)樵趐anel的屬性變化后將會(huì)調(diào)用content對(duì)應(yīng)組件的validateImpl方法來(lái)重新布局組件內(nèi)容。

4.ECharts和GraphView拓?fù)鋱D組件的交互:

legendSelectedFun = function(param) { if(chart._legendSelect){ delete chart._legendSelect; return; } console.info(param); var id = nodeMap[param.target], dm = graphView.dm(), data = dm.getDataById(id), sm = dm.sm(), selection = sm.getSelection(); if(param.selected[param.target]) { sm.appendSelection([data]); if(selectionData.indexOf(param.target) < 0){ selectionData.push(param.target); } }else { sm.removeSelection([data]); var index = selectionData.indexOf(param.target); if(index >= 0){ selectionData.splice(index, 1); } } sm.setSelection(selection.toArray()); }; graphView.mi(function(e){ console.info(e.kind, e.data); var c = chart.getChart(), legend = c.component.legend, selectedMap = legend.getSelectedMap(); if(e.kind === 'endRectSelect'){ chart._legendSelect = true; for(var name in notes){ legend.setSelected(name, false); } notes = {}; graphView.dm().sm().each(function(data){ var note = data.s('note'); if(note) notes[note] = 1; }); for(var name in notes){ legend.setSelected(name, true); } } else if(e.kind === 'clickData'){ chart._legendSelect = true; var data = e.data; if(data instanceof ht.Node){ var note = data.s('note'); if(note){ var selected = legend.isSelected(note); if(selected){ graphView.dm().sm().removeSelection([data]); } legend.setSelected(note, !selected); } } } });

legendSelectedFun函數(shù)是EChart圖表的legend插件選中事件監(jiān)聽(tīng),其中處理的邏輯是:當(dāng)legend插件中的某個(gè)節(jié)點(diǎn)被選中了,也選中在GraphView拓?fù)鋱D中對(duì)應(yīng)的節(jié)點(diǎn),當(dāng)取消選中是,也取消選中GraphView拓?fù)鋱D中對(duì)應(yīng)的節(jié)點(diǎn)。

在GraphView中添加交互監(jiān)聽(tīng),如果在GraphView中做了框選操作,在框選結(jié)束后,將原本legend插件上被選中的節(jié)點(diǎn)取消選中,然后再獲取被選中節(jié)點(diǎn),并在legend插件上選中對(duì)應(yīng)節(jié)點(diǎn);當(dāng)GraphView上的節(jié)點(diǎn)被選中,則根據(jù)legend插件中對(duì)應(yīng)節(jié)點(diǎn)選中情況來(lái)決定legend插件中的節(jié)點(diǎn)和graphView上的節(jié)點(diǎn)是否選中。

在GraphView交互中,我往chart實(shí)例中添加了_legendSelect變量,該變量的設(shè)定是為了阻止在GraphView交互中修改legend插件的節(jié)點(diǎn)屬性后回調(diào)legendSelectedFun回調(diào)函數(shù)做修改GraphView中節(jié)點(diǎn)屬性操作。

名單

更多信息請(qǐng)查看IT技術(shù)專欄

更多信息請(qǐng)查看技術(shù)文章
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門(mén)公布的正式信息和咨詢?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)