vue3项目中使用echarts实现中国地图大区任意分区

最终效果:

背景:项目需要在中国地图上显示各大区的库存情况,使用echarts将下载的中国地图挂载后,好家伙,全是一块块的省份,再定睛一看,我这项目需求的大区咋只有6个,好好好,看来得探索一波如何将各省份自定义为大区了。

1. echarts、中国地图json文件下载

echarts下载:

npm install echarts

中国地图json码文件下载

想要显示地图,这个文件很必要。下载地址:DataV.GeoAtlas地理小工具系列 (aliyun.com)

 2.  实现基本地图展示

 在.vue文件中引用echarts、中国地图json文件:

import * as echarts from 'echarts';
import chinaJson from "@/assets/json/china.json"

注:

1、这里echarts是全部引用,最好按需引用;

2、这里json名是改过的

 html代码:

<div id="myChart" style="width:100%;height:calc(100% - 30px)"></div>

js代码:

  onMounted(() => {
    myChart= echarts.init(document.getElementById('myChart'))
    window.onresize = function(){
      // 图形随窗口变化而变化
      myChart.resize();
    }
  })

  const initMyChartt = (mychart) => {
    let dataList = [
      {name: '湖北省', value: 732},
      {name: '贵州省', value: 666},
      {name: '广东省', value: 333},
      {name: '广西壮族自治区', value: 123},
      {name: '湖南省', value: 50},
      {name: '四川省', value: 0}
    ]
    let option = {
      tooltip: {
        trigger: 'item',
        formatter: function (params) {
          return params.name+':'+params.value;//自行定义formatter格式
        }
      },
      visualMap: {
        show: false,
        min: 0,
        max: 1000,
        left: 'left',
        top: 'bottom',
        text: ['高', '低'],//取值范围的文字
        inRange: {
          color: ['#79bbff', '#c45656', '#FD665F']
        },
      },
      geo: {
        map: 'china',
        roam: true,//不开启缩放和平移
        zoom: 1.23,//视角缩放比例
        scaleLimit:{min:1,max:3}, // 缩放级别
        zoom: 1.23,//视角缩放比例
        regions: [
          {
            name: "南海诸岛",
            value: 0,
            itemStyle: {
              opacity: 0, // 不绘制
            },
            label: {
              show: false // 不显示文字
            }
          }
        ],
        label: {
          show: true,
          fontSize: '10',
          color: 'rgba(0,0,0,0.7)', // 大区文本颜色
          
        },
        itemStyle: {
          // borderWidth: 0,
          // borderColor: 'rgba(0, 0, 0, 0.2)', // 边界框线颜色 
          
        },
        emphasis: {
          label: {
            color: '#fff' 
          },
          itemStyle: {
            areaColor: '#337ecc',//鼠标选择区域颜色
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            shadowBlur: 20,
            shadowColor: 'rgba(0, 0, 0, 0.5)',
          }  
        }
      },
      series: [
        {
          name: '中国地图',
          type: 'map',
          geoIndex: 0,
          data: dataList
        }
      ] 
    }
    echarts.registerMap('china', { geoJSON: chinaJson });
    mychart.setOption(option, true);
  }

 效果如下图:

 3. 大区划分

呃呃,接下来就是大区划分了,也就是将某些省份合成一个大区,怎么合?要合什么地方?害怕!!

不行,为了项目(为了活下去),我们打开地图json码来分析一下,相信答案就在里面嘻嘻嘻。

 下载下来的地图json:

里面包含了两个属性,其中“features”属性里面是个数组,里面是34个对象。好这下明白了,这不就是34个省份?!,把这些省份合成需要的大区就好了。

通过观察,保持原有的数据结构不变,将features.properties.name改成大区名,将归属改大区的省份的features.geometry.coordinates合并为一个,最后将修改后的地图挂载在echart上就能得到想要的省份合并大区了。

