echarts map migration and map drill-down

echarts map migration and map drill-down

1. Migration

Map migration

1. Introduce Chinese map data and echarts

const china = require("./echarts-mapJson-master/china.json")
import * as echarts from 'echarts'

2. Data preparation

//Point data If you need to hover or click to obtain data, you can add additional parameters.
// For example, { value: [118.8062, 31.9208], code:'440100', itemStyle: { color: '#4ab2e5' }, the code can be obtained when hovering or clicking;
//The last point in the array is the end point pointed by the line, or it can be omitted
let pointData = [
                    {<!-- --> value: [118.8062, 31.9208], itemStyle: {<!-- --> color: '#4ab2e5' } }
                    , {<!-- --> value: [127.9688, 45.368], itemStyle: {<!-- --> color: '#4fb6d2' } }
                    , {<!-- --> value: [110.3467, 41.4899], itemStyle: {<!-- --> color: '#52b9c7' } }
                    , {<!-- --> value: [125.8154, 44.2584], itemStyle: {<!-- --> color: '#5abead' } }
                    , {<!-- --> value: [116.4551, 40.2539], itemStyle: {<!-- --> color: '#f34e2b' } }
                    , {<!-- --> value: [123.1238, 42.1216], keysValue: 8, itemStyle: {<!-- --> color: '#f56321' } }
                    , {<!-- --> value: [114.4995, 38.1006], itemStyle: {<!-- --> color: '#f56f1c' } }
                    , {<!-- --> value: [117.4219, 39.4189], itemStyle: {<!-- --> color: '#f58414' } }
                    , {<!-- --> value: [112.3352, 37.9413], itemStyle: {<!-- --> color: '#f58f0e' } }
                    , {<!-- --> value: [109.1162, 34.2004], itemStyle: {<!-- --> color: '#f5a305' } }
                    , {<!-- --> value: [103.5901, 36.3043], itemStyle: {<!-- --> color: '#e7ab0b' } }
                    , {<!-- --> value: [106.3586, 38.1775], itemStyle: {<!-- --> color: '#dfae10' } }
                    , {<!-- --> value: [101.4038, 36.8207], itemStyle: {<!-- --> color: '#d5b314' } }
                    , {<!-- --> value: [103.9526, 30.7617], itemStyle: {<!-- --> color: '#c1bb1f' } }
                    , {<!-- --> value: [108.384366, 30.439702], itemStyle: {<!-- --> color: '#b9be23' } }
                    , {<!-- --> value: [113.0823, 28.2568], itemStyle: {<!-- --> color: '#a6c62c' } }
                    , {<!-- --> value: [102.9199, 25.46639], itemStyle: {<!-- --> color: '#96cc34' } }
                    , {<!-- --> value: [113.335367, 23.13559]}
                ],
