vue?echarts實(shí)現(xiàn)航班選座案例分析
背景
最近在echarts官方看到了一個(gè)航班選座的示例,感覺(jué)很好,可以擴(kuò)大,縮小,鼠標(biāo)放置到座位上可以顯示座位號(hào),允許默認(rèn)選中座位。于是在5.1假期抽了一點(diǎn)點(diǎn)時(shí)間,來(lái)寫(xiě)一篇文章,深入研究分析一下這個(gè)示例,解析一下這個(gè)示例的完整代碼。首先讓我們來(lái)看下示例的效果圖。
實(shí)現(xiàn)思路
代碼是使用echarts來(lái)實(shí)現(xiàn)的,主要用到的是svg和自定義地圖的相關(guān)知識(shí)。
示例的完整代碼
在做選座的功能,我們使用div布局加背景圖的技術(shù)手段也能簡(jiǎn)單實(shí)現(xiàn),但不支持縮放,在位置比較多,想要看詳細(xì)的情況下,就需要用到svg,這個(gè)可以擴(kuò)大縮小后不會(huì)失真的矢量圖形。搭配echarts渲染能力和可擴(kuò)展性,做出來(lái)的功能可以達(dá)到很好的用戶(hù)體驗(yàn)。
這個(gè)示例的主要特性大致有以下幾點(diǎn)
- 座位默認(rèn)三種狀態(tài),未選的(白色),自己選的(綠色的),已被別人選的(紅色)
- 可以擴(kuò)大,縮小,圖片不失真,清晰
- 鼠標(biāo)放到座位上可以顯示座位號(hào)
- 可移植性,換個(gè)svg文件,就能改成影院選座,或會(huì)議室排座
- 簡(jiǎn)單,快捷,代碼只有不到100行
代碼分析
獲取svg
在示例代碼中,首先是要獲取一個(gè)svg文件。
$.get(ROOT_PATH + '/data/asset/geo/flight-seats.svg', function (svg) { // .... })
使用jquery獲取一個(gè)svg文件,svg的完整路徑是 https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/examples/data/asset/geo/flight-seats.svg
點(diǎn)擊可以訪(fǎng)問(wèn)。但顯示的是這樣的。
只顯示個(gè)飛機(jī)頭,這是因?yàn)閟vg太大的原因。要想看完整的,需要使用專(zhuān)門(mén)的svg查看軟件。
使用jquery獲取的svg,是svg文件的編碼。我們可以調(diào)試,打印一下svg的內(nèi)容看一下。
這里可以看到是svg的具體內(nèi)容。
注冊(cè)自定義地圖
echarts是可以搭配地圖來(lái)實(shí)現(xiàn)自定義的位置坐標(biāo)布局渲染的。但不僅僅局限于百度,高德地圖。他還支持將一個(gè)符合地圖數(shù)據(jù)的svg注冊(cè)為一個(gè)地圖。
下面來(lái)看一下echarts的這個(gè)注冊(cè)自定義地圖的api。
registerMap
完整的解釋點(diǎn)擊此處查看
文檔的大致意思就是 你可以配置一個(gè)geoJson的東西,然后echarts可以解析內(nèi)部的坐標(biāo),然后渲染,支持查找。
echarts中g(shù)eo的相關(guān)文檔。
https://echarts.apache.org/zh/option.html#geo
該組件可以配置一些name,顏色,索引,能否被選中,交互后的顏色,hover效果。
這里稍微擴(kuò)展一下GeoJSON這個(gè)東西,我也是第一次接觸。它是一種用于編碼各種地理數(shù)據(jù)結(jié)構(gòu)的格式。
一種編程式的地圖,用一些特殊的屬性來(lái)表達(dá)地圖上的線(xiàn),面,點(diǎn),顏色。區(qū)域。
以GeoJSON支持以下幾何類(lèi)型:Point,LineString, Polygon,MultiPoint,MultiLineString,和MultiPolygon。具有其他屬性的幾何對(duì)象是Feature對(duì)象。要素集包含在FeatureCollection對(duì)象中。
這里說(shuō)的不對(duì)的,歡迎大佬拍磚,傳道解惑。
相關(guān)文檔
這里如果要展開(kāi)講的話(huà),以我現(xiàn)在的知識(shí)點(diǎn),肯定講的不夠透徹,如果有感興趣的同學(xué),可以在評(píng)論區(qū)留言,下篇文章可以給大家?guī)?lái)有關(guān)geojson更詳細(xì)的解析。
回歸主線(xiàn),那么registerMap這個(gè)方法其實(shí)就是將svg轉(zhuǎn)化為一個(gè)標(biāo)準(zhǔn)的地圖坐標(biāo)系。只不過(guò)轉(zhuǎn)化后地圖的定位不是根據(jù)經(jīng)緯度,而是因?yàn)閚ame。
echarts.registerMap('flight-seats', { svg: svg });
好了上面這句代碼的含義就講解到這里。其實(shí)想想,每一個(gè)api的后面都牽扯到一大堆的知識(shí)。只要你細(xì)心,具有探索精神,那就一定會(huì)學(xué)的比別人多,學(xué)的好。知識(shí)是連貫的,不是單獨(dú)存在的。舉一反三,融會(huì)貫通方得學(xué)道。
geo組件的配置
echarts中有很多很多的組件如brush(區(qū)域選擇組件),parallel(平行坐標(biāo)系),timeline,calendar(日歷坐標(biāo)系),其中一個(gè)就是geo,地理坐標(biāo)系組件。
地理坐標(biāo)系組件用于地圖的繪制,支持地理坐標(biāo)系上繪制散點(diǎn)圖,線(xiàn)集。
有關(guān)geo組件的所有的配置項(xiàng)都可以在此處查詢(xún)到詳細(xì)的解析。
此案例使用的就是該組件,那么下面來(lái)看下示例是如何配置的。
geo: { map: 'flight-seats', roam: true, selectedMode: 'multiple', layoutCenter: ['50%', '50%'], layoutSize: '95%', tooltip: { show: true }, itemStyle: { color: '#fff' }, emphasis: { itemStyle: { color: null, borderColor: 'green', borderWidth: 2 }, label: { show: false } }, select: { itemStyle: { color: 'green' }, label: { show: false, textBorderColor: '#fff', textBorderWidth: 2 } }, regions: makeTakenRegions(takenSeatNames) }
以上是示例中有關(guān)geo組件的配置,下面讓我們仔細(xì)分析一下每一個(gè)配置項(xiàng)。
map
首先map指向的是我們剛剛注冊(cè)的一個(gè)自定義地圖'flight-seats'
map: 'flight-seats',
roam
roam
關(guān)鍵字是用于配置是否開(kāi)啟鼠標(biāo)縮放和平移漫游。默認(rèn)不開(kāi)啟。如果只想要開(kāi)啟縮放或者平移,可以設(shè)置成 ‘scale’ 或者 ‘move’。設(shè)置成 true 為都開(kāi)啟
selectedMode
如字面意思selectedMode
字段是用于配置選中模式,表示是否支持多個(gè)選中,默認(rèn)關(guān)閉,支持布爾值和字符串,字符串取值可選’single’表示單選,或者’multiple’表示多選。
layoutCenter, layoutSize
用于調(diào)整echarts的實(shí)例在dom容器中的初始位置。
tooltip
是否開(kāi)啟tooltip效果,開(kāi)啟后,鼠標(biāo)放到座位上會(huì)有文本提示當(dāng)前座位。
itemStyle
座位的默認(rèn)樣式,配置顏色,字體
emphasis
高亮狀態(tài)下的多邊形和標(biāo)簽樣式。
select
選中狀態(tài)下的多邊形和標(biāo)簽樣式。
regions
在地圖中對(duì)特定的區(qū)域配置樣式。這里傳入的是一個(gè)數(shù)組,被格式化后的已被選的座位信息,
默認(rèn)已經(jīng)被選
每一項(xiàng)的數(shù)據(jù)格式是這樣的
{ name: '26E', silent: true, itemStyle: { color: '#bf0e08' }, emphasis: { itemStyle: { borderColor: '#aaa', borderWidth: 1 } }, select: { itemStyle: { color: '#bf0e08' } } }
其中有一個(gè)屬性叫做 silent 它的作用是圖形是否不響應(yīng)和觸發(fā)鼠標(biāo)事件,默認(rèn)為 false,即響應(yīng)和觸發(fā)鼠標(biāo)事件。
到這里該示例的echarts配置其實(shí)已經(jīng)講解完了。這里的坐標(biāo)系不是用經(jīng)緯度,而是用每個(gè)座位的name來(lái)查找的。所以在svg中是可以找到對(duì)應(yīng)的name的。name的值必須保證唯一。
該示例中除了核心的配置外,還有二個(gè)輔助函數(shù)。一起來(lái)看一下。
makeTakenRegions函數(shù)
這個(gè)函數(shù)就是將已經(jīng)定義好的已選座位數(shù)據(jù),轉(zhuǎn)化成格式化的座位樣式數(shù)據(jù)。
下面是定義的默認(rèn)已被選中的座位。
var takenSeatNames = ['26E', '26D', '26C', '25D', '23C', '21A', '20F'];
geoselectchanged
在這個(gè)示例的最后,有一個(gè)監(jiān)聽(tīng)函數(shù)
myChart.on('geoselectchanged', function (params) { var selectedNames = params.allSelected[0].name.slice(); // Remove taken seats. for (var i = selectedNames.length - 1; i >= 0; i--) { if (takenSeatNames.indexOf(selectedNames[i]) >= 0) { selectedNames.splice(i, 1); } } console.log('selected', selectedNames); });
這幾行代碼是干嘛的那?
我們?cè)邳c(diǎn)擊座位的時(shí)候,是有一個(gè)點(diǎn)擊事件,這里就是用于處理點(diǎn)擊后的交互的,然后獲取當(dāng)前用戶(hù)選中的座位。
geoselectchanged 世界是 geo 中地圖區(qū)域切換選中狀態(tài)的事件。
用戶(hù)點(diǎn)擊選中會(huì)觸發(fā)該事件。 相關(guān)文檔
我們可以調(diào)試一下該函數(shù)看下,params的內(nèi)容具體是什么
這里是用于處理點(diǎn)擊已經(jīng)被人選中的座位,不進(jìn)行選中,這段函數(shù)的使用場(chǎng)景是用于獲取當(dāng)前用戶(hù)選中的座位列表,比如用戶(hù)選完座外要將座位信息發(fā)送給后臺(tái)保存。
主要功能就是判斷選的座位是不是已經(jīng)被別人選中了,如果已被選中就剔除。
舉一反三
三
分析完代碼后,了解了每一個(gè)配置項(xiàng)的含義,那么我們趁熱打鐵做一個(gè)類(lèi)似的聯(lián)系題,以達(dá)到舉一反三,融會(huì)貫通的目的。
需求,定義一個(gè)svg文件,有6個(gè)方塊,使用它做一個(gè)選座位的功能。
定義mysvg文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg width="600px" height="600px" version="1.1" xmlns="http://www.w3.org/2000/svg"> <g name="a1"> <rect x="20" y="20" rx="20" ry="20" width="100" fill="#cccccc" stroke="#000000" height="100" /> </g> <g name="a2"> <rect x="20" y="120" rx="20" ry="20" width="100" fill="#cccccc" stroke="#000000" height="100" /> </g> <g name="a3"> <rect x="20" y="220" rx="20" ry="20" width="100" fill="#cccccc" stroke="#000000" height="100" /> </g> <g name="a4"> <rect x="20" y="320" rx="20" ry="20" width="100" fill="#cccccc" stroke="#000000" height="100" /> </g> </svg>
html代碼
<div id="main" style="height:600px;width:600px"></div> <script src="https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> <script> var chartDom = document.getElementById('main'); var myChart = echarts.init(chartDom); var option; $.get('/mysvg.svg', function (svg) { echarts.registerMap('flight-seats', { svg: svg }); var takenSeatNames = ['a1']; option = { tooltip: { }, geo: { map: 'flight-seats', roam: true, selectedMode: 'multiple', layoutCenter: ['50%', '50%'], layoutSize: '95%', tooltip: { show: true }, itemStyle: { color: '#fff' }, emphasis: { itemStyle: { color: null, borderColor: 'green', borderWidth: 2 }, label: { show: false } }, select: { itemStyle: { color: 'green' }, label: { show: false, textBorderColor: '#fff', textBorderWidth: 2 } }, regions: makeTakenRegions(takenSeatNames) } }; function makeTakenRegions(takenSeatNames) { var regions = []; for (var i = 0; i < takenSeatNames.length; i++) { regions.push({ name: takenSeatNames[i], silent: true, itemStyle: { color: '#bf0e08' }, emphasis: { itemStyle: { borderColor: '#aaa', borderWidth: 1 } }, select: { itemStyle: { color: '#bf0e08' } } }); } return regions; } myChart.setOption(option); // Get selected seats. myChart.on('geoselectchanged', function (params) { var selectedNames = params.allSelected[0].name.slice(); // Remove taken seats. for (var i = selectedNames.length - 1; i >= 0; i--) { if (takenSeatNames.indexOf(selectedNames[i]) >= 0) { selectedNames.splice(i, 1); } } console.log('selected', selectedNames); }); }) </script>
效果圖
注意點(diǎn)
- svg文件必須的每一個(gè)座位,可點(diǎn)擊區(qū)域必須要用g標(biāo)簽包裹,且name屬性需
- 定義到g標(biāo)簽上定義geojson時(shí),svg不能指向一個(gè)文本 結(jié)語(yǔ)
如果掌握了echarts的geo自定義地圖,那么你能做出非常多的示例
比如這樣的
這樣的
還有這樣的
只需要一個(gè)svg文件,再加幾個(gè)name,你就可以做成自己想要的地圖系圖表。
最后送大家一句話(huà):
不積跬步,無(wú)以至千里;不積小流,無(wú)以成江海
到此這篇關(guān)于vue echarts實(shí)現(xiàn)航班選座案例分析的文章就介紹到這了,更多相關(guān)vue echarts航班選座案例內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在vue中使用echarts實(shí)現(xiàn)飛機(jī)航線(xiàn)水滴圖詞云圖效果
- Vue中的echarts圖表如何實(shí)現(xiàn)loading效果
- vue使用Echarts設(shè)置數(shù)據(jù)無(wú)效問(wèn)題記錄及解決方法
- vue中echarts關(guān)系圖動(dòng)態(tài)增刪節(jié)點(diǎn)以及連線(xiàn)方式
- vue中使用echarts實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)綁定以及獲取后端接口數(shù)據(jù)
- vue中封裝echarts公共組件過(guò)程
- Vue使用echarts的完整步驟及解決各種報(bào)錯(cuò)
- vue-echarts如何實(shí)現(xiàn)圖表組件封裝詳解
- Vue引入echarts方法與使用介紹
相關(guān)文章
vue+express 構(gòu)建后臺(tái)管理系統(tǒng)的示例代碼
這篇文章主要介紹了vue+express 構(gòu)建后臺(tái)管理系統(tǒng)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07vue?使用addRoutes動(dòng)態(tài)添加路由及刷新頁(yè)面跳轉(zhuǎn)404路由的問(wèn)題解決方案
我自己使用addRoutes動(dòng)態(tài)添加的路由頁(yè)面,使用router-link標(biāo)簽可以跳轉(zhuǎn),但是一刷新就會(huì)自動(dòng)跳轉(zhuǎn)到我定義的通配符?*?指向的404路由頁(yè)面,這說(shuō)明沒(méi)有找到指定路由才跳到404路由的,這樣的情況如何處理呢,下面小編給大家分享解決方案,一起看看吧2023-10-10Vue data的數(shù)據(jù)響應(yīng)式到底是如何實(shí)現(xiàn)的
這篇文章主要介紹了Vue data的數(shù)據(jù)響應(yīng)式到底是如何實(shí)現(xiàn)的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02VUE實(shí)現(xiàn)表單元素雙向綁定(總結(jié))
本篇文章主要介紹了VUE實(shí)現(xiàn)表單元素雙向綁定(總結(jié)) ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08如何解決ElementPlus的el-table底白線(xiàn)問(wèn)題
這篇文章主要介紹了如何解決ElementPlus的el-table底白線(xiàn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12vue利用全局導(dǎo)航守衛(wèi)作登錄后跳轉(zhuǎn)到未登錄前指定頁(yè)面的實(shí)例代碼
這篇文章主要介紹了vue利用全局導(dǎo)航守衛(wèi)作登錄后跳轉(zhuǎn)到未登錄前指定頁(yè)面,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05