vue2 使用echarts實現地圖點選進入下一層級+點選空白處回退

sunshine233發表於2024-05-16

先驗知識:

vue2中echarts的安裝和顯示中國地圖:https://www.cnblogs.com/sunshine233/p/16140522.html

滑鼠事件: https://echarts.apache.org/zh/api.html#echartsInstance.on
echarts.getMap():https://echarts.apache.org/zh/api.html#echarts.getMap
監聽“空白處”的事件:https://echarts.apache.org/handbook/zh/concepts/event/#%E7%9B%91%E5%90%AC%E2%80%9C%E7%A9%BA%E7%99%BD%E5%A4%84%E2%80%9D%E7%9A%84%E4%BA%8B%E4%BB%B6

npm 安裝 echarts4.9(全域性引入不支援5.0)

執行效果(只做了河南的點選和後退):

實現思路:

1. 引入地圖並顯示

// 1. 基於準備好的dom,初始化echarts例項
this.myChart = this.$echarts.init(this.$refs.myChart);
// 2. 引入要顯示的地圖 json 檔案(json檔案可以是echart自帶的,也可以是自己下載的)
this.mapJson = require("echarts/map/json/china.json");
// 3. 註冊可用的地圖 registerMap("自定義的名字,要和option中map:''對應",註冊的地圖指向的json檔案)
this.$echarts.registerMap("mapJson", this.mapJson);
// 4. 指定圖表的配置項和資料
this.option = {
    geo: {
        type: "map",
        map: "mapJson",//這裡的資料會變,"這裡是引入的儲存json檔案的變數名"
        label: {
            normal: {
                color: "#000000",
                show: true, //顯示省份名稱
            },
        },
    },
    series: [
        {
            name: "在地圖中顯示散點圖",
            type: "scatter",
            coordinateSystem: "geo", //設定座標系為 geo
            data: [
                //這裡放標註點的座標[{name: "北京",value: [116.46, 39.92]}]
            ],
        },
    ],
};
// 5. 設定圖表例項的配置項以及資料,萬能介面,所有引數和資料的修改都可以透過 setOption 完成,ECharts 會合並新的引數和資料,然後重新整理圖表。
this.myChart.setOption(this.option);

2. 地圖顯示的是“中國”還是“省”還是“市區”主要就是靠引入的json檔案區分,
也就是 this.mapJson = require("echarts/map/json/china.json"); 的mapJson,
然後 this.$echarts.registerMap("mapJson", this.mapJson); 註冊一下修改後的檔案,
this.myChart.setOption(this.option); 地圖即可重新顯示新的地區。

3. 怎麼確定 this.mapJson 引入的哪個檔案呢? 新增地圖的監聽事件後,可以獲取一個code值,用這個code值判斷應該引入哪個省市的檔案。點選空白處回退同理,只需要確定應該回退層級的code值,就可以由此判斷應該回退到哪個層級頁面了。

全部程式碼如下:

