zoukankan      html  css  js  c++  java
  • 基于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>
    

    这里写图片描述

  • 相关阅读:
    spring管理hibernate session的问题探究
    【J2EE入门】13个规范
    WCF基础
    初识WCF
    一路风雨,一路收获
    【项目经验】——JSON.parse() && JSON.stringify()
    【项目经验】--EasyUI DataGrid之右键菜单
    NuGet 发布
    【项目经验】之——Controller向View传值
    【项目总结】之——JS分割字符串
  • 原文地址:https://www.cnblogs.com/caojunjie/p/8318879.html
Copyright © 2011-2022 走看看