修改中国地图json文件代码:

  import chinaJson from "@/assets/json/chinaLand.json"
  // 将省份合并成大区
  const mergeProvinces = (features, province, region) => {//合并大区里省份的coordinates
    let newFeatures = [];
    if(features[0].properties.name.indexOf('大区')!==-1) {
      return
    }
    for(let i = 0; i < province.length; i++) {
      for(let j = 0; j < province[i].length; j++) {
        for(let k = 0; k < features.length; k++) {
          if(features[k].properties.name == province[i][j]) {
            if(newFeatures[i]) {
              if(features[k].properties.name == '内蒙古自治区') {
                features[k].geometry.coordinates = [features[k].geometry.coordinates]
              }
              newFeatures[i].geometry.coordinates.push(...features[k].geometry.coordinates)
            }else {
              newFeatures.push(features[k])
              newFeatures[i].properties.name = region[i]
            }
            break
          }
        }
      }
    }
    chinaJson.features = newFeatures;
  };
  // 按照需要设定大区分区,province中元素内容为region中各大区所包含的省份,需要对应好
  const provinceAndregion = {
      province: [//把各个大区的省份用二维数组分开
        ["黑龙江省", "吉林省",  "辽宁省", '北京市', '天津市', '河北省'],
        [ '湖北省', '上海市', '江苏省', '安徽省', '浙江省'],
        ["河南省", '山东省'],
        ['湖南省', '重庆市', '四川省', '云南省', '西藏自治区', '贵州省'],
        ['陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区','山西省',"内蒙古自治区"],
        ['广东省', '广西壮族自治区', '福建省', '海南省', '江西省', '香港特别行政区', '澳门特别行政区', '台湾省'],
      ],
      region: ['东北大区', '华东大区', '华中大区', '西南大区', '西北大区', '华南大区'],
  };

  // 调用
  mergeProvinces(chinaJson.features, provinceAndregion.province, provinceAndregion.region);

 最终实现分区js代码(全部):

  onMounted(() => {
    myChart= echarts.init(document.getElementById('myChart'))
    window.onresize = function(){
      // 图形随窗口变化而变化
      myChart.resize();
    }
  })
  // 将省份合并成大区
  const mergeProvinces = (features, province, region) => {//合并大区里省份的coordinates
    let newFeatures = [];
    if(features[0].properties.name.indexOf('大区')!==-1) {
      return
    }
    for(let i = 0; i < province.length; i++) {
      for(let j = 0; j < province[i].length; j++) {
        for(let k = 0; k < features.length; k++) {
          if(features[k].properties.name == province[i][j]) {
            if(newFeatures[i]) {
              if(features[k].properties.name == '内蒙古自治区') {
                features[k].geometry.coordinates = [features[k].geometry.coordinates]
              }
              newFeatures[i].geometry.coordinates.push(...features[k].geometry.coordinates)
            }else {
              newFeatures.push(features[k])
              newFeatures[i].properties.name = region[i]
            }
            break
          }
        }
      }
    }
    chinaJson.features = newFeatures;
  };
  const initMyChartt = (mychart) => {
   const provinceAndregion = {
      province: [//把各个大区的省份用二维数组分开
        ["黑龙江省", "吉林省",  "辽宁省", '北京市', '天津市', '河北省'],
        [ '湖北省', '上海市', '江苏省', '安徽省', '浙江省'],
        ["河南省", '山东省'],
        ['湖南省', '重庆市', '四川省', '云南省', '西藏自治区', '贵州省'],
        ['陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区','山西省',"内蒙古自治区"],
        ['广东省', '广西壮族自治区', '福建省', '海南省', '江西省', '香港特别行政区', '澳门特别行政区', '台湾省'],
      ],
      region: ['东北大区', '华东大区', '华中大区', '西南大区', '西北大区', '华南大区'],
    };
    mergeProvinces(chinaJson.features, provinceAndregion.province, provinceAndregion.region);
    let dataList = [
      {name: '西北大区', value: 732},
      {name: '华南大区', value: 666},
      {name: '东北大区', value: 333},
      {name: '西南大区', value: 123},
      {name: '华东大区', value: 50},
      {name: '华中大区', value: 0}
    ]
    let option = {
      tooltip: {
        trigger: 'item',
        formatter: function (params) {
          return params.name+':'+params.value;//自行定义formatter格式
        }
      },
      visualMap: {
        show: false,
        min: 0,
        max: 1000,
        left: 'left',
        top: 'bottom',
        text: ['高', '低'],//取值范围的文字
        inRange: {
          color: ['#79bbff', '#c45656', '#FD665F']
        },
      },
      geo: {
        map: 'china',
        roam: true,//不开启缩放和平移
        zoom: 1.23,//视角缩放比例
        scaleLimit:{min:1,max:3}, // 缩放级别
        zoom: 1.23,//视角缩放比例
        regions: [
          {
            name: "南海诸岛",
            value: 0,
            itemStyle: {
              opacity: 0, // 不绘制
            },
            label: {
              show: false // 不显示文字
            }
          }
        ],
        label: {
          show: true,
          fontSize: '10',
          color: 'rgba(0,0,0,0.7)', // 大区文本颜色
          
        },
        itemStyle: {
          borderWidth: 0,
          // borderColor: 'rgba(0, 0, 0, 0.2)', // 边界框线颜色 
          
        },
        emphasis: {
          label: {
            color: '#fff' 
          },
          itemStyle: {
            areaColor: '#337ecc',//鼠标选择区域颜色
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            shadowBlur: 20,
            shadowColor: 'rgba(0, 0, 0, 0.5)',
          }  
        }
      },
      series: [
        {
          name: '中国地图',
          type: 'map',
          geoIndex: 0,
          data: dataList
        }
      ] 
    }
    echarts.registerMap('china', { geoJSON: chinaJson });
    mychart.setOption(option, true);
  }

