如何使用Echarts v5版本绘制优雅的中国地图

metal 1年前 ⋅ 3578 阅读
ad

前言

Echarts升级到V5版本之后,在网上想找到一个拿来就能用的绘制地图的文档,就感觉很困难。由于最近有绘制地图展示的需求,求人不如求己,自己总结了一波,虽然也不是太完善,但是能大致可用吧。

一、安装依赖

//这里以5.3.2版本为例
npm install echarts@5.3.2 --save

二、下载地图的JSON数据,保存到本地并命名为geoJson.js

可以通过中国地图获取json数据链接 下载相关数据。类似如下数据

export default {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "adcode": 110000,
                "name": "北京市",
                "center": [
                    116.405285,
                    39.904989
                ],
                "centroid": [
                    116.41995,
                    40.18994
                ],
                "childrenNum": 16,
                "level": "province",
                "parent": {
                    "adcode": 100000
                },
                "subFeatureIndex": 0,
                "acroutes": [
                    100000
                ]
            },
            ...
       ]
}

可以把下载的json数据之间拿来用,也可以把显示在地图中的省份名称修改掉,如上述代码中的“name”, 北京市更换为北京。(下述的实例中都做了相应的调整)

三、初始化

V5版本的Echarts导入稍微有点差异

//v5之前的版本引入echarts
import echarts form 'echarts';

//v5的版本引入echarts
import * as echarts from 'echarts';
//导入地图数据
import geoJson from './geoJson.js';

//注册可用地图
echarts.registerMap('china', { geoJSON: geoJson });

//初始化
const myCharts = echarts.init(document.getElementById(chartId), null, { renderer: 'svg' });

四、设置echarts的地图option

const option = {
    //提示
    tooltip: {
      trigger: 'item',
      backgroundColor: '#1F2329',
      padding: [10, 13],
      textStyle: {
        color: 'rgba(255, 255, 255, 0.65)',
        fontSize: 14,
        lineHeight: 22,
        fontFamily: 'HelveticaNeue'
      },
      extraCssText: 'box-shadow: 0px 2px 8px 0px rgba(31, 35, 41, 0.3);',
      formatter: function (params) {
        if (typeof params.value[2] === 'undefined') {
          return params.name + ' : ' + params.value
        }
        return params.name + ' : ' + params.value[2]
      }
    },
    //视觉映射组件
    visualMap: [
      {
        type: 'piecewise',
        show: true,
        left: 'left',
        top: 'bottom',
        itemGap: 15,
        itemWidth: 24,
        padding: 0,
        itemHeight: 16,
        seriesIndex: [1],
        pieces: [
          { gt: 199, label: '> 199', color: '#2179FF' },
          { gt: 100, lte: 199, label: '100-199', color: 'rgba(33,151,255,0.6)' }, // 不指定 max,表示 max 为无限大(Infinity)。
          { gte: 1, lte: 100, label: '1-100', color: 'rgba(33,151,255,0.3)' },
          { value: 0, label: '0', color: '#F2F3F5', opacity: 0 },
        ],
        textStyle: {
          color: '#646A73',
          fontSize: 14
        }

      }
    ],
    geo: {
      show: true,
      map: mapName,
      label: {
        normal: {
          show: false
        },
        emphasis: {
          show: false,
        }
      },
      roam: false,
      left: '10%',
      top: 50,
      right: '5%',
      bottom: -120,
      aspectScale: .35, //长宽比
      itemStyle: {
        normal: {
          areaColor: '#F2F3F5',
          borderColor: '#fff',
          borderWidth: 1.2,
        },
        emphasis: {
          areaColor: 'rgba(33,151,255,0.1)',
        }
      }
    },
    series: [
      //散点
      {
        name: '散点',
        type: 'effectScatter',
        effectType: 'ripple',
        showEffectOn: 'render',
        rippleEffect: {
          period: 4,
          brushType: 'stroke',
          scale: 4
        },
        coordinateSystem: 'geo',
        data: convertData(data),
        symbolSize: function (params) {
          const value = params[2]
          return value === 0 ? '' : 8
        },
        itemStyle: {
          normal: {
            color: 'rgba(33,151,255,0.1)', //标志颜色
          }
        }
      },
      //区域颜色
      {
        type: 'map',
        map: 'china',
        geoIndex: 0,
        roam: false,
        itemStyle: {
          normal: {
            areaColor: '#F2F3F5',
            borderColor: '#FFF',
          },
          emphasis: {
            areaColor: '#F2F3F5'
          }
        },
        animation: true,
        data: data
      },
      //气泡
      {
        name: '点',
        type: 'scatter',
        coordinateSystem: 'geo',
        symbol: 'pin', //气泡
        animation: true,
        symbolSize: function (param) {
          // const a = (maxSize4Pin - minSize4Pin) / (max - min)
          // let b = minSize4Pin - a * min
          // b = maxSize4Pin - a * max
          const value = param[2]
          return value === 0 ? 0 : 30
        },
        label: {
          normal: {
            position: 'inside',
            distance: 0,
            show: true,
            formatter: function (params) {
              const value = params.data.value[2]
              return value === 0 ? '' : value
            },
            textStyle: {
              color: '#fff',
              fontSize: 10,
            }
          }

        },
        itemStyle: {
          normal: {
            color: '#FF7626', //标志颜色
          }
        },
        zlevel: 6,
        data: convertData(data),
      },
    ]
  }

