react、echarts和地圖的結(jié)合

PS:使用的是React框架

要實現(xiàn)的效果如下:

image-20200828222623165.png
image-20200828222646486.png
  • 需要一張地圖,對地圖進(jìn)行下鉆操作龟糕,地圖的區(qū)域需要顏色標(biāo)記

  • 兩種標(biāo)記方式(氣泡和圓點),且顏色需要不一樣

  • 右邊要有柱狀圖顯示人數(shù)

開始之前我們需要準(zhǔn)備一個獲得地圖json數(shù)據(jù)的網(wǎng)站

地圖選擇器: https://datav.aliyun.com/tools/atlas/

image-20200828222918544.png

需要哪部分的數(shù)據(jù)悔耘,點擊這個按鈕復(fù)制到你的編輯器上就可以了讲岁。

image-20200828223007494.png

準(zhǔn)備工作做完,我們就開始進(jìn)入正題了:首先我們要一個“地圖畫布”衬以,有了畫布才能折騰數(shù)據(jù)缓艳。


畫一個地圖

引入echarts和相關(guān)的json文件

import Echarts from 'echarts';
import jiangxi from '../../../config/mapJSON/jiangxi.json';
import jiujiang from '../../../config/mapJSON/jiujiang.json';

準(zhǔn)備一個div存放地圖,記得寫div的高度和寬度看峻。

<div id='map' style={{height: '100%', width: '100%'}}></div>

整體的框架(我們先把option放一放阶淘,先別急,現(xiàn)在你的頁面一定是空的)

let myChart = Echarts.init(document.getElementById('map'))

let name = 'jiangxi' //地圖名是jiangxi
let data = jiangxi  //地圖的數(shù)據(jù)來自之前引入的json文件
Echarts.registerMap(name, data) //此步不可省略互妓,要想展示一個地圖舶治,先需要注冊,巨坑(官方根本無文檔车猬,全靠瞎猜)
let option = {} //此處先省略,不放入任何數(shù)據(jù)
myChart.setOption(option, true);

現(xiàn)在為option添磚加瓦尺锚,此時你的頁面會有一個小地圖了

let option = {
      backgroundColor: '#fff',
      title: {
        top: 20,
        text: '用戶注冊區(qū)域展示',
        subtext: '',
        x: 'center',
        textStyle: {
          color: '#000'
        }
      },
      geo: {
        type: 'map',
        map: name, //'jiangxi'
        roam: true,
        geoIndex: 1,
        zoom: 1.1,  //地圖的比例
        label: {
          normal: {
            show: true,
            textStyle: {
              color: '#000000'  //字體顏色
            }
          },
          emphasis: {
            textStyle: {
              color: '#000000'  //選中后的字體顏色
            }
          }
        },
        itemStyle: {
          normal: {
            areaColor: '#EEEEEE',
            borderColor: '#8b8b8b',
          },
          emphasis: {
            areaColor: '#ffffff',
          }
        },
      },
    }
image-20200828225711380.png

現(xiàn)在想在地圖上綁定我的數(shù)據(jù)珠闰,應(yīng)該怎么做呢?

//獲得數(shù)據(jù)這一步我就不寫了,用下面的死數(shù)據(jù)
let cityData = [{name:'南昌市',value:47},{name:'九江市',value:22}瘫辩,{name:'新余市',value:4}]

//在geo多配置一行data數(shù)據(jù)
geo:{
    ...
    data:cityData
}


設(shè)置地圖色塊

此時雖然數(shù)據(jù)綁定成功了伏嗜,但是地圖上依舊什么色塊都沒有坛悉。我們繼續(xù)下一步,設(shè)置option中的visualMap參數(shù)和series參數(shù)承绸。

visualMap用來設(shè)置地圖的色塊裸影,series參數(shù)用于標(biāo)記地圖。

visualMap: {
         show: true,
         //設(shè)置最大值和最小值
         min: 0,
         max: 50,
         //設(shè)置位置
         left: '4%',
         top: '40%',
         text: ['高', '低'], // 文本军熏,默認(rèn)為數(shù)值文本
         calculable: true,
         seriesIndex: [0], //作用在哪個series上
         inRange: {
           color: ['#ffcbc5', '#ffd661'] //粉黃
         }
       },
       
series:[
        {
          name: "市報名人數(shù)",
          type: "map",
          geoIndex: 0,
          data: cityData,
        },
      ]

設(shè)置圓點標(biāo)記

下圖是圓點需要的數(shù)組轩猩,為這個數(shù)組命名為areaData

image-20200828231834043.png

給series新增一個圓點標(biāo)記

  {
          name: '區(qū)縣報名人數(shù)',
          type: 'effectScatter',
          coordinateSystem: 'geo',
          showEffectOn: 'render',
          rippleEffect: {
            period: 15,
            scale: 4,
            brushType: 'fill'
          },
          hoverAnimation: true,
          itemStyle: {
            normal: {
              color: '#fffd21', //設(shè)置圓點的顏色
              shadowBlur: 10,
              shadowColor: '#333'
            }
          },
          symbolSize: function (params) {
            console.log('paramsparams', params[2])
            if (params[2] > 30)
              return params[2] / 5
            else
              return 3
          }, //圓點的大小可以自行設(shè)置,這里不贅述
          data: areaData,
},

