历经千辛万苦,终于把这地图给作出来了,可是。。。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() 复制代码