myCharts.setOption(option);

对数据的转换处理

  const mapName = 'china';
  //对应到下载地图json中显示的名称,先初始化数据
  const data = [
    { name: '北京', value: 0 },
    { name: '天津', value: 0 },
    { name: '上海', value: 0 },
    { name: '重庆', value: 0 },
    { name: '河北', value: 0 },
    { name: '山西', value: 0 },
    { name: '辽宁', value: 0 },
    { name: '吉林', value: 0 },
    { name: '黑龙江', value: 0 },
    { name: '江苏', value: 0 },
    { name: '浙江', value: 0 },
    { name: '安徽', value: 0 },
    { name: '福建', value: 0 },
    { name: '江西', value: 0 },
    { name: '山东', value: 0 },
    { name: '河南', value: 0 },
    { name: '湖北', value: 0 },
    { name: '湖南', value: 0 },
    { name: '广东', value: 0 },
    { name: '海南', value: 0 },
    { name: '四川', value: 0 },
    { name: '贵州', value: 0 },
    { name: '云南', value: 0 },
    { name: '陕西', value: 0 },
    { name: '甘肃', value: 0 },
    { name: '青海', value: 0 },
    { name: '台湾', value: 0 },
    { name: '内蒙古', value: 0 },
    { name: '广西', value: 0 },
    { name: '西藏', value: 0 },
    { name: '宁夏', value: 0 },
    { name: '新疆', value: 0 },
    { name: '香港', value: 0 },
    { name: '澳门', value: 0 },
    { name: '南海诸岛', value: 0 },
  ];
  const realData = []; //真实数据
  for (let i = 0; i < data.length; i++) {
    realData.forEach((item) => {
      if (item.name === data[i].name) {
        data[i].value = item.value
      }
    })
  }
  const geoCoordMap = {}
  /*获取地图数据*/
  let mapFeatures = []
  if (echarts.getMap(mapName)) {
    mapFeatures = echarts.getMap(mapName).geoJson.features
  }
  mapFeatures.forEach(function (v) {
    // 地区名称
    const name = v.properties.name
    // 地区经纬度
    geoCoordMap[name] = v.properties.cp
  })
  let maxValue = 0
  for (let i = 0; i < data.length; i++) {
    if (data[i].value > maxValue) {
      maxValue = data[i].value
    }
  }
  const convertData = function (dataCon) {
    const res = []
    for (let i = 0; i < dataCon.length; i++) {
      const geoCoord = geoCoordMap[dataCon[i].name]
      if (geoCoord) {
        res.push({
          name: dataCon[i].name,
          value: geoCoord.concat(dataCon[i].value),
        })
      }
    }
    return res
  }

五、最终成型地图如下

关于Webfunny

Webfunny专注于前端监控系统,前端埋点系统的研发。 致力于帮助开发者快速定位问题,帮助企业用数据驱动业务,实现业务数据的快速增长。支持H5/Web/PC前端、微信小程序、支付宝小程序、UniApp和Taro等跨平台框架。实时监控前端网页、前端数据分析、错误统计分析监控和BUG预警,第一时间报警,快速修复BUG!支持私有化部署,Docker容器化部署,可支持千万级PV的日活量!

  点赞 0   收藏 0
  • metal
    共发布8篇文章 获得0个收藏
全部评论: 0