基於force佈局的map

基於佈局的使用對數據的結構形式要求比較高,所以我們在學習的時候要注意每個佈局所需要的結構,在進行與其他模塊整合的時候就要注意數據的提取轉換,比如說這這篇,1.構造node數據,初始數據是每個省的周邊geo,我們通過path.centroid()—–》拿到中心結點座標,這就是force佈局中的node,同時也要將周邊路徑本身保存進去,因爲我們在基於force繪製node時,要繪製出周邊路徑,不像circle一樣。2.構造links,爲了構造source,target數據,我們需要將每個結點兩兩連接,所以用了泰森多邊形先處理數據,稱爲三角分割,得到一個數據,每個三角形爲一級元素,每個三角形中有三個結點,我們通過將三個結點進行edge方法格式整理成source,target所需要的形式,這樣就有了links。最後綁定nodes與links。

<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]);
    /*路徑生成器加載projection*/
    var path = d3.geo.path()
                    .projection(projection);
    /*設置force導向圖佈局*/
    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);
        console.log(root.features);

這裏寫圖片描述

        var nodes = [];
        var links = [];
        //數組的forEach方法來循環
        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);//將x,y,d本身保存在node中
        });
        console.log(nodes);

這裏寫圖片描述

        /*爲了得到links的數據,用泰森多邊形三角分割處理nodes*/
        var triangles = d3.geom.voronoi().triangles(nodes);
        console.log(triangles)

這裏寫圖片描述

        /*對泰森多邊形處理後,返回一個多邊形數組,每個一級元素中有三個點,就是一個三角形,有每個triangle頂點的座標,我們再取出裏邊的數據進行轉換成links的數據*/
        triangles.forEach(function(d,i){
            links.push( edge( d[0] , d[1] ) );    //每兩兩頂點都做一次連線,放到link是數據中
            links.push( edge( d[1] , d[2] ) );
            links.push( edge( d[2] , d[0] ) );
        });


        console.log(links);

這裏寫圖片描述

        /*配置力導向圖參數*/
        force.gravity(0)
            .charge(0)
            .nodes(nodes)
            .links(links)
            .linkDistance(function(d){ return d.distance; })
            .start();
        /*綁定node數組*/
        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>

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章