【 D3.js 入门系列 --- 10 】 地图的绘制
本人的个人博客为:www.ourd3js.com
csdn博客为:blog.csdn.net/lzhlzz
转载请注明出处,谢谢。
地图的制作在 D3 中可以说是最重要的一环。因为在进行数据可视化时,很多情况都会和地图联系在一起,如中国各省的人口多少,GDP多少等,都可以和地图联系在一起。
D3 中制作地图所需要的文件问 JSON 文件。JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。关于 JSON 的语法格式,可以在:
http://www.w3school.com.cn/json/
学习。将 JSON 的格式应用于地理上的文件,叫做 GeoJSON 文件。本节就是用这种文件绘制地图。
那么如何获得中国地图的 GeoJSON 文件呢,这其实真的有点麻烦,可以参照: https://github.com/clemsos/d3-china-map 进行制作,这不仅需要安装一些东西,还要研究一下制作方法,对想直接下载获取中国地图的 GeoJSON 文件的朋友可能感觉很不舒服,呵呵,其实我也是这样。
好吧,我辛苦一点,将制作好的中国地图放上来与大家分享。
中国地图的 GeoJSON 文件: china.json
这个文件是用 Natural Earth 上的数据,经过提取后制作而成,我还去掉了很多无用的信息,只保留的中国的各省份的名字和 id 号,在这里先感谢 Natural Earth 提供的数据。接下来我还会提取其他各个国家的数据,放到个人博客中供大家分享,希望能省去大家的时间,因为这个部分真的很麻烦。对于只希望进行可视化的朋友来说,估计不想做这个工作。后续制作好的各种 GeoJSON 文件,都会放到 OUR D3.JS 小站中,请关注。
好了,废话不说了。开始用 D3 来绘制地图吧。绘制分为三步:
1. 设定投影函数
var projection = d3.geo.mercator() .center([107, 31]) .scale(850) .translate([width/2, height/2]);由于 GeoJSON 文件中的地图数据,都是经度和纬度的信息,它们都是三维的。要在网页上显示的是二维的,所以要设定一个投影函数来转换经度纬度。如上所示,我们用 d3.geo.mercator() 的投影方式。关于各种投影方式的函数,可以参考: https://github.com/mbostock/d3/wiki/Geo-Projections
center() 函数是用于设定地图的中心位置,[107,31] 指的是经度和纬度。
scale() 函数用于设定放大的比例。
translate() 函数用于设定平移。
2. 设定 path 函数
var path = d3.geo.path() .projection(projection);将上面的投影函数,作为参数,放入 path 中。这个 path 函数后面在绘制的时候就会用于转换经度纬度为平面信息,用于绘制。
3. 读取文件并绘制
d3.json("china.json", function(error, root) { if (error) return console.error(error); console.log(root.features); svg.selectAll("path") .data( root.features ) .enter() .append("path") .attr("stroke","#000") .attr("stroke-width",1) .attr("fill", function(d,i){ return color(i); }) .attr("d", path ) .on("mouseover",function(d,i){ d3.select(this) .attr("fill","yellow"); }) .on("mouseout",function(d,i){ d3.select(this) .attr("fill",color(i)); }); });和上几节一样,用 d3.json 读取文件。请注意,再次声明一下,这个函数的调用需要你搭建一个服务器。接下来,就是给 svg 中添加 path。要注意 attr("d",path) 这一行代码,前面也说过,这个其实相当于:
.attr("d",funtion(d){ return path(d); })请一定要注意这种省略用法。这里是有点难理解的。
好了,看结果吧。
我们的国家就被绘制出来了。要看完整代码和试试互操作的朋友,请点击下面链接查看,把鼠标放上去会有变色效果:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。