vue使用echarts地图数据分析

/**
  描述:
  
  使用高德api获取地图行政区geoJson,再用echarts去加载这个地图实现点击下钻功能
  
  vue渲染地图热力图、块状图,实现方法: https://juejin.im/post/5db6a8ab5188251d5e755cdf
  
  github上有完整的代码:https://github.com/biubiubiu01/EchartsMap
  
  预览地址:https://gist006.gitee.io/echartsmap/#/ 
  
  阿里云geoJson全国所有市县下载地址:
  
  http://datav.aliyun.com/tools/atlas/#&lat=31.840232667909365&lng=104.2822265625&zoom=4
  
  实现前提:你要先去高德api上去申请key值,免费的,然后引入进来

 高德api上申请密钥,免费的,一天可以发出5000次请求,次数太多了你要去花钱申请企业版,直通车:[https://developer.amap.com/](https://developer.amap.com/)
  
**/


//存储市级的geoJson,因为高德无法获取区县级别的geoJosn数据,所以我们只能获取上一个级别的所有行政区
//然后去遍历,通过名字去比对获取geoJson 

 

1. 根据行政区code去获取行政区边界geoJson 

   你要先cdn引入: 

       <script src='http://webapi.amap.com/maps?v=1.3&key='你申请的key'&plugin=AMap.DistrictSearch'></script>

       <script src="//webapi.amap.com/ui/1.0/main.js"></script> 

    在build/webpack.base.conf.js里面让webpack不处理aMap的依赖库 

      externals: {

        'AMap':'AMap',

        'AMapUI': 'AMapUI'

      } 

    通过AMapUI的DistrictExplorer 方法去获取行政区geoJson

<template>
  <v-card height="1200">
    <v-card-title>地区分布</v-card-title>
    <v-divider></v-divider>
    <v-card-text class="d-flex flex-row" style="height:550px;">
      <div class="mapChoose">
        <span v-for="(item, index) in parentInfo" :key="item.code">
          <span class="title" @click="chooseArea(item, index)">{{
            item.cityName == "全国" ? "中国" : item.cityName
          }}</span>
          <span class="icon" v-show="index + 1 != parentInfo.length">></span>
        </span>
      </div>
      <div style="width:100%;height:100%;" ref="报表"></div>
    </v-card-text>
    <v-card-actions> </v-card-actions>
    <v-divider></v-divider>
    <v-card-text class="d-flex flex-row" style="height:550px;">
      <div style="width:100%;height:100%;" ref="柱状图"></div>
    </v-card-text>
  </v-card>
</template>

