溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue?echarts怎么實現(xiàn)航班選座

發(fā)布時間:2022-05-16 09:41:26 來源:億速云 閱讀:349 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹了vue echarts怎么實現(xiàn)航班選座的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇vue echarts怎么實現(xiàn)航班選座文章都會有所收獲,下面我們一起來看看吧。

背景

最近在echarts官方看到了一個航班選座的示例,感覺很好,可以擴大,縮小,鼠標放置到座位上可以顯示座位號,允許默認選中座位。于是在5.1假期抽了一點點時間,來寫一篇文章,深入研究分析一下這個示例,解析一下這個示例的完整代碼。首先讓我們來看下示例的效果圖。

vue?echarts怎么實現(xiàn)航班選座

實現(xiàn)思路

代碼是使用echarts來實現(xiàn)的,主要用到的是svg和自定義地圖的相關知識。
示例的完整代碼

vue?echarts怎么實現(xiàn)航班選座

在做選座的功能,我們使用div布局加背景圖的技術手段也能簡單實現(xiàn),但不支持縮放,在位置比較多,想要看詳細的情況下,就需要用到svg,這個可以擴大縮小后不會失真的矢量圖形。搭配echarts渲染能力和可擴展性,做出來的功能可以達到很好的用戶體驗。
這個示例的主要特性大致有以下幾點

  • 座位默認三種狀態(tài),未選的(白色),自己選的(綠色的),已被別人選的(紅色)

  • 可以擴大,縮小,圖片不失真,清晰

  • 鼠標放到座位上可以顯示座位號

  • 可移植性,換個svg文件,就能改成影院選座,或會議室排座

  • 簡單,快捷,代碼只有不到100行

代碼分析

獲取svg

在示例代碼中,首先是要獲取一個svg文件。

$.get(ROOT_PATH + '/data/asset/geo/flight-seats.svg', function (svg) {
  // ....
})

使用jquery獲取一個svg文件,svg的完整路徑是 https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/examples/data/asset/geo/flight-seats.svg
點擊可以訪問。但顯示的是這樣的。

vue?echarts怎么實現(xiàn)航班選座

只顯示個飛機頭,這是因為svg太大的原因。要想看完整的,需要使用專門的svg查看軟件。
使用jquery獲取的svg,是svg文件的編碼。我們可以調試,打印一下svg的內容看一下。

vue?echarts怎么實現(xiàn)航班選座

這里可以看到是svg的具體內容。

注冊自定義地圖

echarts是可以搭配地圖來實現(xiàn)自定義的位置坐標布局渲染的。但不僅僅局限于百度,高德地圖。他還支持將一個符合地圖數(shù)據(jù)的svg注冊為一個地圖。
下面來看一下echarts的這個注冊自定義地圖的api。

registerMap

完整的解釋點擊此處查看

vue?echarts怎么實現(xiàn)航班選座

文檔的大致意思就是 你可以配置一個geoJson的東西,然后echarts可以解析內部的坐標,然后渲染,支持查找。
echarts中geo的相關文檔。
https://echarts.apache.org/zh/option.html#geo
該組件可以配置一些name,顏色,索引,能否被選中,交互后的顏色,hover效果。

這里稍微擴展一下GeoJSON這個東西,我也是第一次接觸。它是一種用于編碼各種地理數(shù)據(jù)結構的格式。
一種編程式的地圖,用一些特殊的屬性來表達地圖上的線,面,點,顏色。區(qū)域。
以GeoJSON支持以下幾何類型:Point,LineString, Polygon,MultiPoint,MultiLineString,和MultiPolygon。具有其他屬性的幾何對象是Feature對象。要素集包含在FeatureCollection對象中。
這里說的不對的,歡迎大佬拍磚,傳道解惑。
相關文檔
這里如果要展開講的話,以我現(xiàn)在的知識點,肯定講的不夠透徹,如果有感興趣的同學,可以在評論區(qū)留言,下篇文章可以給大家?guī)碛嘘Pgeojson更詳細的解析。

回歸主線,那么registerMap這個方法其實就是將svg轉化為一個標準的地圖坐標系。只不過轉化后地圖的定位不是根據(jù)經緯度,而是因為name。

 echarts.registerMap('flight-seats', { svg: svg });

好了上面這句代碼的含義就講解到這里。其實想想,每一個api的后面都牽扯到一大堆的知識。只要你細心,具有探索精神,那就一定會學的比別人多,學的好。知識是連貫的,不是單獨存在的。舉一反三,融會貫通方得學道。

geo組件的配置