設(shè)置氣泡標(biāo)記

氣泡和圓點的原理是相同的荡澎,他們的數(shù)據(jù)要求是需要經(jīng)緯度以及數(shù)據(jù)均践,你無法知道經(jīng)緯度的時候可以從提前下載好的json數(shù)據(jù)中取。然后繼續(xù)在series中添加氣泡標(biāo)記摩幔。

  let geoCoordMap = jiangxi.features.map(item => {
      return {
        name: item.properties.name,
        value: item.properties.center
      }
  });
  
 let convertData = function (data) {
      let res = [];
      for (let i = 0; i < data.length; i++) {
        if (geoCoordMap.filter(item => item.name === data[i].name).length)
          res.push({
            name: data[i].name,
            value: geoCoordMap.filter(item => item.name === data[i].name)[0].value.concat(data[i].value)
          })
      }
      return res;
}
{
          name: 'Top 5',
          type: 'scatter',
          coordinateSystem: 'geo',
          symbol: 'pin',
          symbolSize: 40,
          label: {
            normal: {
              show: true,
              textStyle: {
                color: '#fff',
                fontSize: 9,
                fontWeight: 'bold'
              },
              formatter(value) {
                return value.data.value[2]
              }
            }
          },
          itemStyle: {
            normal: {
              color: '#F62157', //標(biāo)志顏色
            }
          },
              //使用之前的函數(shù)處理數(shù)據(jù)彤委,為之前的cityData添加經(jīng)緯度,當(dāng)然也可以讓初始數(shù)據(jù)像之前的areaData一樣就有經(jīng)緯度
          data: convertData(cityData), 
          showEffectOn: 'render',
          rippleEffect: {
            brushType: 'stroke'
          },
          hoverAnimation: true,
          zlevel: 1
},

現(xiàn)在的效果:

image-20200828233714352.png

設(shè)置右側(cè)的柱狀圖

為option添加xAxis和yAxis(一定要有或衡,否則在series中新增type為bar的標(biāo)記時會報錯)

柱狀圖中的數(shù)據(jù)需要特殊處理

let barData = cityData.map((item) => {
  return [item.value, item.name]
})
   //option中的grid表示bar的位置
    grid: {
              left: '70%',
              right: '10%',
              // top: '30%',
              // bottom:'40%'
    },

    xAxis: {
      type: 'value',
      // scale: true,
      position: 'top',
      min: 0,
      boundaryGap: false,
      splitLine: {
        show: false
      },
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        margin: 1,
        textStyle: {
          color: '#aaa'
        }
      },
    },
    yAxis: {
      type: 'category',
      inverse: true, //改變數(shù)據(jù)順序
      nameGap: 16,
      axisLine: {
        show: true,
        lineStyle: {
          color: '#ddd'
        }
      },
      axisTick: {
        show: false,
        lineStyle: {
          color: '#ddd'
        }
      },
      axisLabel: {
        interval: 0,
        show: true,
        textStyle: {
          color: '#000000'
        }
      },
    },

地圖下鉆操作※

你需要知道:

  • 點擊地圖怎么做到
  • 怎么通過點擊地圖進(jìn)行下鉆
  • 下鉆后地圖上的標(biāo)記數(shù)據(jù)如何改變(氣泡焦影、圓點、柱狀圖)

你還記得我們給地圖的命名嗎——myChart封断,實現(xiàn)點擊就要為它添加點擊事件斯辰,打印看看這里的e是何方神圣。

 myChart.on('click', (e) => {
      console.log('click', e)
 })

想一想澄港,我們需要根據(jù)點擊城市名的不同下鉆到不同的城市椒涯。那么需要的就是點擊這塊區(qū)域的name了。

image-20200829000036839.png

還記得我們是怎么使用地圖的嗎回梧?注冊地圖時废岂,有一個地圖名和地圖名對應(yīng)的json,由于我們獲得的name是中文狱意,無法和json數(shù)據(jù)對應(yīng)湖苞,選擇switch語句進(jìn)行調(diào)整地圖名,下面的thisMap相當(dāng)于最開始初始化地圖時的name详囤,thisData相當(dāng)于最開始初始化地圖時的data财骨。

image-20200829000610811.png