<script>
import echarts from "echarts";
import { valueUtil, httpDefaultMsgUtil } from "@/util";
export default {
  name: "map-map",
  data: () => ({
    timerId: 0,
    geoJson: {
      features: []
    },
    parentInfo: [
      {
        cityName: "山东",
        code: 370000
      }
    ]
  }),
  components: {},
  computed: {},
  mounted() {
    const ths = this;
    ths.get1();
    ths.get2();
  },
  destroyed() {
    const ths = this;
    clearTimeout(ths.timerId);
  },
  methods: {
    get1() {
      const ths = this;
      ths.loading = true;
      ths.getGeoJson(370000);
    },
    get2() {
      const ths = this;
      ths.loading = true;
      ths.地区数据加载(ths.地区数据转换());
      httpDefaultMsgUtil.get(
        "api/HomePageEchartsAssessment/GetMapCityBarGraph",
        {},
        {},
        ths,
        succeed => {
          ths.loading = false;
          let data = succeed.data;
          ths.地区数据加载(ths.地区数据转换(data));
          ths.timerId = setTimeout(() => {
            ths.get2();
          }, 1000 * 60);
        }
      );
    },
    数据转换(原始数据) {
      原始数据 = valueUtil.defaultValue(原始数据, []);
      const y轴城市 = 原始数据.map(rec => rec.地区);
      const X轴 = 原始数据.map(rec => rec.数量);
      let 转换数据 = { y轴城市, X轴 };
      return 转换数据;
    },
    地区数据转换(原始数据) {
      原始数据 = valueUtil.defaultValue(原始数据, []);
      const 城市 = 原始数据.map(rec => rec.地区);
      const 数量 = 原始数据.map(rec => rec.数量);
      let 转换数据 = { 城市, 数量 };
      return 转换数据;
    },
    地区数据加载(加载数据) {
      const ths = this;
      ths.getCity(加载数据);
    },
    /**
     *  利用高德api获取行政区边界geoJson
     *   adcode 行政区code 编号
     **/

    //此版本不再维护,准备在写另一个新版本

    getGeoJson(adcode) {
      let that = this;
      AMapUI.loadUI(["geo/DistrictExplorer"], DistrictExplorer => {
        var districtExplorer = new DistrictExplorer();
        districtExplorer.loadAreaNode(adcode, function(error, areaNode) {
          if (error) {
            console.error(error);
            return;
          }
          let Json = areaNode.getSubFeatures();
          if (Json.length > 0) {
            that.geoJson.features = Json;
          } else if (Json.length === 0) {
            that.geoJson.features = that.geoJson.features.filter(
              item => item.properties.adcode == adcode
            );
            if (that.geoJson.features.length === 0) return;
          }
          httpDefaultMsgUtil.get(
            "api/HomePageEchartsAssessment/GetMapCity",
            { code: adcode },
            {},
            that,
            succeed => {
              that.loading = false;
              let data = succeed.data;
              that.getMapData(data);
            }
          );
        });
      });
    },

    //获取数据
    getMapData(服务器数据) {
      let mapData = this.geoJson.features.map(item => {
        let value = 0;
        return {
          name: item.properties.name,
          value: [item.properties.center[0], item.properties.center[1], value],
          cityCode: item.properties.adcode
        };
      });
      //获取服务器的数据  将散点的数量替换格式为[{地区:370100,数量:100},{地区:370200,数量:200}]
      mapData.forEach(item => {
        if (!valueUtil.isEmptyValue(服务器数据)) {
          item.value[2] = 服务器数据.find(a => a.地区 == item.cityCode).数量;
        }
      }),
        (mapData = mapData.sort(function(a, b) {
          return a.value[2] - b.value[2];
        }));
      //去渲染echarts
      this.initEcharts(mapData);
    },
    initEcharts(mapData) {
      this.myChart = echarts.init(this.$refs.报表);
      echarts.registerMap("Map", this.geoJson); //注册
      this.myChart.setOption(
        {
          tooltip: {
            trigger: "item",
            formatter: p => {
              let val = p.value[2];
              if (window.isNaN(val)) {
                val = 0;
              }
              let txtCon = p.name + ":" + val.toFixed();
              return txtCon;
            }
          },
          title: {
            show: true,
            left: "center",
            top: "15",
            text:
              this.parentInfo[this.parentInfo.length - 1].cityName +
              "区域分析图",
            textStyle: {
              color: "rgb(0, 0, 0)",
              fontSize: 16
            }
          },
          toolbox: {
            feature: {
              dataView: {
                show: false
              },
              magicType: {
                show: false
              },
              restore: {
                show: false
              },
              saveAsImage: {
                show: true,
                name: "地图",
                pixelRatio: 2
              }
            },
            iconStyle: {
              normal: {
                borderColor: "#1990DA"
              }
            },
            itemSize: 15,
            top: 20,
            right: 22
          },
          geo: {
            show: true,
            map: "Map", //使用
            roam: false,
            itemStyle: {
              normal: {
                show: true,
                areaColor: "#3a7fd5",
                borderColor: "#215495",
                borderWidth: "1.3",
                shadowColor: "rgb(10,76,139)",
                shadowOffsetX: 5,
                shadowOffsetY: 3,
                shadowBlur: 65
              },
              //emphasis 是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时。
              emphasis: {
                show: true,
                areaColor: "#8dd7fc"
              }
            },
            label: {
              normal: {
                show: true,
                color: "rgb(249, 249, 249)", //省份标签字体颜色
                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;
                    default:
                      break;
                  }
                  return p.name;
                }
              },
              emphasis: {
                show: true,
                color: "#f75a00"
              }
            },
            zoom: 1.15
          },
          series: [
            {
              name: "top5",
              type: "effectScatter",
              data: mapData,
              coordinateSystem: "geo",
              //这里可以设置点的大小
              symbolSize: function(val) {
                //return val[2] / 1.2;
                return 15;
              },
              showEffectOn: "render", //高亮时显示特效
              rippleEffect: {
                brushType: "fill"
              },
              hoverAnimation: false,
              label: {
                normal: {
                  formatter: p => {
                    return p.value[2].toFixed();
                  },
                  position: "center", //地图上是否有文字
                  show: true,
                  textStyle: {
                    color: "#fff"
                  }
                },
                emphasis: {
                  show: false
                }
              },
              itemStyle: {
                normal: {
                  color: "rgba(255, 128, 0,0.8)" //地图点的颜色
                }
              },
              layoutCenter: ["80%", "80%"], //属性定义地图中心在屏幕中的位置,一般结合layoutSize 定义地图的大小
              layoutSize: 430
            }
          ]
        },
        true
      );

      let that = this;
      this.myChart.off("click");
      this.myChart.on("click", params => {
        if (!params.data) {
          return;
        }
        if (
          that.parentInfo[that.parentInfo.length - 1].code ==
          params.data.cityCode
        ) {
          return;
        }
        let data = params.data;
        that.parentInfo.push({
          cityName: data.name,
          code: data.cityCode
        });
        that.getGeoJson(data.cityCode);
      });
    }, //选择切换市县
    chooseArea(val, index) {
      if (this.parentInfo.length === index + 1) {
        return;
      }
      this.parentInfo.splice(index + 1);
      this.getGeoJson(this.parentInfo[this.parentInfo.length - 1].code);
    },
    getCity(数据) {
      const ths = this;
      let el = ths.$refs.柱状图;
      var myChart = echarts.init(el);
      let option = {
        color: ["#3398DB"],
        tooltip: {
          trigger: "axis",
          axisPointer: {
            // 坐标轴指示器,坐标轴触发有效
            type: "shadow" // 默认为直线,可选为:'line' | 'shadow'
          }
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true
        },
        xAxis: [
          {
            type: "category",
            data: 数据.城市,
            axisTick: {
              alignWithLabel: true
            },
            axisLabel: {
              interval: 0,
              formatter: function(value) {
                return value.split("").join("\n");
              }
            }
          }
        ],
        yAxis: [
          {
            type: "value"
          }
        ],
        series: [
          {
            name: "直接访问",
            type: "bar",
            barWidth: "60%",
            label: {
              normal: {
                show: true,
                position: "top"
              }
            },
            color: "#6aadf1",
            data: 数据.数量
          }
        ]
      };
      myChart.setOption(option);
    }
  }
};
</script>
<style lang="scss" scoped>
.echarts {
  width: 100%;
  height: 100%;
  position: relative;
  background-size: 100% 100%;
}

.mapChoose {
  position: absolute;
  left: 20px;
  top: 70px;
  color: #eee;

  .title {
    padding: 2px;
    border-top: 1px solid rgba(147, 235, 248, 0.8);
    border-bottom: 1px solid rgba(147, 235, 248, 0.8);
    cursor: pointer;
    color: rgba(8, 8, 8, 0.8);
  }

  .icon {
    font-family: "simsun";
    font-size: 5px;
    margin: 0 5px;
  }
}
</style>

效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香煎三文鱼

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值