最终效果:

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
function getGzMap(_data) { if (_chinaMap == undefined) { var dom = document.getElementById("container"); _chinaMap = echarts.init(dom); _chinaMap.on('click', function(params) { console.log(params); var _type = params.seriesType; if (_type == "map") { //window.parent.aaa('aa') //调用父页面方法 } else if (_type == "effectScatter") { window.parent.showMap(); } }) } var option = { backgroundColor: 'rgba(0,0,0,0)', visualMap: { type: 'piecewise', show: false, min: 0, max: 300, splitNumber: 3, itemWidth: 10, itemHeight: 10, itemGap: 5, seriesIndex: [1], pieces: [ { min: 0, max: 100, label: '优' }, { min: 101, max: 200, label: '良' }, { min: 201, max: 300, label: '高风险' } ], //color: ['#FA4D08', '#4BD94F', '#FBD32B'], //红、绿、黄 color: ['#F8DAE6', '#FEF9B5', '#B0D8B3'], //红、黄、绿 textStyle: { color: '#9EA8B1', fontSize: 10 } }, tooltip: { formatter: '{b}' }, geo: { map: 'guangdong', roam: true, aspectScale: 1, zoom: 1.5, layoutCenter: ['55%', '40%'], layoutSize: 500, label: { normal: { show: true }, emphasis: { show: true } }, itemStyle: { normal: { areaColor: '#323c48', borderColor: '#111', borderColor: '#3BB4DF', shadowColor: '#25A3FC', shadowBlur: 10 }, emphasis: { areaColor: '#ddb926' } } }, series: [{ type: 'effectScatter', coordinateSystem: 'geo', data: unitData, symbolSize: 10, symbol: 'image://../../../../Content/images/One/fire.png', //symbolRotate: 35, rippleEffect: { period: 4, scale: 5, brushType: 'fill', }, label: { normal: { formatter: '{b}', position: 'right', show: false }, emphasis: { show: false } }, itemStyle: { normal: { color: '#fff' } } }, { name: '', type: 'map', geoIndex: 0, mapType: 'guangdong', // 自定义扩展图表类型 label: { normal: { show: true, } }, itemStyle: { normal: { label: { show: true, fontSize: 10, color: '#111' }, shadowColor: '#ddb926', shadowBlur: 5, }, emphasis: { label: { show: true }, shadowColor: 'rgba(0, 0, 0, 0.5)', shadowBlur: 10 } }, data: _data }, { type: 'effectScatter', coordinateSystem: 'geo', data: windData, symbolSize: 10, symbol: 'image://../../../../Content/images/One/wind.png', //symbolRotate: 35, rippleEffect: { period: 4, scale: 5, brushType: 'fill', }, label: { normal: { formatter: '{b}', position: 'right', show: false }, emphasis: { show: false } }, itemStyle: { normal: { color: '#fff' } } }, ] }; $.getJSON('../../MapCN/guangdong.json', function(chinaJson) { echarts.registerMap('guangdong', chinaJson); _chinaMap.setOption(option, true); }); }
要在Vue项目使用echarts图表,你需要先安装echarts库。可以通过npm或yarn来安装echarts: ```bash npm install echarts --save # 或者 yarn add echarts ``` 然后在Vue组件引入echarts使用它来绘制图表。以下是一个简单的例子: ```vue <template> <div class="chart-container"> <div ref="echarts" class="echarts"></div> </div> </template> <script> import echarts from 'echarts' export default { name: 'EchartsDemo', data() { return { chartData: [ { name: '一月', value: 100 }, { name: '二月', value: 200 }, { name: '三月', value: 300 }, { name: '四月', value: 400 }, { name: '五月', value: 500 }, { name: '六月', value: 600 } ] } }, mounted() { this.drawChart() }, methods: { drawChart() { const chartDom = this.$refs.echarts const chart = echarts.init(chartDom) const option = { xAxis: { type: 'category', data: this.chartData.map(item => item.name) }, yAxis: { type: 'value' }, series: [{ data: this.chartData.map(item => item.value), type: 'bar' }] } chart.setOption(option) } } } </script> <style scoped> .echarts { width: 100%; height: 400px; } </style> ``` 在这个例子,我们在组件的`mounted`生命周期钩子调用了`drawChart`方法来绘制图表。方法首先通过`this.$refs.echarts`获取到一个DOM元素,然后使用`echarts.init`方法初始化echarts实例。接着,我们通过设置`option`对象来定义图表的配置,最后调用`chart.setOption`方法来渲染图表。 上面的例子演示了如何使用echarts来绘制一个简单的柱状图。你可以根据需要调整`option`对象的配置来实现其他类型的图表,例如折线图、饼图等等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值