Echarts的地图实现拖拽缩放同步功能(解决多层geo缩放、拖动卡顿问题)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Echarts伪3D地图 Echarts的地图实现拖拽缩放同步功能(解决多层geo缩放、拖动卡顿问题)</title>
  <script src="./js/echarts.min4.8.js"></script>
  <script src="./all.js"></script>
  <!-- <script src="./map-shandong.js"></script> -->
  <!-- <script src="./map-shanxi.js"></script> -->
  <style>
    * {
      margin: 0;
    }

    .map-panel {
      position: relative;
      box-sizing: border-box;
      width: 100vw;
      height: 100vh;
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-template-rows: 55px auto;
      grid-template-areas:
        "header header"
        "left right";
      gap: 10px;
      padding: 10px;
    }

    .title {
      grid-area: header;
      display: grid;
      justify-items: center;
      align-items: center;
      font-size: 28px;
      font-weight: bold;
    }

    .shandong-map {
      grid-area: left;
      border: 1px solid #007acc;
      border-radius: 5px;
    }

    .shanxi-map {
      grid-area: right;
      border: 1px solid #007acc;
      border-radius: 5px;
    }
  </style>
</head>

<body>
  <div class="map-panel">
    Echarts的地图实现拖拽缩放同步功能(解决多层geo缩放、拖动卡顿问题)
    <div id="shandong-map" class="shandong-map"></div>
    <div id="shanxi-map" class="shanxi-map"></div>
  </div>