<template>
    <div id="app">
        <div id="myChart" ref="myChart"></div>
        <el-button type="success" @click="cancelEchartsEvent">點選取消on事件</el-button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            myChart: null,
            mapJson: null,
            option: {},
            curArea: {
                code: -1,
                name: ""
            },
        };
    },
    mounted() {
        this.initEchartParams();
        this.addMouseClick();//開啟 echarts 事件監聽
    },
    beforeDestroy() {
        this.cancelEchartsEvent();
    },
    methods: {
        cancelEchartsEvent() {
            console.log("頁面解除安裝前,取消 echarts 的事件監聽");
            this.myChart.off("click");
        },
        initEchartParams() {
            // 1. 基於準備好的dom,初始化echarts例項
            this.myChart = this.$echarts.init(this.$refs.myChart);
            // 2. 引入要顯示的地圖 json 檔案(json檔案可以是echart自帶的,也可以是自己下載的)
            this.mapJson = require("echarts/map/json/china.json");
            // 3. 註冊可用的地圖 registerMap("自定義的名字,要和option中map:''對應",註冊的地圖指向的json檔案)
            this.$echarts.registerMap("mapJson", this.mapJson);
            // 4. 指定圖表的配置項和資料
            this.option = {
                geo: {
                    type: "map",
                    map: "mapJson",//這裡的資料會變,"這裡是引入的儲存json檔案的變數名"
                    label: {
                        normal: {
                            color: "#000000",
                            show: true, //顯示省份名稱
                        },
                    },
                },
                series: [
                    {
                        name: "在地圖中顯示散點圖",
                        type: "scatter",
                        coordinateSystem: "geo", //設定座標系為 geo
                        data: [
                            //這裡放標註點的座標[{name: "北京",value: [116.46, 39.92]}]
                            { name: "鄭州", value: [113.665412, 34.757975] },
                            { name: "北京", value: [116.41995, 40.18994] },
                            { name: "天津", value: [117.205126, 39.034933] },
                            { name: "昆明", value: [102.81844, 24.906231] },
                            { name: "廣州", value: [113.26453, 23.155008] },
                        ],
                    },
                ],
            };
            // 5. 設定圖表例項的配置項以及資料,萬能介面,所有引數和資料的修改都可以透過 setOption 完成,ECharts 會合並新的引數和資料,然後重新整理圖表。
            this.myChart.setOption(this.option);
        },
        addMouseClick() {
            this.addClickInMap();
            this.addClickInBlank();
        },
        // 點選了地圖非空白處
        addClickInMap() {
            // echarts.getMap 獲取已註冊的地圖
            const maps = this.$echarts.getMap("mapJson").geoJson.features;
            console.log({ maps });

            this.myChart.on("click", (res) => {
                let clickArea = maps.find(map => map.properties.name == res.name);
                // console.log({ clickArea });

                if (!clickArea) {
                    // 如果點的不是地圖,而是地圖上的散點,什麼也不做
                    return;
                }
                this.curArea.code = clickArea.id;
                this.curArea.name = res.name;
                console.log("當前點選的是: " + this.curArea.name + " this.curArea.code:" + this.curArea.code);

                // 修改 mapJson 的數值
                this.configGeoMap(this.curArea.code);
            });
        },
        // 點選了地圖空白處
        addClickInBlank() {
            this.myChart.getZr().on('click', (event) => {
                // !event.target 不存在 證明點選的地方是地圖空白處
                if (!event.target) {
                    let preCode = -1;
                    const curAreaCode = this.curArea.code;
                    console.log("回退前地區code ", curAreaCode);

                    if (curAreaCode == "100000") {//當前在中國,不回退
                        console.log("當前地圖已經是 china, 不可回退!");
                        return;
                    } else if (curAreaCode % 10000 == 0) {//說明當前在省,回退到 china
                        preCode = 100000;
                    } else if (curAreaCode % 100 == 0) {////說明當前在 鄭州市,回退到 河南省
                        preCode = curAreaCode - curAreaCode % 10000;
                    } else {
                        preCode = curAreaCode - curAreaCode % 100; //回退到city
                    }
                    // 回退後,當前顯示地圖的code就是preCode
                    this.curArea.code = preCode;
                    console.log('點選了空白處,回退後地區 code:' + preCode);

                    this.configGeoMap(preCode);
                }
            });
        },
        // 修改 mapJson 的數值
        configGeoMap(code) {
            // 這裡要根據code值找到對應的json檔案,如果是從伺服器獲取,也是找到對應的json檔案即可
            // 這裡我用的是 用npm安裝echarts@4.9.0 時自動下載的檔案 
            if (code == "100000") {
                this.mapJson = require("echarts/map/json/china.json");
            } else if (code == "410000") {
                this.mapJson = require("echarts/map/json/province/henan.json");
            } else {
                console.log('除了河南外,其它地區暫時不能跳轉');
            }

            this.$echarts.registerMap("mapJson", this.mapJson);
            this.myChart.setOption(this.option);
        }
    }
}
</script>
<style scoped>
#myChart {
    width: 100%;
    height: 500px;
    background-color: #f1f3f4;
}

button {
    margin: 20px;
}
</style>

相關文章