数据可视化-中国地图的制作(地图的省级联动)

在数据可视化中,地图是很重要的一部分。很多情况会与地图有关联,如中国各省的人口多少,GDP多少等,都可以和地图联系在一起。

一.地图数据的获取

1.可以参照:https://github.com/clemsos/d3-china-map进行制作

2.联系博主,会给您共享一份地图的JSON数据。

二.地图的制作

第一步:定义画板,并将画板添加到body中

var width  = 1000;
var height = 1000;
var svg = d3.select("body")
	    .append("svg")
	    .attr("width", width)
            .attr("height", height)
	    .attr("transform", "translate(0,0)");

第二步:定义一个投影函数来转换经纬度。因为,地球上的经度和纬度的信息,都是三维的,而要在网页上显示的是二维的,所以要设定一个投影函数来转换经纬度,本文使用d3.geo.mercator()的投影方式。各种投影函数,可以参考: https://github.com/mbostock/d3/wiki/Geo-Projections

var projection = d3.geo.mercator()
		       .center([107, 31])
		       .scale(550)
    		       .translate([width/2, height/2]);

第 2 行:center() 设定地图的中心位置,[107,31] 指的是经度和纬度。

第 3 行:scale() 设定放大的比例。数值越大,地图被放大的比例越大。将数值写在括号中即可。

第 4 行:translate(x,y) 设定平移。第一个参数x为沿x轴移动的距离,第二个参数y为沿y轴移动的距离。

第三步:使用第二步定义出来的投影函数生成路径。projection() 是设定生成器的投影函数,把上面定义的投影传入即可。以后,当使用此生成器计算路径时,会自己加入投影的影响。

var path = d3.geo.path()
		 .projection(projection);

第四步:向服务器请求文件并绘制地图

d3.json("china.geojson", function(error, root) {
		if (error)  return console.error(error);
                svg.selectAll("path")
			.data(root.china.features)
			.enter()
			.append("path")
			.attr("stroke","#000")
			.attr("stroke-width",1)
			.attr("fill", function(d,i){
				return color;
			})
			.attr("fill", "rgba(6,85,178,0.5)")
			.attr("d", path)
			.on("mouseover",function(d,i){
                                d3.select(this)
                                  .attr("fill","yellow");
                        })
                        .on("mouseout",function(d,i){
                               d3.select(this)
                                 .attr("fill","rgba(6,85,178,0.5)");
                        })
                })

结果如图:


再次声明:d3.json() 不能直接读取本地文件,因此你需要搭建一个服务器,例如 Apache。

三.给地图上添加省份的名称

  svg.selectAll("text")
            .data(root.china.features)
            .enter().append("svg:text")
            .text(function (d, i) {
                return d.properties.name
            })           .attr("fill", "rgba(6,85,178,0.5)")
 
            .attr("x", function (d) {
                var local = projection([d.properties.cp[0], d.properties.cp[1]])
                return local[0]
            })
            .attr("y", function (d) {
                var local = projection([d.properties.cp[0], d.properties.cp[1]])
                return local[1]
            })
            .attr("fill", "#04adff")
            .style("font-size", "10px")

注:地图的JSON数据中需要有省份的中心点坐标。结果如下:


四.实现地图的省级联动(即点击某省时出现某个省份的地图)

第一步:给每个省份的路径添加一个属性,属性值为对应的省份名。以便点击时,进行判断,是哪个省份被点击,以及需要调取哪个省份的地图数据。

svg.selectAll("path")
        .attr("tag", function(d){
             return d.properties["name"];
    	})

第二步:添加点击事件

svg.selectAll("path")
   .on("click",function(e){
       if(this.getAttribute('tag')=="黑龙江"){
           d3.json("china.geojson", function(error, root) { //请求黑龙江地区的数据
	       if (error) return console.error(error);
	       svg.selectAll("*").remove(); //清空画板
	           svg.selectAll("path")
		      .data(root.黑龙江.features)
		      .enter()
		      .append("path")
		      .attr("stroke","#000")
		      .attr("stroke-width",1)
		      .attr("fill", "rgba(6,85,178,0.5)")
		      .attr("d", path)
		      .on("mouseover",function(d,i){
		            d3.select(this)
			      .attr("fill","yellow");
		      })
	              .on("mouseout",function(d,i){
			   d3.select(this)
		             .attr("fill","rgba(6,85,178,0.5)");
		      })
				            
	   })
       }   })

五.实现地图上不同区域有不同的着色(如图)

会用到d3中的过滤器,判断数据当中各省份的经纬度,根据经纬度的范围进行着色,具体代码如下:

d3.selectAll("path").filter(function(d,i){
    if(d.properties.id>=31&&d.properties.id<=35&&d.properties.id!=34){
        d3.select(this).attr("fill", function(d,i){
	    return "#03aefe";
	})
    }
})




阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页