D3力導向地圖製作

製作一箇中國地圖的力導向地圖,支持鼠標拖拽,省份作爲節點,連線用三角剖分生成。

訪問地址:http://106.14.147.72/Graphtest/forcemap.html

效果圖:
這裏寫圖片描述

  1. 定義一個力導向佈局、投影和地理路徑生成器
    創建一個力導向佈局,一個墨卡託投影和一個地理路徑生成器
   var width  = 1600;
    var height = 1000;

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

        var force = d3.layout.force()
                    .size([width, height]); 

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

2.請求GeoJSON文件
文件名稱爲China.geojson,保存了中國各省份的地理信息通過d3.json讀入。

var color = d3.scale.category20();


    d3.json("china.geojson", function(error, root) {

        if (error) 
            return console.error(error);
        console.log(root.features);

3.計算節點數組和連線數組

var nodes = [];

        root.features.forEach(function(d, i) {
            //計算省份的中心座標
            var centroid = path.centroid(d);

            //定義兩個變量x和y,保存中心座標
            centroid.x = centroid[0];
            centroid.y = centroid[1];

            //將地理特徵保存在對象裏
            centroid.feature = d;

            //添加到節點數組中
            nodes.push(centroid);
        });



        var voronoi = d3.geom.voronoi()
                            .x(function(d){
                                return d.x;
                            })
                            .y(function(d){
                                return d.y;
                            });

        var links = voronoi.links(nodes);

        console.log(nodes);
        console.log(links);

4.設定力導向佈局的屬性
最重要的是兩節點之間的距離設置,使其節點之間保持適當的位置間隔。

    force.gravity(0)
            .charge(0)
            .linkDistance(function(d){
                var dx = d.source.x - d.target.x;
                var dy = d.source.y - d.target.y;
                return Math.sqrt( dx*dx + dy*dy );
            })
            .nodes(nodes)
            .links(links)
            .start();

5.繪製節點和連線

    var nodeGroups = 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 lines = 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; } );

6.運動更新
當鼠標進行拖拽時,力導向發生作用。

force.on("tick", function() {

            lines.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; });

            nodeGroups.attr("transform", function(d) {
                 return "translate(" + d.x + "," + d.y + ")";
            });
        });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章