// Line data can also add additional parameters. When clicking, the parameters can be obtained when the type is lines.
let linesData = [
                   {<!-- --> coords: [ [118.8062, 31.9208],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#4ab2e5' } }
                    , {<!-- --> coords: [ [127.9688, 45.368],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#4fb6d2' } }
                    , {<!-- --> coords: [ [110.3467, 41.4899],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#52b9c7' } }
                    , {<!-- --> coords: [ [125.8154, 44.2584],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#5abead' } }
                    , {<!-- --> coords: [ [116.4551, 40.2539],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#f34e2b' } }
                    , {<!-- --> coords: [ [123.1238, 42.1216],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#f56321' } }
                    , {<!-- --> coords: [ [114.4995, 38.1006],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#f56f1c' } }
                    , {<!-- --> coords: [ [117.4219, 39.4189],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#f58414' } }
                    , {<!-- --> coords: [ [112.3352, 37.9413],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#f58f0e' } }
                    , {<!-- --> coords: [ [109.1162, 34.2004],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#f5a305' } }
                    , {<!-- --> coords: [ [103.5901, 36.3043],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#e7ab0b' } }
                    , {<!-- --> coords: [ [106.3586, 38.1775],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#dfae10' } }
                    , {<!-- --> coords: [ [101.4038, 36.8207],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#d5b314' } }
                    , {<!-- --> coords: [ [103.9526, 30.7617],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#c1bb1f' } }
                    , {<!-- --> coords: [ [108.384366, 30.439702],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#b9be23' } }
                    , {<!-- --> coords: [ [113.0823, 28.2568],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#a6c62c' } }
                    , {<!-- --> coords: [ [102.9199, 25.46639],[113.335367, 23.13559]], lineStyle: {<!-- --> color: '#96cc34' } }
]

3. Get options

getOptions(name, id, seriesData, pointsData, linesData) {<!-- -->
                let _this = this;
                return {<!-- -->
                    backgroundColor: '#0F1C3C',
                    toolbox: {<!-- --> // Back button
                        right: '5%',
                        top: '15%',
                        feature: {<!-- -->
                            myBack: {<!-- -->
                                show: false,
                                title: 'return',
                                icon: 'path://M473.2 276.9v-133c-4-18.4-11.7-27-20.2-30.3-17.2-6.7-37.8 8.5-37.8 8.5L95.9 395.4c-70.1 48.4-4.8 84.7-4.8 84.7L405.5 751c62.9 46 67.7-24.2 67.7-24.2V603.4c319.3-99.2 449.9 297.5 449.9 297.5 12.1 21.8 19.3 0 19.3 0 123.4-595-469.2 -624-469.2-624z m0 0',
                                iconStyle: {<!-- -->
                                    color: "#1aaef6",
                                    borderColor: "#1aaef6"
                                },
                                onclick: async function () {<!-- -->
                                    const seriesData = await _this.handleMap('china', chinaJson);
                                    const opt = await _this.getOptions('china', '', seriesData, _this.pointsData, _this.linesData)
                                    await _this.myChart.setOption(opt, true);
                                }
                            }
                        }
                    },
                    tooltip: {<!-- -->
                        trigger: 'item',
                        backgroundColor: '#ffff',
                        borderColor: '#FFFFCC',
                        showDelay: 0,
                        hideDelay: 0,
                        enterable: true,
                        transitionDuration: 0,
                        extraCssText: 'z-index:100',
                        formatter: function (params, ticket, callback) {<!-- -->
                            let name = params.name
                            //Expand the content to be displayed according to the business
                            // Custom data params.data
                            let res = "<div>" + name + '</div>'
                            return res;
                        },
                    },
                    geo: {<!-- -->
                        map: 'china',// Named after the current map name when drilling down
                        show: true,
                        roam: true,
                        zoom: 1.2,
                        label: {<!-- -->
                            show: true,
                            color: '#1DE9B6'
                        },
                        layoutSize: '100%',
                        itemStyle: {<!-- -->
                            areaColor: {<!-- -->
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    {<!-- -->
                                        offset: 0,
                                        color: '#073684' // Color at 0%
                                    },
                                    {<!-- -->
                                        offset: 1,
                                        color: '#061E3D' // Color at 100%
                                    }
                                ]
                            },
                            borderColor: '#2863ad',
                            borderWidth: 1,
                            shadowColor: 'rgba(10,76,139,1)',
                            shadowOffsetY: 0,
                            shadowBlur: 60
                        },
                        emphasis: {<!-- -->
                            areaColor: '#2AB8FF',
                            borderWidth: 0,
                            color: 'green',
                            label: {<!-- -->
                                show: true,
                                areaColor: {<!-- -->
                                    x: 0,
                                    y: 0,
                                    x2: 0,
                                    y2: 1,
                                    colorStops: [
                                        {<!-- -->
                                            offset: 0,
                                            color: '#073684' // Color at 0%
                                        },
                                        {<!-- -->
                                            offset: 1,
                                            color: '#061E3D' // Color at 100%
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    series: [
                        {<!-- -->
                            type: 'map',
                            map: 'china',// Not needed when there is data
                            roam: true,
                            geoIndex: 0,
                            aspectScale: 0.85, //aspect ratio
                            show: true,
                            textStyle: {<!-- -->
                                color: '#1DE9B6'
                            },
                            emphasis: {<!-- -->
                                textStyle: {<!-- -->
                                    color: 'rgb(183,185,14)'
                                },
                                itemStyle: {<!-- -->
                                    areaColor: 'rgb(46,229,206)',
                                    borderWidth: 0.1
                                }
                            },
                            itemStyle: {<!-- -->
                                borderColor: 'rgb(147, 235, 248)',
                                borderWidth: 1,
                                areaColor: {<!-- -->
                                    type: 'radial',
                                    x: 0.5,
                                    y: 0.5,
                                    r: 0.8,
                                    colorStops: [{<!-- -->
                                        offset: 0,
                                        color: '#09132c' // Color at 0%
                                    }, {<!-- -->
                                        offset: 1,
                                        color: '#274d68' // Color at 100%
                                    }],
                                    globalCoord: true //default is false
                                },
                            },
                            // data:[{name:'',value:[longitude, latitude]}]
                        },
                        {<!-- -->
                            type: 'effectScatter', // animated scatter points
                            coordinateSystem: 'geo',
                            showEffectOn: 'render',
                            zlevel: 1,
                            rippleEffect: {<!-- --> // Ripple effects
                                period: 4, // animation period, seconds
                                scale: 5, // Maximum scaling ratio of ripples in animation
                                brushType: 'stroke',// ['fill','stroke'] Ripple waves or coils
                            },
                            emphasis: {<!-- --> scale: 1.5 },
                            label: {<!-- -->
                                formatter: '{b}',
                                position: 'right',
                                offset: [15, 0],
                                color: '#1DE9B6',
                                show: true
                            },
                            itemStyle: {<!-- -->
                                color: '#1DE9B6',
                                shadowBlur: 10,
                                shadowColor: '#333'
                            },
                            symbolSize: function (val) {<!-- --> // point size
                                return 12
                            },
                            data: pointsData
                        }, //Animation effect of map lines
                        {<!-- -->
                            type: 'lines',
                            zlevel: 2,
                            effect: {<!-- -->
                                show: true,
                                period: 4, // The arrow points to the speed. The smaller the value, the faster the speed.
                                trailLength: 0.4, // The larger the special effect trail length [0,1] value is, the longer and heavier the trail will be.
                                symbol: 'arrow', // arrow icon
                                symbolSize: 7, // icon size
                            },
                            lineStyle: {<!-- -->
                                color: '#1DE9B6',
                                width: 1, // line width
                                opacity: 0.1, // Trail line transparency
                                curveness: .3 // Trail line straightness
                            },
                            data: linesData
                        }
                    ]
                };
            },

4. Draw pictures

// Register China map first, then draw the map
async loadData(){<!-- -->
 let _this = this;
 this.myChart = echarts.getInstanceByDom(this.$refs.baseEcharts);
 if (!this.myChart) {<!-- -->
    this.myChart = await echarts.init(this.$refs.baseEcharts);
 }
 //National map
 echarts.registerMap('china', chinaJson);
 await _this.myChart.setOption(option);
}

2. Drilling down

1. Draw a map of China
2. Obtain the provincial ID or municipal code from the map click event (see what is displayed at the next level)
3. Get the corresponding provincial map data according to the provincial ID and register the map
4. Get the corresponding option, then setOptions, return to the China map and draw the China map again (draw whichever map is currently displayed)
5. Due to scaling or other reasons, the map is not at the center of the container after switching the map. setOptions(option,true), true means redrawing the map

 /**
             * Get the current configuration items
             * @param{string} name current map
             * @param{string} id current map id
             * @param{array} seriesData group[{name,value}]
             * @param{array} pointsData points
             * @param{array} linesData lines
             * */
            async getOptions(name, id, seriesData, pointsData, linesData) {<!-- -->
            let _this = this;
            //Reference migration diagram
            return{<!-- -->}
            },
/**
             * @description Drawing
             * @param{string} name drawing
             * @param{object} json current map data
             * @return{array} [{name:'',value:[]}]
             * */
            async handleMap(name, json) {<!-- -->
                let obj = {<!-- -->}, map = [];
                // 1. Initialize the national map
                // 2. Set click event - click to drill down, double click to return
                // 3. Click to register and click on the province map-setOption to draw
                // 4. Double-click to return and redraw the national map
                if (name !== 'china') {<!-- --> // Register map
                    echarts.registerMap(name, json);
                }
                let mapFeatures = echarts.getMap(name) ? echarts.getMap(name).geoJson.features : [];
                mapFeatures.forEach(function (v) {<!-- -->
                    obj = {<!-- --> name: v.properties.name, value: v.properties.cp }
                    if (name === 'china') {<!-- -->
                    //The first two values are the latitude and longitude, here we put the upgrade ID in [2]
                    // Clicking on the map itself can only put the value into value. If you click on the drawn point or drawn line, you can set custom parameters in the data array.
                        obj.value.push(v.properties.id)
                    }
                    map.push(obj)
                });
                return map
            },
            /**
             * @description instantiation
             * */
            async loadData() {<!-- -->
                let _this = this;
                this.myChart = echarts.getInstanceByDom(this.$refs.baseEcharts);
                if (!this.myChart) {<!-- -->
                    this.myChart = await echarts.init(this.$refs.baseEcharts);
                }
                //National map
                echarts.registerMap('china', chinaJson);
                //Each map point, the first data of type: 'map' in the series
                const seriesData = await this.handleMap('china', chinaJson);
                // options
                const opt = await this.getOptions('china', '', seriesData, this.pointsData, this.linesData)
                // Painting
                await this.myChart.setOption(opt);
                // Monitor window changes
                // window.addEventListener("resize", this.resize); // myChart.resize();
                this.myChart.on('click', async function (params) {<!-- -->
                    // Project click-drill down params.data.value[2] is the set provincial id
                    // There is only one level of drill-down here, and the city code is required for both levels.
                    if (params.data & amp; & amp; params.data.value & amp; & amp; params.data.value[2]) {<!-- -->
                        const json = require('./echarts-mapJson-master/geometryProvince/' + params.data.value[2] + '.json')
                        if (!json) {<!-- -->
                            return;
                        }
                        //Data for each block of the map
                        const seriesData = await _this.handleMap(params.data.value[2], json);
                        // options
                        const opt = await _this.getOptions(params.data.value[2], params.data.value[2], seriesData, _this.pointsData, _this.linesData)
                        //Return key display
                        opt.toolbox.feature.myBack.show = true
                        // Painting
                        await _this.myChart.setOption(opt, true);

                    }
                })
                // Double click to return
                this.myChart.on('dblclick', async function (params) {<!-- -->
                    if (params.type === 'dblclick' & amp; & amp; params.data & amp; & amp; (!params.data.value || !params.data.value[2])) {< !-- -->
                        const seriesData = await _this.handleMap('china', chinaJson);
                        const opt = await _this.getOptions('china', '', seriesData, _this.pointsData, _this.linesData)
                        await _this.myChart.setOption(opt, true);
                    }
                })
            },

refer to:
1. echarts Demo set https://www.isqqw.com/
2. https://datav.aliyun.com/portal/school/atlas/area_selector# & amp;lat=31.027163647290617 & amp;lng=106.75386074913891 & amp;zoom=4.5
3. Map resources https://gitee.com/niceguy802/map-resources.git