• D3基础---比例尺


    转载请注明出处!

    比例尺简述:

    比例尺是一组把输入域映射到输出范围的函数。

    一般来说数据集中的值不可能恰好与图表中的像素尺度一一对应。比例尺就是把这些数据值映射到可视化图形中使用的新值的便捷手段。

    D3的比例尺就是那些你定义的带有参数的函数。

    听到比例尺有些人就会想到最终图表中一系列的刻度线,对应一系列的值,不要搞错,这些刻度显示坐标轴的一部分,而坐标轴只是比例尺的一种形象的表示。比例尺实际上代表的是一种数学关系,不可能直接输出可见的图形。比例尺和坐标轴是两种不同但相关的东西。

    下面我们只讨论线性比例尺。

    值域和范围:

    比例尺的输入值域(input domain)指的是可能的输入值的范围。

    比例尺的输出范围(output range)指的是输出值的可能范围。

    其实就是归一化,对于线性比例尺,d3可以帮助我们处理归一化过程的数学计算:输入值根据值域先进行归一化,然后再把归一化后的值对应到输出范围。

    创建比例尺:

    1 var scale = d3.scale.linear()
    2 
    3                .domain([100, 500])
    4 
    5                .range([10, 350]);

    例如:

    scale(100)输出是10,scale(300)输出是180…

    缩放散点图:

    var dataset = [  

                                [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],  

                                [410, 12], [475, 44], [25, 67], [85, 21], [220, 88]  

                              ];  

    返回所有坐标中X值中最大的:

    1 d3.max(dataset, function(d) {    //返回 480
    2 
    3     return d[0];             //每一个子数组中的第一个位置的值
    4 
    5 });

    X轴缩放:

    1 var xScale = d3.scale.linear()
    2 
    3                 .domain([0, d3.max(dataset, function(d) { return d[0]; })])
    4 
    5                 .range([0, w]);

    Y轴缩放:

    1 var yScale = d3.scale.linear()
    2 
    3                 .domain([0, d3.max(dataset, function(d) { return d[1]; })])
    4 
    5                 .range([0, h]);

    设定圆心的坐标(注意使用和坐标同样缩放尺度的坐标值):

    .attr("cx", function(d) {

        return d[0];

    })

    缩放后的坐标X值:

    1 .attr("cx", function(d) {
    2 
    3     return xScale(d[0]);
    4 
    5 })

    Y值同样如此:

    .attr("cy", function(d) {

        return d[1];

    })

    缩放后的坐标Y值:

    1 .attr("cy", function(d) {
    2 
    3     return yScale(d[1]);
    4 
    5 })

    设定文本坐标值(同上):

    .attr("x", function(d) {

        return d[0];

    })

    .attr("y", function(d) {

        return d[1];

    })

    变成:

     1 .attr("x", function(d) {
     2 
     3     return xScale(d[0]);
     4 
     5 })
     6 
     7 .attr("y", function(d) {
     8 
     9     return yScale(d[1]);
    10 
    11 })

    源代码:

      1 <!DOCTYPE html>  
      2 
      3 <html>  
      4 
      5   <head>  
      6 
      7         <meta charset="utf-8">  
      8 
      9         <title>testD3-10-scale.html</title>  
     10 
     11         <script type="text/javascript" src="d3.v3.js"></script>  
     12 
     13     <style type="text/css">  
     14 
     15         </style>  
     16 
     17     </head>  
     18 
     19     <body>  
     20 
     21         <script type="text/javascript">  
     22 
     23 //Width and height  
     24 
     25             var w = 500;  
     26 
     27             var h = 100;  
     28 
     29               
     30 
     31             var dataset = [  
     32 
     33                             [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],  
     34 
     35                             [410, 12], [475, 44], [25, 67], [85, 21], [220, 88]  
     36 
     37                           ];  
     38 
     39   
     40 
     41             //Create scale functions  
     42 
     43             var xScale = d3.scale.linear()  
     44 
     45                                  .domain([0, d3.max(dataset, function(d) { return d[0]; })])  
     46 
     47                                  .range([0, w]);  
     48 
     49   
     50 
     51             var yScale = d3.scale.linear()  
     52 
     53                                  .domain([0, d3.max(dataset, function(d) { return d[1]; })])  
     54 
     55                                  .range([0, h]);  
     56 
     57       
     58 
     59             //Create SVG element  
     60 
     61             var svg = d3.select("body")  
     62 
     63                         .append("svg")  
     64 
     65                         .attr("width", w)  
     66 
     67                         .attr("height", h);  
     68 
     69   
     70 
     71             svg.selectAll("circle")  
     72 
     73                .data(dataset)  
     74 
     75                .enter()  
     76 
     77                .append("circle")  
     78 
     79                .attr("cx", function(d) {  
     80 
     81                     return xScale(d[0]);  
     82 
     83                })  
     84 
     85                .attr("cy", function(d) {  
     86 
     87                     return yScale(d[1]);  
     88 
     89                })  
     90 
     91                .attr("r", function(d) {  
     92 
     93                     return Math.sqrt(h - d[1]);  
     94 
     95                });  
     96 
     97   
     98 
     99             svg.selectAll("text")  
    100 
    101                .data(dataset)  
    102 
    103                .enter()  
    104 
    105                .append("text")  
    106 
    107                .text(function(d) {  
    108 
    109                     return d[0] + "," + d[1];  
    110 
    111                })  
    112 
    113                .attr("x", function(d) {  
    114 
    115                     return xScale(d[0]);  
    116 
    117                })  
    118 
    119                .attr("y", function(d) {  
    120 
    121                     return yScale(d[1]);  
    122 
    123                })  
    124 
    125                .attr("font-family", "sans-serif")  
    126 
    127                .attr("font-size", "11px")  
    128 
    129                .attr("fill", "red");  
    130 
    131         </script>  
    132 
    133   
    134 
    135     </body>  
    136 
    137 </html>  
    138 
    139  

    修饰图表:

    点大小与圈大小成正比,想把大的放在下面,只要改变Y轴值域倒转即可: .range([h , 0]);

    有些圆形的边缘会被切掉一部分,为此引入一个边距变量:

    var padding = 20;

    以便在设置两个比例尺的时候加入边距,边距可以把圆形往里推,使他们远离SVG的四边,从而避免被切掉。

    xScale的返回改为:.range([padding, w-padding]);

    但右边的文本仍然会被切掉,可以增大边距2*padding。

    原来我们是把每个圆形的半径设置为y值的平方根,现在,我们同样可以为半径设置一个比例尺:

    1 var rScale = d3.scale.linear()
    2 
    3                       .domain([0, d3.max(dataset,function(d) {
    4                                 return d[1];
    5 })])
    6                       .rangeRound([2, 5]);

    然后再这样设定圆的半径:

    1 .attr("r", function(d) {
    2                            return rScale(d[1]);
    3                         });

    这样所有远的半径就永远介于2~5之间。

    其他方法:

    nice():

    告诉比例尺取得range()设置的任何值域,把两端的值扩展到最接近的整数。“For example, for a domain of [0.20147987687960267, 0.996679553296417], the nice domain is [0.2, 1].”

    rangeRound():

    代替range之后,比例尺输出的所有值都会舍入到最接近的整数值。对输出值取整有助于图形对应精确地像素值,避免边缘出现模糊不清的锯齿。

    clamp():

    默认情况下,比例尺可以返回指定范围之外的值。比如,假设给定的值位于输入值域之外,那么比例尺也会返回一个位于输出范围之外的值。调用clamp之后就会强行所有输出值都要在指定范围内。意味着超出范围,会取整到范围的最大值或最小值。

    源代码微调:

      1 <!DOCTYPE html>
      2 
      3 <html lang="en">
      4 
      5          <head>
      6 
      7                    <title>D3: Linear scales with a scatterplot</title>
      8 
      9                    <script type="text/javascript" src="../d3/d3.js"></script>
     10 
     11                    <style type="text/css">
     12 
     13                             /* No style rules here yet */            
     14 
     15                    </style>
     16 
     17          </head>
     18 
     19          <body>
     20 
     21                    <script type="text/javascript">
     22 
     23                             var w = 500;
     24 
     25                             var h = 300;
     26 
     27                             var padding = 20;
     28 
     29                            
     30 
     31                             var dataset = [
     32 
     33                                                                  [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
     34 
     35                                                                  [410, 12], [475, 44], [25, 67], [85, 21], [220, 88], [600, 150]
     36 
     37                                                           ];
     38 
     39  
     40 
     41                             //create scales function
     42 
     43                             var xScale = d3.scale.linear()
     44 
     45                                                                            .domain([0, d3.max(dataset,function
     46 
     47                                                                                     (d) {return d[0];})])
     48 
     49                                                                            .rangeRound([padding,w-padding*2]);
     50 
     51                             var yScale = d3.scale.linear()
     52 
     53                                                                            .domain([0, d3.max(dataset,function
     54 
     55                                                                                     (d) {return d[1];})])
     56 
     57                                                                            .rangeRound([h-padding,padding]);
     58 
     59                             var rScale = d3.scale.linear()
     60 
     61                                                                            .domain([0, d3.max(dataset,function
     62 
     63                                                                                     (d) {return d[1];})])
     64 
     65                                                                            .rangeRound([2, 5]);
     66 
     67  
     68 
     69                             //create SVG element
     70 
     71                             var svg = d3.select("body")
     72 
     73                                                         .append("svg")
     74 
     75                                                         .attr("width", w)
     76 
     77                                                         .attr("height", h);
     78 
     79  
     80 
     81                             //create circles
     82 
     83                             svg.selectAll("circle")
     84 
     85                                      .data(dataset)
     86 
     87                                      .enter()
     88 
     89                                      .append("circle")
     90 
     91                                      .attr("cx", function(d) {  
     92 
     93                                                return xScale(d[0]);
     94 
     95                                      })
     96 
     97                                      .attr("cy", function(d) {
     98 
     99                                               return yScale(d[1]);
    100 
    101                                      })
    102 
    103                                      .attr("r", function(d) {
    104 
    105                                            return rScale(d[1]);
    106 
    107                                });
    108 
    109  
    110 
    111                             //create text elements
    112 
    113                             svg.selectAll("text")
    114 
    115                                      .data(dataset)
    116 
    117                                      .enter()
    118 
    119                                      .append("text")
    120 
    121                                      .text(function(d){
    122 
    123                                                return d[0] + "," + d[1];
    124 
    125                                      })
    126 
    127                                      .attr("x", function(d) {
    128 
    129                                            return xScale(d[0]);
    130 
    131                                })
    132 
    133                                .attr("y", function(d) {
    134 
    135                                            return yScale(d[1]);
    136 
    137                                })
    138 
    139                                .attr("font-family", "sans-serif")
    140 
    141                                .attr("font-size", "11px")
    142 
    143                                .attr("fill", "red");
    144 
    145                    </script>
    146 
    147          </body>
    148 
    149 </html>

    效果图:

     

    For my lover, CC!

    参考书籍:《数据可视化实战》

  • 相关阅读:
    27. 移除元素-数组-简单
    26. 删除排序数组中的重复项-数组-简单
    25. K 个一组翻转链表-链表-困难
    24. 两两交换链表中的节点-链表、递归-中等难度
    23. 合并K个排序链表-链表-困难
    21. 合并两个有序链表-链表-简单
    20. 有效的括号-栈-简单
    19. 删除链表的倒数第N个节点-链表-中等难度
    17. 电话号码的字母组合-dfs-中等难度
    16. 最接近的三数之和-dfs-中等难度
  • 原文地址:https://www.cnblogs.com/ttcc/p/3878263.html
Copyright © 2020-2023  润新知