1. 程式人生 > >d3js製作可拖動地圖

d3js製作可拖動地圖

效果圖



原始碼

<html>
<head>  
        <meta charset="utf-8">  
        <title>Map Force</title>  
  </head> 
<style>

.link {
	stroke: #ccc;
	stroke-width: 1;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
	var width  = 1000;
	var height = 1000;
	
	var svg = d3.select("body").append("svg")
	    .attr("width", width)
	    .attr("height", height)
	    .append("g")
	    .attr("transform", "translate(0,0)");
	
	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();
	
	d3.json("china_simplify.json", function(error, root) {
		
		if (error) 
			return console.error(error);
		console.log(root.features);
		
		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] ) );
		});
		
		console.log(nodes);
		console.log(links);
		
		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; } );
		
		 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 + ")";
			   });
		});
		
		
	});
		
	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)
		};
	}

</script>
	
</body>  
</html>