• 【 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

        感谢您的阅读。

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

  • 相关阅读:
    .NET 7.0 Preview 6、.NET 6.0.7、.NET Core 3.1.27 和 Visual Studio 2022 17.3 预览版也发布了
    Dapr中国社区活动之 分布式运行时开发者日 (2022.09.03)
    .NET MAUI 社区工具包 1.3版本发布
    .NET 7 SDK 开始 支持构建容器化应用程序
    Unity 将是驱动 C# 增长的引擎吗 ?
    .NET 7 RC 2 发布,倒计时一个月发布正式版
    SqlKata 方便好用的 Sql query builder
    开源数字基础设施 项目 Speckle
    使用autok3s 安装k3s 集群 和 kuboard 管理集群
    Dapr 证书过期了怎么办? 别慌,有救!
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4667383.html
Copyright © 2020-2023  润新知