Echarts绘制地图,且可以下钻到省区

本文介绍了如何使用Echarts在JavaScript中绘制地图,并实现点击后下钻到省区的功能。首先安装并引入echarts,然后注册地图,下载地图数据。接着,配置visualMap进行视觉映射,调整图表尺寸,设置地图数据与图例,同时添加了炸弹图标的特殊效果。最后,提供了完整的Echarts地图配置示例,强调了mapInfos和mapJson中name的一致性以及文字位置的调整以避免重叠。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 点击前

点击后(山东省为例)

1. 安装echarts,echarts按需引入      
  npm install echarts --save

//引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口
import * as echarts from 'echarts/core';

2.引入echarts后,基于准备好的dom,初始化echarts实例。 

const ChartMap = (props) =>{
const {id} = props;
const [name, setName] = useState('china');

 const renderMap = (code, name) => {
    const chartId = document.getElementById(id);
    const myChart = echarts.getInstanceByDom(chartId as HTMLElement);
    if (myChart) {
      mapInstance = myChart;
    } else {
      mapInstance = echarts.init(chartId as HTMLElement);
    }
  };

  const chinaMapConfig = (name, data) => {
    // 地图配置
   const option = {...}
    mapInstance.clear();
    mapInstance.setOption(option);
  }

  useEffect(() =>{
    renderMap(name);
  },[name])

  return (
    <div style={{ width: "100%", height: "70vh" }} id={id}></div>
  );
};
export default ChartMap;

  3.  使用echarts.registerMap 注册可用地图

import { MapChart } from 'echarts/charts';
//使用visiualMap来配置图表根据值的范围显示特定的颜色
import { VisualMapComponent } from 'echarts/components';

// 必须在使用 use 方法注册了 MapChart 后才能使用 registerMap 注册地图
 echarts.registerMap(name, data); // name: 地图当前名称和地图的地理数据

4. 地图数据下载,推荐阿里云 DataV
   我已经提前下载到本地,可以统一放在后端或者cdn上

import { mapJson } from './map';
import { ahuiJson } from './ahui';

// 上海, cp地理位置
export const mapJson = {
    type: 'FeatureCollection',
    features: [{
      type: 'Feature',
      id: 'shang_hai',
      properties: {
        name: '上海',
        cp: [121.4648, 31.2891],
        childNum: 19,
        adcode: '310000',
      },
      geometry: {
        type: 'Polygon',
        coordinates: [
          [
            [120.9375, 31.0254],
            [121.2012, 31.4648],
            [121.377, 31.5088],
            [121.1133, 31.7285],
            [121.2012, 31.8604],
            [121.9922, 31.5967],
            [121.9043, 31.1572],
            [121.9922, 30.8057],
            [121.2891, 30.6738],
            [120.9375, 31.0254],
          ],
        ],
      },
    }],
}

5. visualMap 视觉映射组件 
 visualMap 是视觉映射组件。可以定义为 分段型(visualMapPiecewise) 或 连续型(visualMapContinuous),通过 type 来区分。

visualMap: {
        left: "left", // visualMap 组件离容器左侧的距离,值为`'left'`, `'center'`, `'right'`,组件会根据相应的位置自动对齐。
        bottom: 0,
        itemSymbol:"circle",
        right: 10,
        seriesIndex: [0],
        itemWidth: 10, // 每个图元的宽度
        itemGap: 4,    // 每两个图元之间的间隔距离,单位为px
        pieces: [
          {gte: 8, lte: 9, label: '连续下降', color: '#FF4D4D', symbol: 'circle'},
          {gte: 5, lte: 8, label: '本期下降', color: '#FF6F00', symbol: 'circle'},
          {gte: 1, lte: 5, label: '本期上升', color: '#FFC666', symbol: 'circle'},
          {gte: 0, lte: 1, label: '连续上升', color: '#13BF30', symbol: 'circle'},
          {gte: -1, lte: 0, label: '价格预警', color:'', symbol: 'image://http://xxx.png'}
        ],
      },

6. 利用echartsInstance.resize改变图表尺寸 

useEffect(() => {
    window.addEventListener("resize", function () {
      mapInstance.resize();
    });
    return () => {
      mapInstance && mapInstance.dispose();
    };
  }, []);

