• D3.js系列——布局:打包图和地图


    一、打包图

      打包图( Pack ),用于表示包含与被包含的关系,也可表示各对象的权重,通常用一圆套一圆来表示前者,用圆的大小来表示后者。

    1、布局(数据转换)

    var pack = d3.layout.pack()
                .size([ width, height ])
                .radius(20);

      第 1 行:打包图的布局
      第 2 行:size() 设定转换的范围,即转换后顶点的坐标(x,y),都会在此范围内。
      第 3 行:radius() 设定转换后最小的圆的半径。

      读取数据并转换的代码

    d3.json("city2.json", function(error, root) {
            var nodes = pack.nodes(root);
            var links = pack.links(nodes);
            
            console.log(nodes);
            console.log(links);
    }

      上面用 pack 函数分别将数据转换成了顶点 nodes 和 连线 links。来看看顶点数据被转换成了什么样:

      数据被转换后,多了深度信息(depth),半径大小(r),坐标位置(x,y)等。打包图无需对连线进行绘制。

      注意:无论用什么 Layout 来转换数据,一定要先看转换后的数据是什么再绘制,否则很容易出错。

    2、绘制

      绘制的内容有圆和文字,都在 SVG 中绘制。实例代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>vue生命周期学习</title>
      <script src="d3.min.js"></script>
    </head>
    <body>
    </body>
    <script>
    //准备画布
    var width=500,height=500;
    var svg = d3.select("body").append("svg").attr("width",width).attr("height",height);
    //布局
    var pack = d3.layout.pack().size([width,height]).radius(20);
    //读取数据并转换数据
    d3.json('city2.json',function(error,root){
        var nodes = pack.nodes(root);
        var links = pack.links(nodes);
        console.log(nodes,links);
        //画圆
        svg.selectAll("circle")
        .data(nodes)
        .enter()
        .append("circle")
        .attr("fill","rgb(31, 119, 180)")
        .attr("fill-opacity","0.4")
        .attr("cx",function(d){
            return d.x;
        })
        .attr("cy",function(d){
            return d.y;
        })
        .attr("r",function(d){
            return d.r;
        })
        .on("mouseover",function(d,i){
            d3.select(this).attr("fill","yellow")
        })
        .on("mouseout",function(d,i){
            d3.select(this).attr("fill","rgb(31, 119, 180)");
        });
        //给文本
        svg.selectAll("text")
        .data(nodes)
        .enter()
        .append("text")
        .attr("font-size","10px")
        .attr("fill","white")
        .attr("fill-opacity",function(d){
            if(d.depth == 2)
                return "0.9";
            else
                return "0";
        })
        .attr("x",function(d){ return d.x; })
        .attr("y",function(d){ return d.y; })
        .attr("dx",-12)
        .attr("dy",1)
        .text(function(d){ return d.name; });
    })
    </script>
    </html>

    二、地图

      在数据可视化中,地图是很重要的一部分。很多情况会与地图有关联,如中国各省的人口多少,GDP多少等,都可以和地图联系在一起。

      将 JSON 的格式应用于地理上的文件,叫做 GeoJSON 文件。本文就是用这种文件绘制地图。

    1、投影函数

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

      由于 GeoJSON 文件中的地图数据,都是经度和纬度的信息。它们都是三维的,而要在网页上显示的是二维的,所以要设定一个投影函数来转换经度纬度。如上所示,使用 d3.geo.mercator() 的投影方式。

      第 2 行:center() 设定地图的中心位置,[107,31] 指的是经度和纬度。
      第 3 行:scale() 设定放大的比例。
      第 4 行:translate() 设定平移。

    2、地理路径生成器

      为了根据地图的地理数据生成 SVG 中 path 元素的路径值,需要用到 d3.geo.path(),我称它为地理路径生成器

    var path = d3.geo.path()
        .projection(projection);

      projection() 是设定生成器的投影函数,把上面定义的投影传入即可。以后,当使用此生成器计算路径时,会自己加入投影的影响。

    3、向服务器请求文件并绘制地图

    <html>  
      <head>  
            <meta charset="utf-8">  
            <title>中国地图</title>  
      </head>
    <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 color = d3.scale.category20();
        
        d3.json("china.geojson", function(error, root) {
            if (error) 
                return console.error(error);
            console.log(root.features);
            
            svg.selectAll("path")
                .data( root.features )
                .enter()
                .append("path")
                .attr("stroke","#000")
                .attr("stroke-width",1)
                .attr("fill", function(d,i){
                    return color(i);
                })
                .attr("d", path )
                .on("mouseover",function(d,i){
                    d3.select(this)
                        .attr("fill","yellow");
                })
                .on("mouseout",function(d,i){
                    d3.select(this)
                        .attr("fill",color(i));
                });
        });
    </script>
    </body>
    </html> 

      再次声明:d3.json() 不能直接读取本地文件,因此你需要搭建一个服务器,例如 Apache。但是在火狐浏览器是可以直接读取的。

      接下来,就是给 svg 中添加 path 元素。本例中,每一个 path 表示一个省。要注意 attr(“d”,path) 这一行代码,它相当于:

    .attr("d",funtion(d){
        return path(d);
    })
  • 相关阅读:
    Java设计模式知识整理
    Java单例实现及分析
    Java开源框架知识整理
    JavaJ2EE相关知识整理
    数据库相关知识整理
    JavaJDK8新特性相关知识整理
    Java并发编程相关知识整理
    Java集合框架相关知识整理
    Java虚拟机JVM相关知识整理
    若依项目利用nginx实现负载均衡及保持会话
  • 原文地址:https://www.cnblogs.com/goloving/p/8618825.html
Copyright © 2020-2023  润新知