echarts实现伪3D地图、省会坐标涟漪、自动轮播、数据联动

效果图:


实现的效果:

  1. 伪3D效果地图
  2. 省会坐标展示标点,并带有涟漪效果
  3. 鼠标覆盖的区域,区域以及涟漪高亮
  4. 地图上的所有区域按照时间间隔轮播
  5. 点击、轮播时的区域,会带着所有其他表格的数据进行联动刷新,展示不同地区的统计数据

完整的JS代码:


let regions = [];
let orgRegions = [];// 初始状态颜色
var selectedAreaName = "";// 当前被选中/轮播地市
var mapName = 'NX';
var geoJson = mapData;

// 普通涟漪效果的标点
function convertNormalLianyiData(mapData) {
    var res = [];
    for (var i = 0; i < mapData.features.length; i++) {
        var prop = mapData.features[i].properties;
        //var geoCoord =  prop.center;// 标点位于地区省会
        var geoCoord = prop.centroid;// 标点位于地区正中心
        if (geoCoord && prop.name != selectedAreaName) {
            res.push({
                name: prop.name,
                // 横纵坐标后,拼接高度坐标,默认为10
                value: geoCoord.concat(100),
                adcode: prop.adcode,
            });
        }
    }
    return res;
}
// 选中区域涟漪效果的标点
function convertSelectedLianyiData(mapData) {
    var res = [];
    for (var i = 0; i < mapData.features.length; i++) {
        var prop = mapData.features[i].properties;
        //var geoCoord =  prop.center;// 标点位于地区省会
        var geoCoord = prop.centroid;// 标点位于地区正中心
        if (geoCoord && prop.name == selectedAreaName) {
            res.push({
                name: prop.name,
                // 横纵坐标后,拼接高度坐标,默认为10
                value: geoCoord.concat(100),
                adcode: prop.adcode,
            });
        }
    }
    return res;
}

for (i = 0; i < geoJson.features.length; i++) {
    let cityInfo = {
        name: geoJson.features[i].properties.name,
        adcode: geoJson.features[i].properties.adcode,
    }
    city.push(cityInfo);
}
for (i = 0; i < city.length; i++) {
    regions.push({
        name: city[i].name,
        adcode: city[i].adcode,
        itemStyle: {
            color: color[i % 10]
        },
    });
    orgRegions.push({
        name: city[i].name,
        adcode: city[i].adcode,
        itemStyle: {
            color: color[i % 10]
        },
    });
}

// 叠加图层构建立体效果
let addShadow = function (geo) {
    let max = 30;
    let upper = '#2768b6';
    let deeper = '#0e408a';
    for (let i = 0; i < max; i++) {
        geo.push({
            type: 'map',
            map: mapName,
            // 地图标签
            label: {
                show: false
            },
            layoutCenter: ['50%', '50%'],
            layoutSize: '80%',
            zlevel: -1 * i,
            itemStyle: {
                normal: {
                    color: 'rgba(39, 104 ,190, 1)',
                    borderColor: '#AEFBFF',
                    borderWidth: 1,
                    opacity: 0.8,
                    shadowColor: i < max / 2 ? upper : deeper,
                    shadowOffsetX: i * -1,
                    shadowOffsetY: i * 1.5,
                    shadowBlur: 1
                },
                emphasis: {
                    show: false,
                    color: "#fff",
                    // 地图区域被选中的颜色
                    areaColor: "rgba(0,254,233,0.6)",
                },
            },
            aspectScale: 1, //长宽比
            selectedMode: false, //是否允许选中多个区域
        });
    }
};
let geo = [
    {
        type: 'map',
        map: mapName,
        itemStyle: {
            normal: {
                areaColor: {
                    type: "linear",
                    x: 1200,
                    y: 0,
                    x2: 0,
                    y2: 0,
                    colorStops: [
                        {
                            offset: 0,
                            color: "rgba(3,27,78,0.75)", // 0% 处的颜色
                        },
                        {
                            offset: 1,
                            color: "rgba(58,149,253,0.75)", // 50% 处的颜色
                        },
                    ],
                    global: true, // 缺省为 false
                },
                borderColor: "#fff",
                borderWidth: 0.2,
            },
            emphasis: {
                show: false,
                color: "#fff",
                // 地图区域被选中的颜色
                areaColor: "rgba(0,254,233,0.6)",
            },
        },
        // 地图标签
        label: {
            show: false
        },
        layoutCenter: ['50%', '50%'],
        layoutSize: '80%',
        zlevel: 0,
        aspectScale: 1, //长宽比
        selectedMode: false, //是否允许选中多个区域
    }
];
addShadow(geo);

