echarts-for-react实现国内各省的地图切换

没接触echarts-for-react之前一直使用的是echarts封装画图,但是突然接到一个需要显示各省的地图切换,查遍了百度也没发现类似的案例。既然我们有画地图的工具ehcarts和各省的地标位置数据那么应该是可以实现的,理论可行,开始实践。

首先我们获取到各省的地表数据

https://github.com/lj-code/city_data/blob/master/%E7%9C%81%E5%B8%82%E5%8E%BF.json

然后我们需要动态的获取地图信息

fetch(`https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=${code}`);

这里我还添加了antd的级联选择组件,是地图的显示精确到了区县地区。详细的页面代码如下:

import React, { useEffect, useState } from 'react';
import { Select, Spin } from 'antd';
import ReactECharts from 'echarts-for-react';
import * as echarts from 'echarts';
import proCityData from './data/proCityCounties.json';

const { Option } = Select;

// 示例数据
const provinceData = proCityData;
// 来源https://github.com/lj-code/city_data/blob/master/%E7%9C%81%E5%B8%82%E5%8E%BF.json

// 异步函数,获取GeoJSON数据
const fetchGeoJson = async (code: string) => {
  // 请求对应code的GeoJSON数据
  const response = await fetch(`https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=${code}`);
  return response.json();
};

const ProvinceMap: React.FC = () => {
  const [selectedProvince, setSelectedProvince] = useState<string>(''); // 选中的省份
  const [selectedCity, setSelectedCity] = useState<string>(''); // 选中的城市
  const [selectedDistrict, setSelectedDistrict] = useState<string>(''); // 选中的区县
  const [loading, setLoading] = useState<boolean>(false); // 加载状态
  const [option, setOption] = useState<any>({
    series: [],
  });

  // 当选中的省市区变化时,加载相应的GeoJSON数据
  useEffect(() => {
    const loadGeoJson = async (code: string) => {
      setLoading(true); // 开始加载
      const geoJson = await fetchGeoJson(code); // 获取GeoJSON数据
      echarts.registerMap(code, geoJson); // 注册地图数据
      setOption({
        series: [
          {
            type: 'map',
            map: code,
            roam: true, // 开启缩放和平移
            label: {
              show: true, // 显示标签
            },
            itemStyle: {
              normal: {
                areaColor: '#fde6cf', // 正常状态下区域的颜色
                borderColor: 'none' // 边界颜色
              },
              emphasis: {
                areaColor: '#fbb569', // 鼠标移到区域上时的颜色
              },
            },
          },
        ],
      });
      setLoading(false); // 加载完成
    };

    // 优先加载区县地图,其次是城市地图,再次是省份地图
    if (selectedDistrict) {
      loadGeoJson(selectedDistrict);
    } else if (selectedCity) {
      loadGeoJson(selectedCity);
    } else if (selectedProvince) {
      loadGeoJson(selectedProvince);
    }
  }, [selectedProvince, selectedCity, selectedDistrict]);

  // 处理省份选择变化
  const handleProvinceChange = (value: string) => {
    setSelectedProvince(value); // 设置选中的省份
    setSelectedCity(''); // 清空选中的城市
    setSelectedDistrict(''); // 清空选中的区县
  };

  // 处理城市选择变化
  const handleCityChange = (value: string) => {
    setSelectedCity(value); // 设置选中的城市
    setSelectedDistrict(''); // 清空选中的区县
  };

  // 处理区县选择变化
  const handleDistrictChange = (value: string) => {
    setSelectedDistrict(value); // 设置选中的区县
  };

  // 获取指定省份的城市列表
  const getCities = (provinceCode: string) => {
    const province = provinceData.find(p => p.code === provinceCode);
    return province ? province.cityList : [];
  };

  // 获取指定城市的区县列表
  const getDistricts = (cityCode: string) => {
    const province = provinceData.find(p => p.cityList.some(c => c.code === cityCode));
    const city = province?.cityList.find(c => c.code === cityCode);
    return city ? city.areaList : [];
  };

  return (
    <div>
      {/* 省份选择器 */}
      <div style={{ width: '600' }}>
        <Select
          style={{ width: 200, marginBottom: 20 }}
          placeholder="选择省份"
          onChange={handleProvinceChange}
          value={selectedProvince}
        >
          {provinceData.map(province => (
            <Option key={province.code} value={province.code}>
              {province.name}
            </Option>
          ))}
        </Select>

        {/* 城市选择器 */}
        {selectedProvince && (
          <Select
            style={{ width: 200, marginBottom: 20, marginLeft: 10 }}
            placeholder="选择城市"
            onChange={handleCityChange}
            value={selectedCity}
          >
            {getCities(selectedProvince).map(city => (
              <Option key={city.code} value={city.code}>
                {city.name}
              </Option>
            ))}
          </Select>
        )}

        {/* 区县选择器 */}
        {selectedCity && (
          <Select
            style={{ width: 200, marginBottom: 20, marginLeft: 10 }}
            placeholder="选择区县"
            onChange={handleDistrictChange}
            value={selectedDistrict}
          >
            {getDistricts(selectedCity).map(district => (
              <Option key={district.code} value={district.code}>
                {district.name}
              </Option>
            ))}
          </Select>
        )}

        {/* 显示加载状态或地图 */}
        <div style={{ width: '600px',height:'600px' }}>
          {loading ? <Spin /> : <ReactECharts option={option} style={{ height: 500, width: '100%' }} />}
        </div>
      </div>
    </div>
  );
};

export default ProvinceMap;

其中代码注释已经很详细了,希望能帮助到你!

(请注意!页面用到的插件为echarts-for-react,并非只有echarts。)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值