歷經千辛萬苦,終於把這地圖給作出來了,可是。。。emm,很醜,有不少須要優化的地方,這個地圖一開始一直在antv L7的實例中找,沒有找到,通過查找資料,參考這篇博客才頓悟,原來能夠獲取中國地圖的數據,作一個圖表,如下是個人思路:css
htmlhtml
<div id='map'></div> 複製代碼
css,g2-tooltip和 g2-tooltip-list是官網複製的樣式,是當鼠標滑過是顯示的div的樣式jquery
<style> .labelclass { width: 50px; height: 50px; border-radius: 50%; color: #9c0a0d; text-align: center; line-height: 50px; } .g2-tooltip{ position: absolute; visibility: hidden; border: 1px solid #efefef; background-color: white; color: #000; opacity: 0.8; padding: 5px 15px; transition: top 200ms,left 200ms; } .g2-tooltip-list{ margin: 10px; } </style> 複製代碼
引入須要的js文件ajax
<script src="jquery-3.4.1.min.js"></script> <script src="https://gw.alipayobjects.com/os/lib/antv/g2/3.4.10/dist/g2.min.js"></script> <script src="https://unpkg.com/@antv/data-set"></script> 複製代碼
爲了不回調地獄混亂思路,我封裝了promise類型的ajaxjson
function $get(url) { return new Promise((resolve, rejected) => { $.get(url, res => { resolve(res) }) }) } 複製代碼
封裝getColor函數,判斷數據的區域獲得不一樣的顏色api
function getColor(v) { const trend = ['#ffefd7', '#ffd2a0', '#fe8664', '#e64b47', '#c91014', '#9c0a0d',]; return v > 9999 ? trend[5] : v > 999 ? trend[4] : v > 499 ? trend[3] : v > 99 ? trend[2] : v > 9 ? trend[1] : trend[0]; } 複製代碼
先來作地圖的框架數組
let mapData = await $get('https://geo.datav.aliyun.com/areas/bound/100000_full.json') var chart = new G2.Chart({ container: 'map', height: 1000, width: 1000, padding: [55, 20] }); chart.scale({ //sync:當 chart 存在不一樣數據源的 view 時,用於統一相同數據屬性的值域範圍 //nice:默認爲 true,用於優化數值範圍,使繪製的座標軸刻度線均勻分佈。例如原始數據的範圍爲 [3, 97],若是 nice 爲 true,那麼就會將數值範圍調整爲 [0, 100] x: { sync: true, nice: false }, y: { sync: true, nice: false } }) //chart.coord().reflect('' | 'x' | 'y'): 座標系轉置,將 x 或者 y 的起始、結束值倒置。 chart.coord().reflect(); chart.axis(false); //處理數據 var ds = new DataSet(); // createView建立並返回一個數據視圖實例 var dv = ds.createView('back') .source(mapData, { type: 'GeoJSON' }) .transform({ //geo.projection 地理映射 type: 'geo.projection', projection: 'geoMercator', as: ['x', 'y', 'centroidX', 'centroidY'] }); //繪製地圖 var bgView = chart.view(); bgView.source(dv); bgView.polygon() .position('x*y') .style({ fill: '#000088',//地圖顏色 stroke: '#b1b1b1',//界線顏色 lineWidth: 0.5,//線粗細 fillOpacity: 1 }) 複製代碼
好了,地圖框架出來了promise
接下來要將疫情數據導出到圖表上,我是從網站上獲得的數據,因此還要進行處理bash
let res = await $get('http://lovebridge.migu.cn:18188/api/map?url=http:%2F%2Fgarnetcdn.migu.cn%2Flovebridge.html') res = res.data.country[0].province//處理數據,獲得一個數組 複製代碼
將疫情數據和地圖串聯起來,只能經過地名,可是疫情書籍裏地名沒有顯示市、省,因此我用了find和slice方法,找到對應的對象,處理我須要的數據markdown
//處理疫情數據,顯示數據 var userData = ds.createView().source(res) userData.transform({ //數據轉換,type至關於數組轉換的方法 type: 'map', //因爲我從網上得到的數據中市省都去掉了,因此我經過查找匹配前兩個字符同樣的獲得經緯度 callback: function (obj, index) { let one = dv.rows.find(item => { return item.name.slice(0, 2) === obj.na.slice(0, 2) }) obj.x = one.centroidX * 1; obj.y = one.centroidY * 1; obj.data = parseInt(obj.tn.split(',')[0]) one.data = obj.data return obj; } }); //以下是數據顯示及樣式 var pointView = chart.view(); pointView.source(userData); pointView.intervalStack() .position('x*y').label('na', { offset: -5, textStyle: { fontSize: 10, fill: '#000', }, formatter: (text, item) => { const d = item.point; return d.na + '\n' + d.data; } }) 複製代碼
須要按確診人數的數量來讓不一樣區域顯示相應的顏色,我前面已經將數據存在userData上了
bgView.polygon().position('x*y').color('data', getColor)//傳入回調函數,使不一樣的數據顯示不同的背景顏色 複製代碼
當鼠標劃過期,顯示相應的數據,只有chart有tooltip方法
chart.tooltip({ showTitle: false, // 默認標題不顯示 containerTpl: `<div class="g2-tooltip"><ul class="g2-tooltip-list"></ul> </div>`, itemTpl: '<li >確診{value}例</li>' }) 複製代碼
取消動畫,將圖表渲染至畫布
chart.animate(false) chart.render(); 複製代碼
成品
下面是總的js代碼
function $get(url) { return new Promise((resolve, rejected) => { $.get(url, res => { resolve(res) }) }) } function getColor(v) { const trend = ['#ffefd7', '#ffd2a0', '#fe8664', '#e64b47', '#c91014', '#9c0a0d',]; return v > 9999 ? trend[5] : v > 999 ? trend[4] : v > 499 ? trend[3] : v > 99 ? trend[2] : v > 9 ? trend[1] : trend[0]; } async function aa() { let mapData = await $get('https://geo.datav.aliyun.com/areas/bound/100000_full.json') var chart = new G2.Chart({ container: 'map', // forceFit: true, height: 1000, width: 1000, padding: [55, 20] }); // // force sync scales chart.scale({ //sync:當 chart 存在不一樣數據源的 view 時,用於統一相同數據屬性的值域範圍 //nice:默認爲 true,用於優化數值範圍,使繪製的座標軸刻度線均勻分佈。例如原始數據的範圍爲 [3, 97],若是 nice 爲 true,那麼就會將數值範圍調整爲 [0, 100] x: { sync: true, nice: false }, y: { sync: true, nice: false } }) //chart.coord().reflect('' | 'x' | 'y'): 座標系轉置,將 x 或者 y 的起始、結束值倒置。 chart.coord().reflect(); chart.axis(false); //處理數據,繪製地圖 var ds = new DataSet(); // createView建立並返回一個數據視圖實例 var dv = ds.createView('back') .source(mapData, { type: 'GeoJSON' }) .transform({ //geo.projection 地理映射 type: 'geo.projection', projection: 'geoMercator', as: ['x', 'y', 'centroidX', 'centroidY'] }); var bgView = chart.view(); bgView.source(dv); bgView.polygon() .position('x*y') .style({ fill: '#000088',//地圖顏色 stroke: '#b1b1b1',//界線顏色 lineWidth: 0.5,//線粗細 fillOpacity: 1 }) .color('data', getColor)//傳入回調函數,使不一樣的數據顯示不同的背景顏色 let res = await $get('http://lovebridge.migu.cn:18188/api/map?url=http:%2F%2Fgarnetcdn.migu.cn%2Flovebridge.html') res = res.data.country[0].province//處理數據,獲得一個數組 //處理疫情數據,顯示數據 var userData = ds.createView().source(res) userData.transform({ //數據轉換,type至關於數組轉換的方法 type: 'map', //因爲我從網上得到的數據中市省都去掉了,因此我經過查找匹配前兩個字符同樣的獲得經緯度 callback: function (obj, index) { let one = dv.rows.find(item => { return item.name.slice(0, 2) === obj.na.slice(0, 2) }) obj.x = one.centroidX * 1; obj.y = one.centroidY * 1; obj.data = parseInt(obj.tn.split(',')[0]) one.data = obj.data return obj; } }); //以下是數據顯示及樣式 var pointView = chart.view(); pointView.source(userData); pointView.intervalStack() .position('x*y').label('na', { offset: -5, textStyle: { fontSize: 10, fill: '#000', }, formatter: (text, item) => { const d = item.point; return d.na + '\n' + d.data; } }) //圖例顯示在右邊 chart.legend('data', { position: 'right', }) //當鼠標劃過期,顯示相應的數據,只有chart有tooltip方法 chart.tooltip({ showTitle: false, // 默認標題不顯示 containerTpl: `<div class="g2-tooltip"><ul class="g2-tooltip-list"></ul> </div>`, itemTpl: '<li >確診{value}例</li>' }) chart.animate(false) chart.render(); } aa() 複製代碼