React + d3绘制疫情地图

1,840 阅读3分钟

全球疫情仍在持续之中,虽然国内情况正在日渐好转,但国外疫情却愈演愈烈。大家应该

每天都会查看疫情地图来了解世界各地的疫情情况,那如何使用前端知识来绘制我们自己的疫情地图呢。

首先我们创建一个react组件,在其render函数中返回一个svg元素

然后在componentDidMount生命周期方法中选择此svg元素并定义其宽高

这里在d3.select方法内部传入svg标签的id值来取到render方法定义的svg标签,然后通过attr方法定义其宽高。

然后componentDidMount内部调用了三个方法,分别用来绘制主地图,legend和南海诸岛。

现在让我们来看一下renderMainLand方法内部都做了些什么

这里我们现在svg内部创建一个g标签用来作为所有将要绘制的元素的容器。使用d3.geoMercator创建莫托卡投影,然后定义其中心center(这里传入中心位置经纬度),缩放比例scale和中心位置相对svg的偏移(传入svg元素的半宽和半高使中心经纬度定在svg元素的中心)

接下来创建path路径元素,这里使用selectAll('path').data().enter().append('path)模板代码来创建足够的路径元素,data内部传入一个数组,当g元素内部path元素数量不够时,会自动创建若干数量的path使其数量与data数组的长度相等。data方法内部传入的数据是从网上(datav.aliyun.com/tools/atlas)下载的中国地图的geojson。再后面便是定义每个path元素的填充颜色,边颜色。

绘制path元素填充元素时使用了这个一个颜色配置,后面绘制legend时也会用到这个配置。

上面的代码便是绘制每个省份名称的代码,这里仍然使用模板代码创建足够多个text元素。在定义偏移transform时,需要取出geojson中定义的各个省的中心坐标,然后通过其坐标值进行相应偏移便可将各省名称绘制在每个省的中心位置。

这样中国主地图便绘制完成,让我们看一下效果

疫情地图的legend代表了颜色与人数之间的关系

创建legend方法内部先创建一个容器元素g。然后根据颜色配置中的颜色数量在该容器元素中创建足够多的g元素用来包含legend的颜色块与文字部分。接下来在内部的g元素中分别创建rect和text元素代表颜色块与文字,并调整它们之间的位置关系。最终调整外层g元素的位置使其定位在svg的左下角。

主地图和legend都已绘制完成,接下来绘制南海诸岛。南海诸岛的地图是使用一个矩形绘制在主地图旁边。在这里我使用的方法是单独绘制一个矩形和南海诸岛的地图,然后将它们偏移到相应位置使它们看起来就像是一个元素。代码如下

前面绘制南海诸岛的代码和绘制主地图基本相同,只是使用不同的geojson(由于网上无法单独下载南海诸岛的json文件,这里我在中国的geojson里取到应该显示的省份并过滤掉较高的维度,便生成了可绘制的json文件)

地图绘制完毕,现在就来看一下最终效果吧