vue使用echarts實現中國地圖和點擊省份進行查看功能

1,實現的效果和功能

vue使用echarts實現中國地圖和點擊省份進行查看;
下面是效果圖:主要實現的功能如下:
1,第一張是實現中國地圖,點擊任意省份能夠顯示tooltip提示框 ;
2,第二張是點擊詳情能夠在原來的位置顯示此省的地圖並可以查看詳細;
3,第三張是點擊第二張左上角的返回箭頭 重新返回到 第一張中國地圖
需要的保費模擬數據我會放到文章的最後面;
echarts官網:https://echarts.apache.org/examples/zh/index.html
map地圖參考:https://echarts.apache.org/zh/option.html#series-map

效果圖:

2,安裝ECharts

npm install echarts --save // 最新版本
### 之前版本
npm install [email protected] --save 
### 卸載echarts
npm uninstall echarts

註意:echarts5.0版本下會有地圖的數據,5.0版本以上則沒有地圖的數據,需要自己下載;
或者安裝低版本的echart把map文件夾的地圖數據復制到高版本的對應文件下面也是可以的;

1.1 地圖數據的位置

中國地圖和各省的地圖繪制信息需要放到依賴裡面的echarts下面的map文件夾下面;如下圖:

1.2 還可以自己下載這些地圖數據

下載地址:https://datav.aliyun.com/portal/school/atlas/area_selector

3,main.js裡面引入echarts

// 引入echarts
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts //掛載到原型上面 也可以選擇不掛載 直接在頁面上引入

4,實現如下

主要流程如下:

1,需要有一個容器 <div id="chinaMap" v-if="pyName === 'china'"></div> 且有唯一 id值
2,this.$echarts.init(document.getElementById('chinaMap')); 用來初始化節點 id和上面的相對應;
3,require('../../../node_modules/echarts/map/json/china.json');用來導入相對應的地圖數據,echarts進行渲染
4,options配置項用來設置echarts圖表的樣式和展示數據相關;
5,this.myEchartsOfChina.setOption(options);設置圖表實例的配置項以及數據,萬能接口,所有參數和數據的修改都可以通過 setOption 完成,ECharts 會合並新的參數和數據,然後刷新圖表;
6,optionsformatterhtml裡面的點擊事件需要在mounted裡面先行註冊一下,否則此方法會報錯:undefined;

全部代碼如下:

<template>
  <div>
    <h1>echarts可視化</h1>
    <hr />
    <div class="container">
      <!-- 全國地圖 機構趨勢模塊 -->
      <div class="china">
        <!-- 點擊返回全國-->
        <div @click="returnCh">
          <img v-if="pyName !== 'china'" class="returnImg" src="@/assets/img/return.png" />
        </div>
        <div id="chinaMap" v-if="pyName === 'china'"></div>
        <div id="provinceMap" v-if="pyName !== 'china'">111</div>
      </div>
    </div>
  </div>