7. 地图的后端数据
   alwaysDown:true是显示炸弹图标
   value: 是根据数据大小显示色值不同

  const mapInfos1 = [
    {
      alwaysDown: false,
      marketShareTrend: "8",
      name: "上海",
      provCode: "310000",
      provName: "上海",
      value: 1,
    },
    {
      alwaysDown: true,
      marketShareTrend: "8",
      name: "安徽",
      provCode: "340000",
      provName: "安徽省",
      value: 8,
    }
  ]
  const mapInfos2 = [
    {
      alwaysDown: false,
      marketShareTrend: "2",
      provCode: "340200",
      provName: "芜湖市",
      name: "芜湖市",
      value: 3
    },
    {
      alwaysDown: false,
      marketShareTrend: "2",
      name: "马鞍山市",
      provCode: "340500",
      provName: "马鞍山市",
      value: 3
    }
  ]

8.  图例禁止点击

const toEntriesObject = (data) => {
  return data?.features?.map((v) => ({
    name: v.properties.name,
    adcode: v.properties.adcode,
  }));
};

const handleClickMap = () => {
    mapInstance?.on('click', (params) => {
      clearTimeout(timeFn);
      timeFn = setTimeout(function() {
        const name = params.name; //地区name
        const code = toEntriesObject(mapJson).find((el:any) => el.name === name)?.adcode;
        if(!code) return
        setName(name);
    }, 250);
    });
    // 炸弹不点击
    mapInstance?.on('datarangeselected',(e) => {
      const selected = { 0: true, 1: true, 2: true, 3: true, 4: true };
      if (JSON.stringify(selected) !== JSON.stringify(e.selected) && !Object.values(e.selected)[4]) { //* 判断是否为全部选中,全部选中则不用设置。如果不判断则会死循环
        e.selected[4] = true
        mapInstance.dispatchAction({ //* 调用action方法将图例重新设置为全部选中
          type: 'selectDataRange',
          selected: e.selected
        })
      }
    })
  }

9. 炸弹图标添加

geo: {
        map: name,
        zoom: 1.25,
        roam: false,
      },
series: [{
        map: name,
        type: "scatter",
        coordinateSystem: "geo",
        symbol: icon,
        symbolSize: 16,
        symbolOffset: [2, 8],
        data:convertData(mapInfos, mapData),
        tooltip:{
          show: false
        }
 }]

10.  地图的完整配置

const option =  {
      backgroundColor: '#E1E6EB',
      tooltip: {
        trigger: "item",
        showDelay: 0,
        transitionDuration: 0.2,
      },
      visualMap: {
        left: "left", // visualMap 组件离容器左侧的距离,值为`'left'`, `'center'`, `'right'`,组件会根据相应的位置自动对齐。
        bottom: 0,
        itemSymbol:"circle",
        right: 10,
        seriesIndex: [0],
        itemWidth: 10, // 每个图元的宽度
        itemGap: 4,    // 每两个图元之间的间隔距离,单位为px
        pieces: [
          {gte: 8, lte: 9, label: '连续下降', color: '#FF4D4D', symbol: 'circle'},
          {gte: 5, lte: 8, label: '本期下降', color: '#FF6F00', symbol: 'circle'},
          {gte: 1, lte: 5, label: '本期上升', color: '#FFC666', symbol: 'circle'},
          {gte: 0, lte: 1, label: '连续上升', color: '#13BF30', symbol: 'circle'},
          {gte: -1, lte: 0, label: '价格预警', color:'', symbol: 'image://http://xxx.png'}
        ],
      },
      geo: {
        map: name,
        zoom: 1.25,
        roam: false,
      },
      series: [{
        name: 'MAP',
        type: 'map',
        zoom: 1.25,
        mapType: name,
        selectedMode: false,//是否允许选中多个区域
        label: {
            normal: {
                show: true,
            },
            emphasis: {
                show: true
            }
        },
        itemStyle: {
          normal: {
            borderColor: "rgba(254, 254, 254, 1)",
            borderWidth: 1,
            label:{
              color: '#48535A'
            }
          },
          emphasis: {
            areaColor: "#eee",
            borderColor: "rgba(255,111,0,1)",
            borderWidth: 1,
            label:{
              color: '#FF6F00'
            }
          },
        },
        data: mapInfos
      },{
        map: name,
        type: "scatter",
        coordinateSystem: "geo",
        symbol: icon,
        symbolSize: 16,
        symbolOffset: [2, 8],
        data:convertData(mapInfos, mapData),
        tooltip:{
          show: false
        }
      }]
    };

 注意:

  •  mapInfos1,mapInfos2中的name的值要和mapJson的name保持一致,这样数据才会展示出来
  •  mapJson的cp字段是为了调整文字展示的位置,防止重叠在一起
  • serise内scatter的配置与option.geo共存,即在地理坐标系内添加组件,且option.geo.roam为false,否则出现如下情况​​​​​​​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值