//得到加載地圖時的地圖名
switch (e.name) {
        case  '九江市':
          thisMap = 'jiujiang';
          break
        case '南昌市':
          thisMap = 'nanchang';
          break
        case '撫州市':
          thisMap = 'fuzhou';
          break
        case '贛州市':
          thisMap = 'ganzhou';
          break
        case '吉安市':
          thisMap = 'jian';
          break
        case '景德鎮(zhèn)市':
          thisMap = 'jingdezhen';
          break
        case '萍鄉(xiāng)市':
          thisMap = 'pingxiang';
          break
        case '上饒市':
          thisMap = 'shangrao';
          break
        case '新余市':
          thisMap = 'xinyu';
          break
        case '宜春市':
          thisMap = 'yichun';
          break
        case '鷹潭市':
          thisMap = 'yingtan';
          break
      }
      //得到加載地圖時的地圖json
      let area = {
      '九江市': require('../../../config/mapJSON/jiujiang.json'),
      '南昌市': require('../../../config/mapJSON/nanchang.json'),
      '撫州市': require('../../../config/mapJSON/fuzhou.json'),
      '贛州市': require('../../../config/mapJSON/ganzhou.json'),
      '吉安市': require('../../../config/mapJSON/jian.json'),
      '景德鎮(zhèn)市': require('../../../config/mapJSON/jingdezhen.json'),
      '萍鄉(xiāng)市': require('../../../config/mapJSON/pingxiang.json'),
      '上饒市': require('../../../config/mapJSON/shangrao.json'),
      '新余市': require('../../../config/mapJSON/xinyu.json'),
      '宜春市': require('../../../config/mapJSON/yichun.json'),
      '鷹潭市': require('../../../config/mapJSON/yingtan.json')
    }
      
    thisData = area[e.name]

如何動態(tài)的把thisMap和thisData傳遞給Echarts,告訴Echarts我需要換一個地圖進(jìn)行注冊呢藏姐?可以寫一個函數(shù)loadMap(可以還有別的方法隆箩,不贅述)。先打個框架羔杨。

let loadMap = (name,data) =>{
 //現(xiàn)在是否是下鉆狀態(tài)=>通過name是否為'jiangxi'判斷
 //如果是下鉆:過濾areaData,barData中的其他區(qū)域數(shù)據(jù)捌臊,
 //如果不是下鉆狀態(tài):之前在jiangxi時的數(shù)據(jù)全部存入state,現(xiàn)在取出并賦值還原兜材。
    let option = {}
} 

總結(jié)

最后重新整理一下整體框架

showMap(cityData, areaData){
    //cityData理澎,areaData 這里的數(shù)據(jù)需要你自己獲得 
    let myChart = Echarts.init(document.getElementById('map'))
    
     //默認(rèn)地圖:江西省
    let thisMap = 'jiangxi'
    let thisData = jiangxi
    
    let loadMap = (name, data) => {
      //地圖名轉(zhuǎn)回中文逞力,為了方便過濾數(shù)據(jù)
      if (name !== 'jiangxi') {
        let key = ''
        switch (name) {
          case 'jiujiang' :
            key = '九江市';
            break
          //... 不贅述
        }
        //在areaData中找到對應(yīng)市的區(qū)和縣
        let array = areaData.filter(item => item.city === key)
        let cd = array.map(item => {
          return {
            name: item.name,
            value: item.value[2]
          }
        })
        barData = array.map(item => {
          return [item.value[2], item.name]
        })
        areaData = []
        cityData = cd
      } else {
        areaData = this.state.areaData
        cityData = this.state.cityData
        barData = cityData.map((item) => {
          return [item.value, item.name]
        })
      }
      Echarts.registerMap(name, data) //注冊地圖

      let option = {}
      myChart.setOption(option, true);
    }
    
     loadMap(thisMap, thisData)
     myChart.on('click', (e) => {
      switch (e.name) {
        case  '九江市':
          thisMap = 'jiujiang';
          break
        //...不贅述
      }
      thisData = area[e.name]
      //下鉆
      if (thisData) {
        loadMap(thisMap, thisData)
      } else {
        //不繼續(xù)下鉆返回上一層
        loadMap('jiangxi', jiangxi)
      }
    })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市糠爬,隨后出現(xiàn)的幾起案子寇荧,更是在濱河造成了極大的恐慌,老刑警劉巖执隧,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揩抡,死亡現(xiàn)場離奇詭異,居然都是意外死亡殴玛,警方通過查閱死者的電腦和手機(jī)捅膘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滚粟,“玉大人寻仗,你說我怎么就攤上這事》踩溃” “怎么了署尤?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亚侠。 經(jīng)常有香客問我曹体,道長,這世上最難降的妖魔是什么硝烂? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任箕别,我火速辦了婚禮,結(jié)果婚禮上滞谢,老公的妹妹穿的比我還像新娘串稀。我一直安慰自己,他們只是感情好狮杨,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布母截。 她就那樣靜靜地躺著,像睡著了一般橄教。 火紅的嫁衣襯著肌膚如雪清寇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天护蝶,我揣著相機(jī)與錄音华烟,去河邊找鬼。 笑死持灰,一個胖子當(dāng)著我的面吹牛垦江,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼比吭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姨涡?” 一聲冷哼從身側(cè)響起衩藤,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涛漂,沒想到半個月后赏表,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡匈仗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年瓢剿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悠轩。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡间狂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出火架,到底是詐尸還是另有隱情鉴象,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布何鸡,位于F島的核電站纺弊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骡男。R本人自食惡果不足惜淆游,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隔盛。 院中可真熱鬧犹菱,春花似錦、人聲如沸骚亿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽来屠。三九已至虑椎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間俱笛,已是汗流浹背捆姜。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留迎膜,地道東北人泥技。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像磕仅,于是被迫代替她去往敵國和親珊豹。 傳聞我的和親對象是個殘疾皇子簸呈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360