echarts中有很多很多的組件如brush(區(qū)域選擇組件),parallel(平行坐標系),timeline,calendar(日歷坐標系),其中一個就是geo,地理坐標系組件。
地理坐標系組件用于地圖的繪制,支持地理坐標系上繪制散點圖,線集。
有關geo組件的所有的配置項都可以在此處查詢到詳細的解析。
此案例使用的就是該組件,那么下面來看下示例是如何配置的。

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)
}

以上是示例中有關geo組件的配置,下面讓我們仔細分析一下每一個配置項。

map

首先map指向的是我們剛剛注冊的一個自定義地圖'flight-seats'

map: 'flight-seats',

roam

roam關鍵字是用于配置是否開啟鼠標縮放和平移漫游。默認不開啟。如果只想要開啟縮放或者平移,可以設置成 ‘scale’ 或者 ‘move’。設置成 true 為都開啟

selectedMode

如字面意思selectedMode 字段是用于配置選中模式,表示是否支持多個選中,默認關閉,支持布爾值和字符串,字符串取值可選’single’表示單選,或者’multiple’表示多選。

layoutCenter, layoutSize

用于調整echarts的實例在dom容器中的初始位置。

tooltip

是否開啟tooltip效果,開啟后,鼠標放到座位上會有文本提示當前座位。

itemStyle

座位的默認樣式,配置顏色,字體

emphasis

高亮狀態(tài)下的多邊形和標簽樣式。

select

選中狀態(tài)下的多邊形和標簽樣式。

regions

在地圖中對特定的區(qū)域配置樣式。這里傳入的是一個數(shù)組,被格式化后的已被選的座位信息,
默認已經被選
每一項的數(shù)據(jù)格式是這樣的

{
    name: '26E',
    silent: true,
    itemStyle: {
        color: '#bf0e08'
    },
    emphasis: {
        itemStyle: {
            borderColor: '#aaa',
            borderWidth: 1
        }
    },
    select: {
        itemStyle: {
            color: '#bf0e08'
        }
    }
}

其中有一個屬性叫做 silent 它的作用是圖形是否不響應和觸發(fā)鼠標事件,默認為 false,即響應和觸發(fā)鼠標事件。

到這里該示例的echarts配置其實已經講解完了。這里的坐標系不是用經緯度,而是用每個座位的name來查找的。所以在svg中是可以找到對應的name的。name的值必須保證唯一。

vue?echarts怎么實現(xiàn)航班選座

該示例中除了核心的配置外,還有二個輔助函數(shù)。一起來看一下。

makeTakenRegions函數(shù)

這個函數(shù)就是將已經定義好的已選座位數(shù)據(jù),轉化成格式化的座位樣式數(shù)據(jù)。
下面是定義的默認已被選中的座位。

var takenSeatNames = ['26E', '26D', '26C', '25D', '23C', '21A', '20F'];

geoselectchanged

在這個示例的最后,有一個監(jiān)聽函數(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);
});

這幾行代碼是干嘛的那?
我們在點擊座位的時候,是有一個點擊事件,這里就是用于處理點擊后的交互的,然后獲取當前用戶選中的座位。
geoselectchanged 世界是 geo 中地圖區(qū)域切換選中狀態(tài)的事件。
用戶點擊選中會觸發(fā)該事件。 相關文檔

我們可以調試一下該函數(shù)看下,params的內容具體是什么

vue?echarts怎么實現(xiàn)航班選座

這里是用于處理點擊已經被人選中的座位,不進行選中,這段函數(shù)的使用場景是用于獲取當前用戶選中的座位列表,比如用戶選完座外要將座位信息發(fā)送給后臺保存。
主要功能就是判斷選的座位是不是已經被別人選中了,如果已被選中就剔除。

舉一反三

分析完代碼后,了解了每一個配置項的含義,那么我們趁熱打鐵做一個類似的聯(lián)系題,以達到舉一反三,融會貫通的目的。
需求,定義一個svg文件,有6個方塊,使用它做一個選座位的功能。
定義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" ></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>

效果圖

vue?echarts怎么實現(xiàn)航班選座

注意點

  • svg文件必須的每一個座位,可點擊區(qū)域必須要用g標簽包裹,且name屬性需

  • 定義到g標簽上定義geojson時,svg不能指向一個文本 結語

如果掌握了echarts的geo自定義地圖,那么你能做出非常多的示例
比如這樣的

vue?echarts怎么實現(xiàn)航班選座

這樣的

vue?echarts怎么實現(xiàn)航班選座

還有這樣的

vue?echarts怎么實現(xiàn)航班選座

只需要一個svg文件,再加幾個name,你就可以做成自己想要的地圖系圖表。

關于“vue echarts怎么實現(xiàn)航班選座”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“vue echarts怎么實現(xiàn)航班選座”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI