【 D3.js 入门系列 --- 10.2 】 你可以拖动地图

简介:

    我的个人博客是:www.ourd3js.com 

    csdn博客为:blog.csdn.net/lzhlzz

    转载请注明出处。谢谢。


    本节是结合9.2节 和10节 的内容制作的一个可力学导向的中国地图,用户能够拖动中国的各个省份。

    数据用的是 10.1节 中简化的中国地图文件: china_simplify.json

    1. 定义各函数

	var projection = d3.geo.mercator()
						.center([107, 31])
						.scale(850)
    					.translate([width/2, height/2]);
	
	var path = d3.geo.path()
					.projection(projection);
	
	var force = d3.layout.force().size([width, height]);
	
	var color = d3.scale.category20();
    projection 函数是用于将三维地图的坐标投影到二维所用的投影函数。详细可见:  10节

    path 函数用于绘制地图路径,里面要传入投影函数 projection 。详细可见: 10节

    force 是定义力学图的 layout 。详细可见: 9.2节

    color 是颜色函数。

    2. 读取数据

d3.json("china_simplify.json", function(error, root) {
		
		if (error) 
			return console.error(error);
		console.log(root.features);
}
    和前几节一样,用 d3.json() 读取文件,后面两句是用于检測错误,以及输出错误信息。

    3. 转换数据

		var nodes = [];
		var links = [];
		
		root.features.forEach(function(d, i) {
			var centroid = path.centroid(d);
			centroid.x = centroid[0];
			centroid.y = centroid[1];
			centroid.feature = d;
			nodes.push(centroid);
		});
		
		var triangles = d3.geom.voronoi().triangles(nodes);
		
		triangles.forEach(function(d,i){
			links.push( edge( d[0] , d[1] ) );
			links.push( edge( d[1] , d[2] ) );
			links.push( edge( d[2] , d[0] ) );
		});
    读取后的文件信息都存在变量 root 中,上面的代码是将 root 中的数据分别转换为力学图所须要的点和线。存在变量 nodes 和 links 中。
    第1-2行: 定义变量 nodes 和 links

    第4-10行: 对于 root.features 中存有每个省的数据, root.features.forEach() 即对每个省的数据。运行后面的无名函数。函数里面是计算出各省的中点,保存在 centroid.x 和 centroid.y 中,再把其它信息赋值给 centroid.feature。最后插入到 nodes 中。

    第12行: 对 nodes 中的顶点进行三角剖分。即用三角形来连接各顶点。结果保存在 triangles 中。

    第14-18行: 将三角形的各边存到 links 变量中。当中的 edge 函数的实现为:

	function edge(a, b) {
		var dx = a[0] - b[0], dy = a[1] - b[1];
		return {
			source: a,
			target: b,
			distance: Math.sqrt(dx * dx + dy * dy)
		};
	}

    4. 绘制地图

		force.gravity(0)
			.charge(0)
			.nodes(nodes)
			.links(links)
			.linkDistance(function(d){ return d.distance; })
			.start();
		
		var node = svg.selectAll("g")
						.data(nodes)
						.enter().append("g")
						.attr("transform", function(d) { return "translate(" + -d.x + "," + -d.y + ")"; })
      					.call(force.drag)
				        .append("path")
				        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
				        .attr("stroke","#000")
				        .attr("stroke-width",1)
				        .attr("fill", function(d,i){
				            return color(i);
				        })
				        .attr("d", function(d){
				        	return path(d.feature);
				        } );
		
		var link = svg.selectAll("line")
						.data(links)
						.enter()
						.append("line")
						.attr("class","link")
						.attr("x1",function(d) { return d.source.x; } )
						.attr("y1",function(d) { return d.source.y; } )
						.attr("x2",function(d) { return d.target.x; } )
						.attr("y2",function(d) { return d.target.y; } );
    第1-6行: 设定 force 的各參数进行设定。
    第8-22行: 绘制各顶点。即中国各省。 当中要注意。第11行和第14行,是全然相反的两个平移函数,不错,这么做就是为了移过去,再移回来,即初始时显示的是各省拼成的完整的地图且显示在最初设定的位置,由于拖拽的过程中变化的量是 d.x 和 d.y 。所以要这么做。

这里有点难理解,请好好体会一下,如有疑问,请在以下留言。另外。第12行是调用 force.drag 函数。

    第24-32行: 绘制连接各省的线条。

    5. 力学图的结合

		 force.on("tick", function() {
			    link.attr("x1", function(d) { return d.source.x; })
			        .attr("y1", function(d) { return d.source.y; })
			        .attr("x2", function(d) { return d.target.x; })
			        .attr("y2", function(d) { return d.target.y; });

			   node.attr("transform", function(d) {
			      return "translate(" + d.x + "," + d.y + ")";
			   });
		});
    这里和  9.2节  一样,tick 指的是时间间隔,也就是每个时间间隔之后就刷新一遍画面。刷新的内容写在后面的无名函数 function 中, function 函数中写上作图的内容。

这里看到了吧。第7-9行里是用于平移的,平移的參数为 d.x 和 d.y 。

    结果图:


    拖动试试吧。哈哈:


    

    自己用鼠标试试吧,点击以下的链接,完整代码请右键点击浏览器后选择查看:

    http://www.ourd3js.com/demo/mapforce.html

    感谢您的阅读。

版权声明:本文博客原创文章,博客,未经同意,不得转载。







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4667383.html,如需转载请自行联系原作者


相关文章
|
1月前
|
JavaScript 前端开发 C语言
javascript基础入门
javascript基础入门
24 1
|
3月前
|
JSON JavaScript 前端开发
Danfo.js专题 - Danfo.js与Dnotebook简介与入门
Danfo.js专题 - Danfo.js与Dnotebook简介与入门
47 0
|
3月前
|
JavaScript
Vue3 + Js 指定位置进行拖动
Vue3 + Js 指定位置进行拖动
|
3月前
|
JSON JavaScript 前端开发
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(下)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
49 2
|
2月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
27 0
|
3月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)(上)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
29 0
|
2月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
74 0
|
3月前
|
JavaScript 前端开发 API
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)(下)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
35 0
|
3月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)(上)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
42 0
|
3月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)(下)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
25 0