</body>
<script>
  window.onload = () => {
    initMap("mapjson", mapjson, "shandong-map");
    initMap("mapjson", mapjson, "shanxi-map");
  };
  var mapData = [
    {
      "bidProjectName": "111呼和浩特xx",
      "createTime": "2023-09-07",
      "creatorName": "xx",
      "longitude": "111.75340",
      "latitude": "40.85991",
      "orgName": "公司",
      "orgNo": "010054",
      "orgShortName": "呼和浩特xx",
      "projectName": "呼和浩特xx----",
      "projectNo": "1001",
      "retestLevel": "2",
      "retestLevelText": "2级",
      "riskNo": "0122",
      "riskStatus": "DKG",
      "riskStatusText": "待开工",
      "singleProjectName": "呼和浩特xx",
      "workContent": "大型电器施工",
      "bidId": "0333985f6c7c4c4aa447462a7d56d7bd",
      "bidNo": "10010202",
      value: [40.85991, 111.75340],
    }
  ];
  var outdata = [];
  var areacolor = '#325eb4';
  var bodercolor = '#29a0f6';
  var disareacolor = '#2e43a8';
  var emareacolor = '#029cd4';
  var regions = ['呼伦贝尔市', '兴安盟', '通辽市', '赤峰市'].map(item => {
    return {
      name: item,
      label: {
        normal: {
          show: false,
          color: '#fff',
          fontSize: 16,
        },
        emphasis: {
          show: false,
          color: '#fff',
          fontSize: 16,
        },
      },
      itemStyle: {
        normal: {
          shadowColor: 'rgba(0,0,0,0.5)',
          shadowBlur: 0,
          areaColor: disareacolor,
          color: disareacolor,
        },
        emphasis: {
          shadowColor: 'rgba(0,0,0,0.5)',
          shadowBlur: 0,
          areaColor: disareacolor,
          color: disareacolor,
        },
      },
    }
  });
  var scatterData = [
    {
      "bidProjectName": "111呼和浩特xx",
      "createTime": "2023-09-07",
      "creatorName": "xx",
      "longitude": "111.75340",
      "latitude": "40.85991",
      "orgName": "公司",
      "orgNo": "010054",
      "orgShortName": "呼和浩特xx",
      "projectName": "呼和浩特xx----",
      "projectNo": "1001",
      "retestLevel": "2",
      "retestLevelText": "2级",
      "riskNo": "0122",
      "riskStatus": "DKG",
      "riskStatusText": "待开工",
      "singleProjectName": "呼和浩特xx",
      "workContent": "大型电器施工",
      "bidId": "0333985f6c7c4c4aa447462a7d56d7bd",
      "bidNo": "10010202",
      value: [40.85991, 111.75340],
    }
  ].map(item => {
    item.value = [item.longitude, item.latitude, 50]
    return item
  })
  function initMap(mapName, mapJsonData, domId) {
    echarts.registerMap(mapName, mapJsonData);
    let option = {
      tooltip: {
        show: false,
      },
      geo: [
        {
          show: true,
          map: mapName,
          zoom: 1,
          roam: true,
          animationDurationUpdate: 0,//实现缩放、拖动同步且不卡顿
          regions: [],
          zlevel: 98,
          aspectScale: 0.85,
          layoutCenter: ["50%", "50%"],
          layoutSize: "90%",
          itemStyle: {
            areaColor: "transparent",
          },
          label: {
            show: true,
            // position: 'insideBottom',
            alignText: "center",

            color: "#fff", //文字颜色
            fontSize: 14, //文字大小
            // padding: [5, 10],
            // alignText: "center",
            // lineHeight: 24,
            // backgroundColor: "rgba(0,0,0,0.32)", //透明度0清空文字背景
            // borderWidth: 1.5, //分界线宽度
            // borderRadius: 5,
            // borderColor: "#06b2f7", //分界线颜色
          },
          textStyle: {
            color: '#3899FF' // 值域文字颜色
          },
          emphasis: {
            label: {
              show: true, //鼠标经过是否显示高亮
              textStyle: {
                color: "#fff", //高亮文字颜色
              },
            },
            itemStyle: {
              // areaColor: "#074a9a", //地图颜色
              // areaColor: "#ccc", //地图颜色
              //   color: "#ccc", //地图高亮颜色
            },
          },
          itemStyle: {
            normal: {
              // shadowColor: 'rgba(0,0,0,0.5)',
              // shadowBlur: 30,
              areaColor: areacolor,
              borderWidth: 1, // (地图板块间的分隔线)图形描边的宽度。加上描边后可以更清晰的区分每个区域 [ default: 0 ]
              borderColor: bodercolor, // 图形描边的颜色。[ default: #333 ]
            },
            emphasis: {
              // shadowColor: 'rgba(0,0,0,0.5)',
              // shadowBlur: 30,
              areaColor: emareacolor,
            },
          },
          regions: regions,
        },
        {
          show: true,
          map: mapName,
          zoom: 1,
          roam: 'false',
          animationDurationUpdate: 0,//实现缩放、拖动同步且不卡顿
          zlevel: 4,
          layoutCenter: ["50.5%", "50.5%"],
          layoutSize: "90%",
          aspectScale: 0.85,
          itemStyle: {
            borderWidth: 1,
            borderColor: "rgba(22, 186, 212,0.8)",
            shadowColor: "rgba(80, 183, 140,0.5)",
            shadowOffsetY: 5,
            shadowBlur: 15,
            areaColor: "rgba(5,21,35,0.1)",
          },
          silent: true,
        },
        {
          show: true,
          map: mapName,
          zoom: 1,
          roam: 'false',
          animationDurationUpdate: 0,//实现缩放、拖动同步且不卡顿
          zlevel: 3,
          layoutCenter: ["51%", "51%"],
          layoutSize: "90%",
          aspectScale: 0.85,
          itemStyle: {
            borderWidth: 1,
            borderColor: "rgba(9, 170, 148,0.6)",
            shadowColor: "rgb(80,183,140)",
            shadowOffsetY: 5,
            shadowBlur: 15,
            areaColor: "transpercent",
          },
          silent: true,
        },
        {
          show: true,
          map: mapName,
          zoom: 1,
          roam: 'false',
          animationDurationUpdate: 0,//实现缩放、拖动同步且不卡顿
          zlevel: 2,
          layoutCenter: ["51.5%", "51.5%"],
          layoutSize: "90%",
          aspectScale: 0.85,
          itemStyle: {
            borderWidth: 1,
            borderColor: "rgba(105, 174, 253,0.4)",
            shadowColor: "rgba(10, 177, 105,0.4)",
            shadowOffsetY: 15,
            shadowBlur: 10,
            areaColor: "transpercent",
          },
          silent: true,
        },
        {
          show: true,
          map: mapName,
          zoom: 1,
          roam: 'false',
          animationDurationUpdate: 0,//实现缩放、拖动同步且不卡顿
          zlevel: 1,
          layoutCenter: ["52%", "52%"],
          layoutSize: "90%",
          aspectScale: 0.85,
          itemStyle: {
            borderWidth: 5,
            borderColor: "rgb(6,125,119)",
            shadowColor: "rgba(10,177,105,0.3)",
            shadowOffsetY: 15,
            shadowBlur: 10,
            areaColor: "rgba(5,21,35,0.1)",
          },
          silent: true,
        },

      ],
      dataRange222: {
        show: true,
        x: 'left',
        y: 'center',
        splitList: [
          { start: 0.8, label: '80%以上', color: '#FF6699' },
          { start: 0.6, end: 0.8, label: '60-80%', color: '#CC3300' },
          { start: 0.4, end: 0.6, label: '40-60%', color: '#F7BB37' },
          { start: 0.3, end: 0.4, label: '30-40%', color: '#3BAE56' },
          { start: 0.2, end: 0.3, label: '20-30%', color: '#92D050' },
          { start: 0.1, end: 0.2, label: '10-20%', color: '#3899FF' },
          { start: 0, end: 0.1, label: '0-10%', color: '#BFBFBF' }
        ],
        textStyle: {
          color: '#3899FF' // 值域文字颜色
        },
        selectedMode: false,
        color: ['#E0022B', '#E09107', '#A3E00B']
      },
      //散点
      series: [{
        type: 'scatter',
        tooltip: {
          show: true,
          textStyle: {
            fontSize: 14,
          },
          formatter: function (params) {

            let data = params.data || {};
            return `
                  <div style='text-align:left'>
                    项目名称:${data.projectName || ""}<br/>
                    单项工程名称:${data.singleProjectName || ""}<br/>
                    标段名称:${data.bidProjectName || ""}<br/>
                    建设单位:${data.orgName || ""}<br/>
                    风险编号:${data.riskNo || ""}<br/>
                    风险状态:${data.riskStatusText || ""}<br/>
                    复测风险等级:${data.retestLevelText || ""}<br/>
                    创建人姓名:${data.creatorName || ""}<br/>
                    创建时间:${data.createTime || ""}<br/>
                    </div>
                    `
          }
        },
        coordinateSystem: 'geo',
        rippleEffect: {
          brushType: 'stroke',
        },
        showEffectOn: 'render',
        itemStyle: {
          normal: {
            color: {
              type: 'radial',
              x: 0.5,
              y: 0.5,
              r: 0.5,
              colorStops: [
                {
                  offset: 0,
                  color: 'rgba(0,228,242,0.5)',
                },
                {
                  offset: 0.8,
                  color: 'rgba(0,228,242,0.8)',
                },
                {
                  offset: 1,
                  color: 'rgba(0,228,242,1)',
                },
              ],
              global: false, // 缺省为 false
            },
          },
        },
       symbol:'pin',
        symbolSize: function (val) {
          // return (val[2] / maxData) * 4;
          return 50
        },
        data: scatterData,
        zlevel: 99,
      },
      ],
      series1: [
        {
          data: [
            { name: '呼伦贝尔市', value: 0.4 }],

          type: "map",
          map: mapName,
          zoom: 1,
          roam: true,
          animationDurationUpdate: 0,//实现缩放、拖动同步且不卡顿
          aspectScale: 0.85,
          layoutCenter: ["50%", "50%"],
          layoutSize: "90%",
          selectedMode: false,
          itemStyle: {
            normal: {
              label: {
                show: true,
                color: "#FF0",
                fontSize: 14,
              },
              borderColor: "#FFFFFF",
              borderWidth: 1,
              areaColor: {
                type: "linear",
                x: 1200,
                y: 0,
                x2: 0,
                y2: 0,
                colorStops: [
                  {
                    offset: 0,
                    color: "rgb(60,213,147)", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "rgba(126, 207, 195,0.75)", // 50% 处的颜色
                  },
                ],
                global: true, // 缺省为 false
              },
            },
            emphasis: {
              // label: {
              //   show: true,
              //   color: "#FF0",
              //   fontSize: 14,
              // },
              // areaColor: "rgba(18, 190, 115, 0.6)",
              // borderColor: "#ffdc00",
            },
          },
          zlevel: 99,

        },
      ],
    };

    let mapChart = echarts.init(document.getElementById(domId));
    mapChart.setOption(option);
    window.onresize = () => {
      mapChart.resize();
    };

    mapChart.on('click', (params) => {
      console.log(params);
    })
    mapChart.on('georoam', (params) => {
      let option = mapChart.getOption();//获得option对象
      let len = option.geo.length;
      if (params.zoom != null) { //捕捉到缩放时
        for (var i = 0; i < len; i++) {
          option.geo[i].center = option.geo[0].center;
          option.geo[i].zoom = option.geo[0].zoom;
        }
      } else {//捕捉到拖曳时

        for (var i = 0; i < len; i++) {
          option.geo[i].center = option.geo[0].center;
        }
      }
      mapChart.setOption(option);//设置option
    })
  }