option = {
    tooltip: {
        show: true, // 提示框
        trigger: 'item',
        formatter: function (params) {
            return params.name;
        }
    },
    geo: geo,
    series: [
        {
            type: 'map',
            map: mapName,
            itemStyle: {
                normal: {
                    areaColor: {
                        type: "linear",
                        x: 1200,
                        y: 0,
                        x2: 0,
                        y2: 0,
                        colorStops: [
                            {
                                offset: 0,
                                color: "rgba(3,27,78,0.75)", // 0% 处的颜色
                            },
                            {
                                offset: 1,
                                color: "rgba(58,149,253,0.75)", // 50% 处的颜色
                            },
                        ],
                        global: true, // 缺省为 false
                    },
                    borderColor: "#fff",
                    borderWidth: 0.2,
                },
                emphasis: {
                    show: false,
                    color: "#fff",
                    // 地图区域被选中的颜色
                    areaColor: "rgba(0,254,233,0.6)",
                },
            },
            // 地图标签
            label: {
                show: false
            },
            zlevel: -1,
            aspectScale: 1, //长宽比
            selectedMode: false, //是否允许选中多个区域
            data: convertNormalLianyiData(mapData),
        },
        // 常规状态下的涟漪效果
        {
            // 动效散点公共配置项
            type: 'effectScatter',
            // 使用的坐标系
            coordinateSystem: 'geo',
            // 涟漪效果
            rippleEffect: {
                //涟漪特效
                color: '#f29130',
                period: 4, //动画时间,值越小速度越快
                brushType: 'stroke', //波纹绘制方式 stroke, fill
                scale: 10 //波纹圆环最大限制,值越大波纹越大
            },
            symbol: 'circle',
            symbolSize: 15,
            label: {
                normal: {
                    show: true,
                    position: 'bottom', //显示位置
                    offset: [5, 0], //偏移设置
                    formatter: function (params) {
                        //圆环显示文字
                        return params.data.name;
                    },
                    textStyle: {
                        fontSize: 15,
                        color: 'white',
                        borderWidth: 15
                        //borderColor: 'orange'
                    }
                },
                emphasis: {
                    show: true
                }
            },
            // 城市坐标样式
            itemStyle: {
                normal: {
                    color: {
                        type: 'linear',
                        x: 0,
                        y: 0,
                        x2: 0,
                        y2: 1,
                        colorStops: [
                            {
                                offset: 0,
                                color: '#fbc05d' // 0% 处的颜色
                            },
                            {
                                offset: 1,
                                color: '#ee8125' // 100% 处的颜色
                            }
                        ],
                        global: false // 缺省为 false
                    }
                }
            },
            data: convertNormalLianyiData(mapData)
        },
        // 选中状态下的涟漪效果
        {
            // 动效散点公共配置项
            type: 'effectScatter',
            // 使用的坐标系
            coordinateSystem: 'geo',
            // 涟漪效果
            rippleEffect: {
                //涟漪特效
                color: '#1a6198',
                period: 4, //动画时间,值越小速度越快
                brushType: 'fill', //波纹绘制方式 stroke, fill
                scale: 15 //波纹圆环最大限制,值越大波纹越大
            },
            symbol: 'circle',
            symbolSize: 15,
            label: {
                normal: {
                    show: true,
                    position: 'bottom', //显示位置
                    offset: [5, 0], //偏移设置
                    formatter: function (params) {
                        //圆环显示文字
                        return params.data.name;
                    },
                    textStyle: {
                        fontSize: 15,
                        color: 'white',
                        borderWidth: 15
                        //borderColor: 'orange'
                    }
                },
                emphasis: {
                    show: true
                }
            },
            // 城市坐标样式
            itemStyle: {
                normal: {
                    color: {
                        type: 'linear',
                        x: 0,
                        y: 0,
                        x2: 0,
                        y2: 1,
                        colorStops: [
                            {
                                offset: 0,
                                color: '#fbc05d' // 0% 处的颜色
                            },
                            {
                                offset: 1,
                                color: '#ee8125' // 100% 处的颜色
                            }
                        ],
                        global: false // 缺省为 false
                    }
                }
            },
            data: convertSelectedLianyiData(mapData)
        }
    ]
};