</template>
<script>
import { cityArr, totalMap } from './data/mapData';
export default {
  components: {},
  data() {
    return {
      // 全省保費信息
      totalMap: null,
      // 各個城市的數據
      cityArr: null,
      myEchartsOfChina: null,
      // 默認選擇的城市 這是拼音
      pyName: 'china',
      // 保留一份省名的中文
      pyNameOfChinese: '',
    };
  },

  created() {
    // 拿到數據
    this.totalMap = totalMap;
    this.cityArr = cityArr;
    // 頁面進來註冊tooltip上面的點擊事件 否則會報此事件undefined
    window.lookVideoGo = this.lookVideoGo;
  },

  // 頁面掛載完成後調用
  mounted() {
    this.chinaMapFun();
  },

  methods: {
    /*中國地圖 參考文章:https://echarts.apache.org/zh/option.html#series-map*/
    chinaMapFun(cityName) {
      // 先處理數據 很重要
      let mapData = [];
      for (let i = 0; i < this.totalMap.length; i++) {
        let obj = { value: 0, datas: [] }; // 數組裡面是多個對象
        obj.name = this.totalMap[i].comname2; // names屬性時數據所對應的地圖區域的名稱,例如 '廣東','浙江';參考文章: https://echarts.apache.org/zh/option.html#series-map.data
        obj.value = this.totalMap[i].achieveRate; // 該區域的數據值 number類型
        obj.datas[0] = this.totalMap[i].preium;
        obj.datas[1] = this.totalMap[i].target;

        //註意: 此行是模擬下面的省份用的 實際開發中每個省份的數據是後端返回的
        if (this.totalMap[i].children) {
          obj.children = this.totalMap[i].children;
        }
        mapData.push(obj);
      }

      // 這裡進行篩選傳進來的省份數據 模擬黑龍江省份下面的和黑河市
      if (this.pyNameOfChinese) {
        mapData = mapData.map((item) => {
          if (item.children) {
            return { name: item.children.comname2, value: item.children.achieveRate, datas: [item.children.preium, item.children.target] };
          }
        });
      }
      console.log('當前渲染的地圖:', this.pyName);
      console.log('當前渲染的數據2:', mapData);

      // 1,初始化節點
      // 檢測是否已經存在echarts實例,如果不存在,則不再去初始化
      if (this.pyName === 'china') {
        this.myEchartsOfChina = this.$echarts.init(document.getElementById('chinaMap'));
      } else {
        this.myEchartsOfChina = this.$echarts.init(document.getElementById('provinceMap'));
      }

      // 顯示加載動畫
      this.myEchartsOfChina.showLoading();
      if (this.pyName === 'china') {
        let province = require('../../../node_modules/echarts/map/json/china.json');
        // 註冊地圖數據
        this.$echarts.registerMap(this.pyName, province);
      } else {
        // 單獨引入其他省份的地圖  註意:registerMap方法的第一參數要和引入的省名相同
        let province = require('../../../node_modules/echarts/map/json/province/' + this.pyName + '.json');
        this.$echarts.registerMap(this.pyName, province);
      }

      this.myEchartsOfChina.hideLoading();
      /* 參考文檔: https://echarts.apache.org/zh/option.html#series-map */
      // 設置整個中國地圖的參數
      let options = {
        title: {
          show: false, // 是否顯示標題組件
          text: '中國地圖', // 主標題文本
          subtext: '註:展示當月和當年累計情況',
          left: '3%',
          top: '85%',
        },
        tooltip: {
          enterable: true, // 允許點擊觸發tooltip中的事件
          show: true, // 是否顯示提示框組件,包括提示框浮層和 axisPointer。 [ default: true ]
          trigger: 'item', // 觸發類型。 [ default: 'item' ]
          triggerOn: 'click', // 隻有點擊時才觸發 不設置默認隨鼠標移動並顯示
          formatter: (array, returnData, callback) => {
            if (isNaN(array.value)) {
              if (this.cityArr.includes(array.name)) {
                return '保費: 暫無' + '<br/>' + '目標: 暫無' + '<br/>' + '保費達成率: 暫無';
              } else {
                return '保費: 暫無' + '<br/>';
              }
            } else {
              let result =
                '<div style="display: flex"><div style="float:left;">保費: ' +
                array.data.datas[0] +
                '萬元  <br/>  目標: ' +
                array.data.datas[1] +
                '萬元  <br/>  保費達成率: ' +
                array.data.value +
                '%</div>' +
                '<div style="float:left; margin-left: 0.1rem;width: 0.05rem;height: 1rem; background: #D8D8D8;"></div>' +
                '<div style="float:left; margin-left: 0.1rem; "οnclick="lookVideoGo(\'' +
                array.name +
                '\')"><p style="height:2rem; line-height:2rem;">詳 情 >&nbsp</p></div></div>';
              return result;
            }
          },
          backgroundColor: 'rgba(50,50,50,0.7)', // tooltip 背景顏色 rgba
          // 文本設置
          textStyle: {
            color: 'rgb(255,255,255)', // 值域文字顏色
            fontSize: 12,
          },
        },

        // 底部小導航圖標
        visualMap: {
          // text: ['註:展示當月和當年累計情況'],
          orient: 'horizontal',
          itemWidth: 15,
          textGap: 2,
          // calculable: false,
          show: true,
          left: 'center',
          y: 'bottom',
          splitList: [
            { end: 0, label: '無', color: '#DDDDDD' },
            { end: 30, color: 'rgb(255,248,220)' },
            { start: 30, end: 60, label: '30-60', color: 'rgb(252,235,207)' },
            { start: 60, end: 90, label: '60-90', color: '#FFDAB9' },
            { start: 90, end: 100, label: '90-100', color: 'rgb(245,158,131)' }, // 245 158  131
            { start: 100, label: '>=100', color: 'rgb(40,183,163)' }, // 40 183 163
          ],
        },
        backgroundColor: '#fff', // 圖表背景色

        series: [
          {
            name: '省份',
            type: 'map', // 指定是地圖類型
            map: this.pyName, // 和上面registerMap中的第一個參數值一致才可以正常加載地圖
            zoom: 1.2,
            roam: true, // 是否開啟平遊或縮放
            // geoIndex: 0,
            // aspectScale: 0.75,
            // scaleLimit: { // 滾輪縮放的極限控制
            //   min: 1,
            //   max: 2
            // },
            selectedMode: 'single', // 選中模式,表示是否支持多個選中,默認關閉,支持佈爾值和字符串,字符串取值可選'single'表示單選,或者'multiple'表示多選。
            itemStyle: {
              areaColor: '#FFFFFF',
              borderColor: '#0f0f0f',
              normal: { label: { show: true }, areaColor: '#DDDDDD' },
              emphasis: { label: { show: true } },
            },
            emphasis: {
              // 強調的樣式,也就是鼠標移入後的樣式==高亮狀態下的多邊形和標簽樣式。
              itemStyle: {
                areaColor: '#000000',
              },
            },
            label: {
              normal: {
                show: true, // 是否顯示標簽,這裡顯示的就是省份的名字。默認就是false
                textStyle: {
                  fontWeight: 300,
                  color: '#000000', // 值域文字顏色
                  fontSize: 7, // 文字的字體大 小
                },
              },
              emphasis: {
                show: false, // 在鼠標移入時,是否顯示,如果不寫,默認是顯示的
              },
            },
            data: mapData, // 各省地圖數據導入
          },
        ],
      };

      // 設置各個省份地圖的參數
      let options1 = {
        title: {
          show: false, // 是否顯示標題組件
          subtext: '註:展示當月和當年累計情況',
          left: '3%',
          top: '85%',
        },
        tooltip: {
          enterable: true, // 允許點擊觸發tooltip中的事件
          show: true, // 是否顯示提示框組件,包括提示框浮層和 axisPointer。 [ default: true ]
          trigger: 'item', // 觸發類型。 [ default: 'item' ]
          backgroundColor: 'rgba(50,50,50,0.7)', // tooltip 背景顏色 rgba
          // 文本設置
          textStyle: {
            color: 'rgb(255,255,255)', // 值域文字顏色
            fontSize: 12,
          },
          formatter: (array, returnData, callback) => {
            console.log(array);
            if (isNaN(array.value)) {
              if (this.cityArr.includes(array.name)) {
                return '保費: 暫無' + '<br/>' + '目標: 暫無' + '<br/>' + '保費達成率: 暫無';
              } else {
                return '保費: 暫無' + '<br/>';
              }
            } else {
              let result =
                '<div style="display: flex"><div style="float:left;">保費: ' +
                array.data.datas[0] +
                '萬元  <br/>  目標: ' +
                array.data.datas[1] +
                '萬元  <br/>  保費達成率: ' +
                array.data.value +
                '%</div>' +
                '<div style="float:left; margin-left: 0.1rem;width: 0.05rem;height: 1rem; background: #D8D8D8;"></div>' +
                '<div style="float:left; margin-left: 0.1rem; "οnclick="lookVideoGo(\'' +
                array.name ;
              return result;
            }
          },
        },
        // 底部小導航圖標
        visualMap: {
          // text: ['註:展示當月和當年累計情況'],
          orient: 'horizontal',
          itemWidth: 15,
          textGap: 2,
          // calculable: false,
          show: true,
          left: 'center',
          y: 'bottom',
          splitList: [
            { start: 6, label: '>=7', color: '#FFDAB9' },
            { start: 3, end: 6, label: '4-6', color: 'rgb(245,158,131)' }, // 245 158  131
            { start: 1, end: 3, label: '1-3', color: 'rgb(40,183,163)' }, // 40 183 163
            { end: 0, label: '無', color: '#DDDDDD' },
          ],
        },
        series: [
          {
            name: '省份', // 系列名稱,用於tooltip的顯示,legend 的圖例篩選,在 setOption 更新數據和配置項時用於指定對應的系列。見上:可以在tooltip中獲取到
            type: 'map', // 指定是地圖類型
            map: this.pyName, // 和上面registerMap中的一直
            zoom: 1.2,
            selectedMode: 'single', // 選中模式,表示是否支持多個選中,默認關閉,支持佈爾值和字符串,字符串取值可選'single'表示單選,或者'multiple'表示多選。
            itemStyle: {
              areaColor: '#FFFFFF',
              borderColor: '#0f0f0f',
              normal: { label: { show: true }, areaColor: '#DDDDDD' },
              emphasis: { label: { show: true } },
            },
            emphasis: {
              // 強調的樣式,也就是鼠標移入後的樣式==高亮狀態下的多邊形和標簽樣式。
              itemStyle: {
                areaColor: '#000000',
              },
            },
            label: {
              normal: {
                show: true, // 是否顯示標簽,這裡顯示的就是省份的名字。默認就是false
                textStyle: {
                  fontWeight: 300,
                  color: '#000000', // 值域文字顏色
                  fontSize: 7, // 文字的字體大 小
                },
              },
              emphasis: {
                show: false, // 在鼠標移入時,是否顯示,如果不寫,默認是顯示的
              },
            },
            // 數據對不上 省下面的地區對不上
            data: mapData,
          },
        ],
      };
      // 判斷是否是各個省份
      if (this.pyName === 'china') {
        this.myEchartsOfChina.setOption(options);
      } else {
        this.myEchartsOfChina.setOption(options1);
      }
    },

    /* 傳過來的參數是省份名 */
    lookVideoGo(cityName) {
      // 保留一份中文
      this.pyNameOfChinese = cityName;
      // this.myEchartsOfChina.clear(); // 清空當前實例,會移除實例中所有的組件和圖表。
      this.myEchartsOfChina.dispose(); // 銷毀後實例無法在使用

      // 獲取城市拼音
      for (var i = 0, len = this.cityArr[0].length; i < len; i++) {
        if (cityName === this.cityArr[0][i]) {
          // 獲取得城市拼音
          this.pyName = this.cityArr[1][i];
          // 使用nextTick Api 防止echarts初始化時避免節點不存在的報錯
          this.$nextTick(() => {
            this.chinaMapFun(this.pyName);
          });
          break;
        } else {
          console.warn('沒有找到此城市的拼音');
        }
      }
    },
    /* 點擊返回全國 */
    returnCh() {
      // this.myEchartsOfChina.clear(); // 清空當前實例,會移除實例中所有的組件和圖表。
      this.myEchartsOfChina.dispose(); // 銷毀後實例 這裡使用dispose防止殘留
      this.pyName = 'china';
      this.pyNameOfChinese = '';

      // 使用nextTick Api 防止echarts初始化時避免節點不存在的報錯
      this.$nextTick(() => {
        this.chinaMapFun();
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.container {
  width: 90%;
  // margin: 0 auto;
  border: 1px solid balck;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-direction: row;
  flex-wrap: wrap;
  #chinaMap,#provinceMap {
    width: 400px;
    height: 400px;
    margin-right: 30px;
    margin-top: 20px;
  }
  .china{
  }
  // 返回箭頭
  .returnImg{
    cursor: pointer;
    display: block;
    width: 25px;
  }
}
</style>

5,遇到的問題

5.1 渲染中國地圖時警告地圖不存在:

原因:series裡面的map屬性沒有和上面registerMap中的第一個參數值保持一致

正確寫法:

5,2 點擊tooltip提示框中的詳情 生產省份地圖失敗,警告如下:

原因:沒有拿到dom節點,需要在 this.$nextTick API裡面獲取dom節點

正確寫法:

 		// 獲取城市拼音
      for (var i = 0, len = this.cityArr[0].length; i < len; i++) {
        if (cityName === this.cityArr[0][i]) {
          // 獲取得城市拼音
          this.pyName = this.cityArr[1][i];
          // 使用nextTick Api 防止echarts初始化時避免節點不存在的報錯
          this.$nextTick(() => {
            this.chinaMapFun(this.pyName);
          });
          break;
        } else {
          console.warn('沒有找到此城市的拼音');
        }
      }

6,用到的模擬數據

mapData.js

// 定義全國省份的數組
export const cityArr = [
  [
    '上海',
    '河北',
    '山西',
    '內蒙古',
    '遼寧',
    '吉林',
    '黑龍江',
    '江蘇',
    '浙江',
    '安徽',
    '福建',
    '江西',
    '山東',
    '河南',
    '湖北',
    '湖南',
    '廣東',
    '廣西',
    '海南',
    '四川',
    '貴州',
    '雲南',
    '西藏',
    '陜西',
    '甘肅',
    '青海',
    '寧夏',
    '新疆',
    '北京',
    '天津',
    '重慶',
    '香港',
    '澳門',
    '臺灣',
  ],
  [
    'shanghai',
    'hebei',
    'shanxi',
    'neimenggu',
    'liaoning',
    'jilin',
    'heilongjiang',
    'jiangsu',
    'zhejiang',
    'anhui',
    'fujian',
    'jiangxi',
    'shandong',
    'henan',
    'hubei',
    'hunan',
    'guangdong',
    'guangxi',
    'hainan',
    'sichuan',
    'guizhou',
    'yunnan',
    'xizang',
    'shanxi1',
    'gansu',
    'qinghai',
    'ningxia',
    'xinjiang',
    'beijing',
    'tianjin',
    'chongqing',
    'xianggang',
    'aomen',
    'taiwan',
  ],
];

// 全省保費信息
export const totalMap = [
  {
    achieveRate: 104.1,
    comname2: '山東',
    preium: 22855,
    target: 21960,
  },
  {
    achieveRate: 154,
    comname2: '新疆',
    preium: 893,
    target: 580,
  },
  {
    achieveRate: 128.6,
    comname2: '青海',
    preium: 935,
    target: 727,
  },
  {
    achieveRate: 84.7,
    comname2: '四川',
    preium: 7357,
    target: 8687,
  },
  {
    achieveRate: 79.4,
    comname2: '陜西',
    preium: 5102,
    target: 6427,
  },
  {
    achieveRate: 84.6,
    comname2: '內蒙古',
    preium: 10448,
    target: 12357,
  },
  {
    achieveRate: 0,
    comname2: '無錫',
    preium: 21,
    target: 0,
  },
  {
    achieveRate: 74.8,
    comname2: '甘肅',
    preium: 5468,
    target: 7308,
  },
  {
    achieveRate: 93.4,
    comname2: '海南',
    preium: 3746,
    target: 4009,
  },
  {
    achieveRate: 71.4,
    comname2: '湖北',
    preium: 2870,
    target: 4017,
  },
  {
    achieveRate: 39.4,
    comname2: '廈門',
    preium: 188,
    target: 477,
  },
  {
    achieveRate: 63.3,
    comname2: '寧夏',
    preium: 1292,
    target: 2042,
  },
  {
    achieveRate: 135.2,
    comname2: '江西',
    preium: 5616,
    target: 4155,
  },
  {
    achieveRate: 0,
    comname2: '東莞',
    preium: 0,
    target: 0,
  },
  {
    achieveRate: 95,
    comname2: '貴州',
    preium: 6931,
    target: 7298,
  },
  {
    achieveRate: 39.1,
    comname2: '江蘇',
    preium: 2303,
    target: 5893,
  },
  {
    achieveRate: 0,
    comname2: '上海',
    preium: 6,
    target: 0,
  },
  {
    achieveRate: 85.7,
    comname2: '天津',
    preium: 1672,
    target: 1950,
  },
  {
    achieveRate: 60.1,
    comname2: '廣東',
    preium: 3260,
    target: 5428,
  },
  {
    achieveRate: 58.6,
    comname2: '青島',
    preium: 1979,
    target: 3380,
  },
  {
    achieveRate: 67.7,
    comname2: '吉林',
    preium: 12375,
    target: 18288,
  },
  {
    achieveRate: 45.3,
    comname2: '湖南',
    preium: 4527,
    target: 9995,
  },
  {
    achieveRate: 52.2,
    comname2: '北京',
    preium: 6,
    target: 12,
  },
  {
    achieveRate: 86.1,
    comname2: '河南',
    preium: 5733,
    target: 6659,
  },
  {
    achieveRate: 71.6,
    comname2: '安徽',
    preium: 3201,
    target: 4471,
  },
  {
    achieveRate: 50.6,
    comname2: '黑龍江',
    preium: 3127,
    target: 6186,
    children:{
        comname2:'黑河市',
        preium: 3127,
        target: 6186,
        achieveRate: 50.6,
    }
  },
  {
    achieveRate: 0,
    comname2: '蘇州',
    preium: 193,
    target: 0,
  },
  {
    achieveRate: 69.9,
    comname2: '山西',
    preium: 2051,
    target: 2935,
  },
  {
    achieveRate: 77.6,
    comname2: '福建',
    preium: 4371,
    target: 5632,
  },
  {
    achieveRate: 96.5,
    comname2: '浙江',
    preium: 9650,
    target: 10000,
  },
  {
    achieveRate: 73.5,
    comname2: '遼寧',
    preium: 8753,
    target: 11915,
  },
  {
    achieveRate: 78.1,
    comname2: '重慶',
    preium: 2587,
    target: 3313,
  },
  {
    achieveRate: -0.5,
    comname2: '深圳',
    preium: 0,
    target: 24,
  },
  {
    achieveRate: 112.5,
    comname2: '寧波',
    preium: 1233,
    target: 1096,
  },
  {
    achieveRate: 122.7,
    comname2: '雲南',
    preium: 5477,
    target: 4462,
  },
  {
    achieveRate: 104.9,
    comname2: '河北',
    preium: 13750,
    target: 13107,
  },
  {
    achieveRate: 66.4,
    comname2: '廣西',
    preium: 1134,
    target: 1707,
  },
];

到此這篇關於vue使用echarts實現中國地圖和點擊省份進行查看的文章就介紹到這瞭,更多相關vue echarts 中國地圖內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: