实现echats地图

当一个项目需要用echarts做地图时 会觉得相当棘手
身为前端cv工程师 我在网上找到一个jq版本引入echarts地图的版本 由于项目不用jq 所以我将其转化为vue的版本 效果图如下:
image.png

首先 需要在根目录HTML下引入CDN

image.png

<script src="https://webapi.amap.com/maps?v=1.3&key=73cddabc2173e0166a622f4483d3592a&plugin=AMap.DistrictSearch"></script>
    <script src="https://webapi.amap.com/maps?v=1.3&key=73cddabc2173e0166a622f4483d3592a" type="text/javascript"></script> 
    <script src="https://webapi.amap.com/ui/1.0/main.js"></script>
    <script src="https://echarts.baidu.com/resource/echarts-gl-latest/dist/echarts-gl.min.js"></script>

在创建自己的组件 当然此demo可以层级跳转

<template>

  <div ref="charts"
    id="chart-panel"
    >
    <div class="back">返 回</div>
  </div>

</template>
           
<script>
import * as echarts from 'echarts';
export default {
  name: '',
  data() {
    return {
      geoJson: {},
      parentInfo: [{ cityName: '全国', code: 100000 }],
      currentIndex: 0,
      timeTitle: ['2015', '2016', '2017', '2018', '2019'],
    };
  },
  created() {
    this.$nextTick(() => {
      this.initCharts();
    });
  },
  computed: {},
  methods: {
    initCharts() {
      this.init(100000);
    },
    init(adcode) {
      this.getGeoJson(adcode).then((data) => {
        this.geoJson = data;
        console.log(data, '123123');
        this.getMapData();
      });
    },
    // 获取省市区
    getGeoJson(adcode, childAdcode = '') {
      return new Promise((resolve, reject) => {
        function insideFun(adcode, childAdcode) {
          AMapUI.loadUI(['geo/DistrictExplorer'], (DistrictExplorer) => {
            var districtExplorer = new DistrictExplorer();
            districtExplorer.loadAreaNode(adcode, function (error, areaNode) {
              if (error) {
                console.error(error);
                reject(error);
                return;
              }
              let Json = areaNode.getSubFeatures();
              if (Json.length === 0) {
                let parent = areaNode._data.geoData.parent.properties.acroutes;
                insideFun(parent[parent.length - 1], adcode);
                return;
              }
              if (childAdcode) {
                Json = Json.filter((item) => {
                  return item.properties.adcode == childAdcode;
                });
              }
              let mapJson = {
                features: Json,
              };
              resolve(mapJson);
            });
          });
        }
        insideFun(adcode, childAdcode);
      });
    },
    // 封装数据
    getMapData() {
      let mapData = [],
        pointData = [],
        sum = 0;
      this.geoJson.features.forEach((item) => {
        let value = Math.random() * 3000;
        mapData.push({
          name: item.properties.name,
          value: value,
          cityCode: item.properties.adcode,
        });
        pointData.push({
          name: item.properties.name,
          value: [item.properties.center[0], item.properties.center[1], value],
          cityCode: item.properties.adcode,
        });
        sum += value;
      });
      mapData = mapData.sort(function (a, b) {
        return b.value - a.value;
      });
      this.initEchartMap(mapData, sum, pointData);
      console.log(mapData, 111);
      console.log(sum, 222);
      console.log(pointData, 333);
    },
    initEchartMap(mapData, sum, pointData) {
      var myChart = echarts.init(this.$refs['charts']);
      var xData = [],
        yData = [];
      var min = mapData[mapData.length - 1].value;
      var max = mapData[0].value;
      if (mapData.length === 1) {
        min = 0;
      }
      mapData.forEach((c) => {
        xData.unshift(c.name.replace(/(省|市|自治区|回族|维吾尔|壮族|特别行政区)/g, ''));
        yData.unshift(c.value);
      });
      //这里做个切换,全国的时候才显示南海诸岛  只有当注册的名字为china的时候才会显示南海诸岛
      echarts.registerMap(this.parentInfo.length === 1 ? 'china' : 'map', this.geoJson);

      var option = {
        // 正下方时间自动轮播
        // timeline: {
        //   data: this.timeTitle,
        //   axisType: 'category',
        //   autoPlay: true,
        //   playInterval: 5000,
        //   left: '10%',
        //   right: '10%',
        //   bottom: '2%',
        //   width: '80%',
        //   label: {
        //     normal: {
        //       textStyle: {
        //         color: 'rgb(179, 239, 255)'
        //       }
        //     },
        //     emphasis: {
        //       textStyle: {
        //         color: '#fff'
        //       }
        //     }
        //   },
        //   this.currentIndex: this.currentIndex,
        //   symbolSize: 10,
        //   lineStyle: {
        //     color: '#8df4f4'
        //   },
        //   checkpointStyle: {
        //     borderColor: '#8df4f4',
        //     color: '#53D9FF',
        //     borderWidth: 2,
        //   },
        //   controlStyle: {
        //     showNextBtn: true,
        //     showPrevBtn: true,
        //     normal: {
        //       color: '#53D9FF',
        //       borderColor: '#53D9FF'
        //     },
        //     emphasis: {
        //       color: 'rgb(58,115,192)',
        //       borderColor: 'rgb(58,115,192)'
        //     }
        //   },
        // },
        baseOption: {
          // backgroundColor: '#012248',
          title: [
            {
              left: 'center',
              top: 20,
              text:
                this.parentInfo[this.parentInfo.length - 1].cityName + '销售额统计图(可点击到县)',
              textStyle: {
                color: '#b3efff',
                fontSize: 16,
              },
            },
            {
              text: '销售总额:' + sum.toFixed(2) + '万',
              left: 'center',
              top: 45,
              textStyle: {
                color: '#FFAC50',
                fontSize: 20,
              },
            },
          ],
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'none', // 默认为直线,可选为:'line' | 'shadow'
            },
          },
          legend: {
            show: true,
            icon: 'roundRect',
            itemWidth: 25,
            itemHeight: 15,
            itemGap: 9,
            bottom: '10',
            right: '20',
            textStyle: {
              fontSize: 14,
              color: '#b3efff',
            },
            data: ['单数', '销售额'],
          },
          grid: [
            {
              show: false,
              right: '21%',
              top: '12%',
              bottom: '8%',
              containLabel: true,
              width: '15%',
            },
            {
              show: false,
              right: '18.5%', //调整中间文字位置
              top: '14%', //使中间文字对齐
              bottom: '8%',
              width: '0%',
            },
            {
              show: false,
              right: '2%',
              top: '12%',
              bottom: '8%',
              containLabel: true,
              width: '15%',
            },
          ],
          toolbox: {
            feature: {
              restore: {
                show: false,
              },
              dataView: {
                show: false,
              },
              saveAsImage: {
                name: this.parentInfo[this.parentInfo.length - 1].cityName + '销售额统计图',
              },
              dataZoom: {
                show: false,
              },
              magicType: {
                show: false,
              },
            },
            iconStyle: {
              normal: {
                borderColor: '#1990DA', //右上角下载的颜色
              },
            },
            top: 15,
            right: 35,
          },
          geo: {
            map: this.parentInfo.length === 1 ? 'china' : 'map',
            zoom: 1.1,
            roam: true,
            left: '10%',
            top: '15%',
            tooltip: {
              trigger: 'item',
              formatter: (p) => {
                let val = p.value[2];
                if (window.isNaN(val)) {
                  val = 0;
                }
                let txtCon =
                  "<div style='text-align:left'>" +
                  p.name +
                  ':<br />单数:' +
                  val.toFixed(2) +
                  '单<br />销售额:' +
                  val.toFixed(2) +
                  '万</div>';
                return txtCon;
              },
            },
            label: {
              normal: {
                show: true,
                color: '#f9f9f9', //省份标签字体颜色
                formatter: (p) => {
                  switch (p.name) {
                    case '内蒙古自治区':
                      p.name = '内蒙古';
                      break;
                    case '西藏自治区':
                      p.name = '西藏';
                      break;
                    case '新疆维吾尔自治区':
                      p.name = '新疆';
                      break;
                    case '宁夏回族自治区':
                      p.name = '宁夏';
                      break;
                    case '广西壮族自治区':
                      p.name = '广西';
                      break;
                    case '香港特别行政区':
                      p.name = '香港';
                      break;
                    case '澳门特别行政区':
                      p.name = '澳门';
                      break;
                  }
                  return p.name;
                },
              },
              emphasis: {
                show: true,
                color: '#f75a00',
              },
            },
            itemStyle: {
              normal: {
                areaColor: '#24CFF4',
                borderColor: '#53D9FF',
                borderWidth: 1.3,
                shadowBlur: 15,
                shadowColor: '#3a73c0',
                shadowOffsetX: 7,
                shadowOffsetY: 6,
              },
              emphasis: {
                areaColor: '#8dd7fc',
                borderWidth: 1.6,
                shadowBlur: 25,
              },
            },
          },
          visualMap: {
            //右下角
            min: min,
            max: max,
            left: '3%',
            bottom: '5%',
            calculable: true,
            seriesIndex: [0],
            inRange: {
              color: ['#24CFF4', '#2E98CA', '#1E62AC'],
            },
            textStyle: {
              color: '#24CFF4',
            },
          },
          xAxis: [
            {
              type: 'value',
              inverse: true, //是否是反向坐标轴。
              scale: true,
              position: 'top',
              boundaryGap: false,
              splitLine: {
                show: false,
              },
              axisLine: {
                show: true,
                lineStyle: {
                  color: '#455B77',
                },
              },
              axisTick: {
                show: true,
              },
              axisLabel: {
                show: true,
                lineStyle: {
                  color: 'rgba(255,255,255,0.2)',
                },
                margin: 2,
                textStyle: {
                  color: '#c0e6f9',
                },
              },
            },
            {
              gridIndex: 1,
              show: false,
            },
            {
              gridIndex: 2,
              type: 'value',
              inverse: false, //是否是反向坐标轴。
              scale: true,
              position: 'top',
              boundaryGap: false,
              splitLine: {
                show: false,
              },
              axisLine: {
                show: true,
                lineStyle: {
                  color: '#455B77',
                },
              },
              axisTick: {
                show: true,
              },
              axisLabel: {
                show: true,
                lineStyle: {
                  color: 'rgba(255,255,255,0.2)',
                },
                margin: 2,
                textStyle: {
                  color: '#c0e6f9',
                },
              },
            },
          ],
          yAxis: [
            {
              type: 'category',
              inverse: false,
              position: 'right',
              nameGap: 16,
              axisLine: {
                show: true,
                lineStyle: {
                  color: '#455B77',
                },
              },
              axisTick: {
                show: false,
              },
              axisLabel: {
                show: false,
              },
              data: xData,
            },
            {
              gridIndex: 1,
              type: 'category',
              inverse: false,
              position: 'center',
              nameGap: 16,
              axisLine: {
                show: false,
              },
              axisTick: {
                show: false,
              },
              axisLabel: {
                show: true,
                textStyle: {
                  color: '#c0e6f9',
                  fontSize: 12,
                  align: 'center',
                },
              },
              data: xData,
            },
            {
              gridIndex: 2,
              type: 'category',
              inverse: false,
              position: 'left',
              nameGap: 16,
              axisLine: {
                show: true,
                lineStyle: {
                  color: '#455B77',
                },
              },
              axisTick: {
                show: false,
              },
              axisLabel: {
                show: false,
              },
              data: xData,
            },
          ],
          series: [
            {
              //最外层鼠标经过显示的黑框
              name: this.timeTitle[this.currentIndex] + '年销售额度',
              type: 'map',
              geoIndex: 0,
              map: this.parentInfo.length === 1 ? 'china' : 'map',
              roam: true,
              zoom: 1.3,
              tooltip: {
                trigger: 'item',
                formatter: (p) => {
                  let val = p.value;
                  if (p.name == '南海诸岛') return;
                  if (window.isNaN(val)) {
                    val = 0;
                  }
                  let txtCon =
                    "<div style='text-align:left'>" +
                    p.name +
                    ':<br />单数:' +
                    val.toFixed(2) +
                    '单<br />销售额:' +
                    val.toFixed(2) +
                    '万</div>';
                  return txtCon;
                },
              },
              label: {
                normal: {
                  formatter: function (data) {
                    return '4';
                  },
                  show: true,
                  position: 'right',
                  distance: 5,
                  color: 'white',
                  backgroundColor: '#1D3039',
                  padding: 10,
                  borderRadius: 20,
                  // show: false,
                },
                emphasis: {
                  show: false,
                },
              },
              data: mapData,
            },
            {
              name: '散点',
              type: 'effectScatter',
              coordinateSystem: 'geo',
              rippleEffect: {
                brushType: 'fill',
              },
              itemStyle: {
                normal: {
                  color: '#F4E925',
                  shadowBlur: 10,
                  shadowColor: '#333',
                },
              },
              data: pointData,
              symbolSize: function (val) {
                let value = val[2];
                if (value == max) {
                  return 27;
                }
                return 10;
              },
              showEffectOn: 'render', //加载完毕显示特效
            },
            {
              name: '单数',
              type: 'bar',
              barGap: '-100%',
              barCategoryGap: '60%',
              stack: 'left',
              label: {
                show: true,
                fontSize: 10,
                distance: 10,
                color: '#fff',
                position: 'left', //inside|right
                formatter: (params) => {
                  return params.value.toFixed(2);
                },
              },
              itemStyle: {
                normal: {
                  barBorderRadius: 30,
                  color: new echarts.graphic.LinearGradient(0, 1, 1, 1, [
                    { offset: 0, color: '#EB3B5A' },
                    { offset: 1, color: '#FE9C5A' },
                  ]),
                },
                emphasis: {
                  show: false,
                },
              },
              data: yData,
            },
            {
              name: '销售额',
              type: 'bar',
              barGap: '-100%',
              barCategoryGap: '60%',
              stack: 'right',
              xAxisIndex: 2,
              yAxisIndex: 2,
              label: {
                show: true,
                fontSize: 10,
                distance: 10,
                color: '#fff',
                position: 'right', //inside|right
                formatter: (params) => {
                  return params.value.toFixed(2);
                },
              },
              itemStyle: {
                normal: {
                  barBorderRadius: 30,
                  color: new echarts.graphic.LinearGradient(0, 1, 1, 1, [
                    { offset: 0, color: '#395CFE' },
                    { offset: 1, color: '#2EC7CF' },
                  ]),
                },
                emphasis: {
                  show: false,
                },
              },
              data: yData,
            },
          ],
        },
      };
      myChart.setOption(option, true);
      //点击前解绑,防止点击事件触发多次
      myChart.off('click');
      myChart.on('click', this.echartsMapClick);
      //监听时间切换事件
      myChart.off('timelinechanged');
      myChart.on('timelinechanged', (params) => {
        this.currentIndex = params.this.currentIndex;
        getMapData();
      });
    },
    echartsMapClick(params) {
      // $('.back').css({ cursor: 'pointer', opacity: '1' });
      if (!params.data) {
        return;
      } else {
        //如果当前是最后一级,那就直接return
        if (this.parentInfo[this.parentInfo.length - 1].code == params.data.cityCode) {
          return;
        }
        let data = params.data;
        this.parentInfo.push({
          cityName: data.name,
          code: data.cityCode,
        });
        this.init(data.cityCode);
      }
    },
  },
};
</script>
<style lang='scss'  scoped>
#chart-panel {
  width: 100%;
  height: 1900px;
  height: 770px;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin-top: 10px;
  background-size: 100% auto;
  background-color: #0e0e29;
}
#chart-panel .back {
  opacity: 0.5;
  position: absolute;
  left: 25px;
  top: 20px;
  color: #b3efff;
  font-size: 16px;
  cursor: not-allowed;
  z-index: 100;
}
</style>

第一次做 希望大佬可以留下宝贵的建议

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值