</script>

</html>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Echarts伪3D地图    Echarts的地图实现拖拽缩放同步功能(解决多层geo缩放、拖动卡顿问题)</title>
    <script src="./js/echarts.min4.8.js"></script>
    <script src="./320000_full.js"></script>
    <!-- <script src="./map-shandong.js"></script> -->
    <!-- <script src="./map-shanxi.js"></script> -->
    <style>
      * {
        margin: 0;
      }
      .map-panel {
        position: relative;
        box-sizing: border-box;
        width: 100vw;
        height: 100vh;
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        grid-template-rows: 55px auto;
        grid-template-areas:
          "header header"
          "left right";
        gap: 10px;
        padding: 10px;
      }
      .title {
        grid-area: header;
        display: grid;
        justify-items: center;
        align-items: center;
        font-size: 28px;
        font-weight: bold;
      }
      .shandong-map {
        grid-area: left;
        border: 1px solid #007acc;
        border-radius: 5px;
      }
      .shanxi-map {
        grid-area: right;
        border: 1px solid #007acc;
        border-radius: 5px;
      }
    </style>
  </head>
  <body>
    <div class="map-panel">
      Echarts的地图实现拖拽缩放同步功能(解决多层geo缩放、拖动卡顿问题)
      <div id="shandong-map" class="shandong-map"></div>
      <div id="shanxi-map" class="shanxi-map"></div>
    </div>
  </body>
  <script>
    window.onload = () => {
      initMap("mapjson", mapjson, "shandong-map");
      initMap("mapjson", mapjson, "shanxi-map");
    };

    function initMap(mapName, mapJsonData, domId) {
      echarts.registerMap(mapName, mapJsonData);
      let option = {
        tooltip: {
          show: false,
        },
        geo: [
          {
            show: true,
            map: mapName,
            zoom: 1,
            roam: 'false',
animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
            regions: [],
            zlevel: 1,
            aspectScale: 0.85,
            layoutCenter: ["50%", "50%"],
            layoutSize: "90%",
            itemStyle: {
              areaColor: "transparent",
            },
          },
          {
            show: true,
            map: mapName,
            zoom: 1,
            roam: 'false',
animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
            zlevel: 4,
            layoutCenter: ["50.5%", "50.5%"],
            layoutSize: "90%",
            aspectScale: 0.85,
            itemStyle: {
              borderWidth: 1,
              borderColor: "rgba(22, 186, 212,0.8)",
              shadowColor: "rgba(80, 183, 140,0.5)",
              shadowOffsetY: 5,
              shadowBlur: 15,
              areaColor: "rgba(5,21,35,0.1)",
            },
            silent: true,
          },
          {
            show: true,
            map: mapName,
            zoom: 1,
            roam: 'false',
animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
            zlevel: 3,
            layoutCenter: ["51%", "51%"],
            layoutSize: "90%",
            aspectScale: 0.85,
            itemStyle: {
              borderWidth: 1,
              borderColor: "rgba(9, 170, 148,0.6)",
              shadowColor: "rgb(80,183,140)",
              shadowOffsetY: 5,
              shadowBlur: 15,
              areaColor: "transpercent",
            },
            silent: true,
          },
          {
            show: true,
            map: mapName,
            zoom: 1,
            roam: 'false',
animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
            zlevel: 2,
            layoutCenter: ["51.5%", "51.5%"],
            layoutSize: "90%",
            aspectScale: 0.85,
            itemStyle: {
              borderWidth: 1,
              borderColor: "rgba(105, 174, 253,0.4)",
              shadowColor: "rgba(10, 177, 105,0.4)",
              shadowOffsetY: 15,
              shadowBlur: 10,
              areaColor: "transpercent",
            },
            silent: true,
          },
          {
            show: true,
            map: mapName,
            zoom: 1,
            roam: 'false',
animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
            zlevel: 1,
            layoutCenter: ["52%", "52%"],
            layoutSize: "90%",
            aspectScale: 0.85,
            itemStyle: {
              borderWidth: 5,
              borderColor: "rgb(6,125,119)",
              shadowColor: "rgba(10,177,105,0.3)",
              shadowOffsetY: 15,
              shadowBlur: 10,
              areaColor: "rgba(5,21,35,0.1)",
            },
            silent: true,
          },

        ],
        series: [
          {
            type: "map",
            map: mapName,
            zoom: 1,
            roam: true,
animationDurationUpdate:0,//实现缩放、拖动同步且不卡顿
            aspectScale: 0.85,
            layoutCenter: ["50%", "50%"],
            layoutSize: "90%",
            selectedMode: false,
            itemStyle: {
              normal: {
                label: {
                  show: true,
                  color: "#FF0",
                  fontSize: 14,
                },
                borderColor: "#FFFFFF",
                borderWidth: 1,
                areaColor: {
                  type: "linear",
                  x: 1200,
                  y: 0,
                  x2: 0,
                  y2: 0,
                  colorStops: [
                    {
                      offset: 0,
                      color: "rgb(60,213,147)", // 0% 处的颜色
                    },
                    {
                      offset: 1,
                      color: "rgba(126, 207, 195,0.75)", // 50% 处的颜色
                    },
                  ],
                  global: true, // 缺省为 false
                },
              },
              emphasis: {
                label: {
                  show: true,
                  color: "#FF0",
                  fontSize: 14,
                },
                areaColor: "rgba(18, 190, 115, 0.6)",
                borderColor: "#ffdc00",
              },
            },
            zlevel: 99,
            data: [],
          },
        ],
      };

      let mapChart = echarts.init(document.getElementById(domId));
      mapChart.setOption(option);
      window.onresize = () => {
        mapChart.resize();
      };

      mapChart.on('georoam',(params)=>{
      let option = mapChart.getOption();//获得option对象
      let len=option.geo.length;
      if(params.zoom != null){ //捕捉到缩放时
        for(var i=0;i<len;i++){
            option.geo[i].center=option.series[0].center;
            option.geo[i].zoom=option.series[0].zoom;
        }
      }else{//捕捉到拖曳时

        for(var i=0;i<len;i++){
            option.geo[i].center=option.series[0].center;
        }
      }
      mapChart.setOption(option);//设置option
    })
    }
  </script>
</html>
posted @ 2023-10-09 17:20  7c89  阅读(2190)  评论(0编辑  收藏  举报