function buildOption(context, eChartData, chartOption, echarts) {
    debugger
    echarts.registerMap(mapName, geoJson);
    startLunbo(context, true);
    // 初始化时立即广播宁夏
    if (context.vueContext) {
        let selectedCode = '640000';
        let msg = {
            //P_ND: "20220101",
            CZQH: selectedCode
        }
        context.vueContext.emit('sendMsg', msg)
    }
    chartOption = option;
    return chartOption;
};
var myChart;
var interval;
function onRender(context, eChartData, container, obj, instance) {
    debugger
    myChart = instance;

    // 鼠标移入轮播结束,移出轮播开始
    myChart.off('mouseover')
    myChart.on("mouseover", (params) => {
        clearInterval(interval);
        clearAllStyle();
        // 记录被选中的/轮播的区域
        selectedAreaName = params.name;
        resetScatter();
        setSelectedStyle();
        myChart.setOption(option);
    });
    myChart.off('mouseout')
    myChart.on("mouseout", () => {
        debugger

        selectedAreaName = "";
        resetScatter();

        //轮播函数开始
        clearInterval(interval);
        clearAllStyle();
        startLunbo(context);
        // 记录被选中的/轮播的区域



        myChart.setOption(option);


    });
    myChart.off('click')
    myChart.on("click", function (params) {
        // debugger

        // 点击区域的区划code
        let changeCode = params.region.adcode;
        if (changeCode && context.vueContext) {
            let msg = {
                //P_ND: "20220101",
                CZQH: changeCode
            }
            context.vueContext.emit('sendMsg', msg)
        }

        // 仪表盘的Id
        // let dashboardGuid = window['nvwa-dataanalyze-dashboard_0000018A39DD52A99D9A26069BCED0DE'].dashboardGuid;

        console.log('点击获取Params', params);
    });
};
/**
 * 
 * @param context 图表上下文参数
 * @param init 是否为第一加载:true:立即开启选中,false:时间间隔后开启选中
 */
function startLunbo(context, init = false) {
    // debugger
    // 保留当前选中地市的下标和颜色信息
    const lastSelectedArea = {
        index: 0,
        color: 'rgba(39, 104 ,190, 1)',
    };
    let _context = context;
    // 开始轮播,-1表示展示省级信息
    let mapIndex = -1;
    interval = setInterval(() => {
        if (mapIndex == -1) {
            clearAllStyle();
            if (!init) {
                // 广播宁夏
                if (_context.vueContext) {
                    let selectedCode = '640000';
                    let msg = {
                        //P_ND: "20220101",
                        CZQH: selectedCode
                    }
                    _context.vueContext.emit('sendMsg', msg)
                }
            }
            mapIndex++;

        } else {
            regions[lastSelectedArea.index].itemStyle.color = lastSelectedArea.color;
            let finishLunbo = (mapIndex == mapData.features.length);
            mapIndex = mapIndex % mapData.features.length;
            lastSelectedArea.index = mapIndex;
            lastSelectedArea.color = regions[lastSelectedArea.index].itemStyle.color;
            // 当前轮播被选中的地区颜色
            regions[mapIndex].itemStyle.color = '#ffffff';
            // regions[mapIndex].itemStyle.color = '#e2cd00';
            // 记录被选中的/轮播的区域
            selectedAreaName = regions[mapIndex].name;

            // 广播当前轮播的财政区划
            if (_context.vueContext) {
                let selectedCode = regions[mapIndex].adcode;
                let msg = {
                    //P_ND: "20220101",
                    CZQH: selectedCode
                }
                _context.vueContext.emit('sendMsg', msg)
            }
            if (finishLunbo == true) {
                // 全部轮询完成,从省级重新开始,下标恢复为-1
                mapIndex = -1;
            } else {
                mapIndex++;
            }

            for (let i = 0; i < option.geo.length; i++) {
                const geoItem = option.geo[i];
                geoItem.regions = regions;
            }

            resetScatter();
        }

        myChart.setOption(option);
    }, 15000);// 此处修改轮播的频率(单位毫秒)
}
// 清除所有地区被选中样式
function clearAllStyle() {
    // debugger
    for (let i = 0; i < option.geo.length; i++) {
        const geoItem = option.geo[i];
        geoItem.regions = orgRegions;
    }
    regions = [];
    for (i = 0; i < city.length; i++) {
        regions.push({
            name: city[i].name,
            adcode: city[i].adcode,
            itemStyle: {
                color: color[i % 10]
            },

        });
    }
    myChart.setOption(option);
}
// 重置涟漪效果
function resetScatter() {
    option.series[1].data = convertNormalLianyiData(mapData);
    option.series[2].data = convertSelectedLianyiData(mapData);
}
// 设置被选中地区样式
function setSelectedStyle() {
    // debugger
    // 被选中的地区颜色
    let selectedStyle = {
        color: "rgba(0,254,233,0.6)",
    }
    for (let i = 0; i < regions.length; i++) {
        const selectedItem = regions[i];
        if (selectedItem.name == selectedAreaName) {
            selectedItem.itemStyle = selectedStyle;
            break;
        }
    }
    for (let i = 0; i < option.geo.length; i++) {
        const geoItem = option.geo[i];
        geoItem.regions = regions;
    }
}

你可能感兴趣的:(echarts,前端,javascript)