【D3使用教程】(4) 添加数轴

简介: 【D3使用教程】(4) 添加数轴

(1)设置数轴

D3的数轴实际商是由程序员自己来定义参数的函数。调用数轴函数,会生成数轴相关的可见元素,包括轴线、标签和刻度 。

使用d3.svg.axis()能创建通用的数轴函数:

var xAxis = d3.svg.axis();

但是你要注意,在使用之前你要告诉这个函数,是基于什么比例尺工作的。例如序数比例尺。

同时,你可以设置标签相对数轴显示的位置,默认出现在轴线的下方。通常而言,水平数轴的位置,可放置在顶部或底部,垂直数轴则要么放在左或者右。

var Axis = d3.svg.axis()
                 .scale(xScale)
                 .orient("bottom");

最后你想要把实际生成的数轴,将其线条和标签插入到SVG中,必须调用xAxis函数。

svg.append("g").call(xAxis);

//在svg标签内,g元素就是一个分组元素。分组元素是不可见的,跟line,rect和circle不一样,但它有两大用途:一是用来包含其他元素;二是对整个分组应用变换,从而影响到该组中所有元素。

//call()在D3中会取得传递过来的元素,然后再把它交给其他函数。对这个例子而言,传递过来的元素就hi新的分组元素g。而call()接着把g交给了xAxis函数,即在g元素内生成数轴。

(2)修整数轴

上面的情况,我们还无法给新创建的g元素赋予样式。

那该怎么做呢?通常情况下,我们可以给g元素指定一个axis类。

svg.append("g")
     .attr("class","axis")
     .call(xAxis);
然后写下样式:
.axis path,
.axis line {
      fill: none;
      stroke:black;
      shape-rendering:crispEdges;
}
.axis text {
     font-size:11px;
}

于是,就这样我们把所有的数轴元素都放在一个g分组中,能够使用CSS选择符.axis 为其中的任何元素应用样式。

从上面的样式可见,数轴本身是由path,line,和text元素组成的。

但是,要注意的是,在给SVG元素应用样式时,要确保应用的属性名是SVG的,而不是CSS的。(SVG属性名参考:https://developer.mozilla.org/en-US/docs/SVG/Attribute)

但是,我们看到这个数轴是在上方。按常理,不是都应该在下面的吗?

此时,我们可以通过SVG变换:

svg.append("g")
     .attr("class","axis")
     .attr("transform","translate(0,"+(h-padding)+")")
     .call(xAxis);
//translate(x,y)这是一个平移变换,上述代码中只是平移了y轴,x轴不变。(h-padding)是把分组的顶边y坐标设置为h,即整个SVG元素的高度,然后再减去我们前面定义的边距值(padding).

我们看到,g元素被加上了一个transform属性。

另外,如果你觉得数轴上的刻度线有些多的话,你还能设置设置刻度线的数量:

在定义数轴时,使用ticks(num)函数,设置数量值。如图:

##(3)垂直数轴

相比水平数轴xAxis,我们可以通过修改其代码,相对于yScale比例尺而定义一个y轴。

let yAxis = d3.svg.axis()
      .scale(yScale)
       .orient("left")
       .ticks(5);
svg.append("g").attr("class","axis").attr("transform","translate("+padding+",0)").call(yAxis);

##(4)优化

为了证明新坐标轴是可动态伸缩的,我们把静态的数据集改成随机生成的:

let dataset = [];
let numDataPoints = 50;
let xRange = Math.random() * 1000;
let yRange = Math.random() * 1000;
for(let i = 0;i<numDataPoints;i++) {
    let newNumber1 = Math.floor(Math.random()* xRange);
    let newNumber2 = Math.floor(Math.random()* yRange);
    dataset.push([newNumber1,newNumber2]);//初始化随机数据集
}

现在我们在来刷新下页面,你会发现每次刷新,都会生成不同的数据集。但是,你也看到数轴会随着输入值域的变化而相应地缩放,刻度和标签也会相应地变化。

另外,我们也可以会刻度上的标签定义样式。利用tickFormat()能为数值应用不同的格式,例如数值保留小数后三位,或显示为百分比等等。如,数值为0.23返回的是23%

但是,使用tickFormat()之前,首先要定义一个新的数值格式函数。通过这个函数可以告诉D3把数值当成百分比,同时保留一位小数等等。

let formatAsPercentage = d3.format(".1%");
xAxis.tickFormat(formatAsPercentage);

##(5)附完整代码

<!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>Document</title>
    <style>
        div.bar {
            display: inline-block;
            width: 20px;
            height: 75px;
            margin-right: 2px;
            background-color: teal;
        }
        .axis path,
    .axis line {
          fill: none;
          stroke:black;
          shape-rendering:crispEdges;
    }
    .axis text {
         font-size:11px;
    }
    </style>
</head>
<body>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    <script src="https://d3js.org/d3.v3.js"></script>
    <script>
        //D3.js code
       let w = 600;
       let h = 200;
       let padding = 30;
       let svg = d3.select("body").append("svg").attr("width",w).attr("height",h);//把append()返回的新元素保存在了变量svg中
        // let dataset = [
        //     [5,20],[480,90],[250,50],[100,33],[330,95],[410,12],[475,44],[25,67],[85,21],[220,88]
        //     ];
       let dataset = [];
       let numDataPoints = 50;
       let xRange = Math.random() * 1000;
       let yRange = Math.random() * 1000;
       for(let i = 0;i<numDataPoints;i++) {
          let newNumber1 = Math.floor(Math.random()* xRange);
          let newNumber2 = Math.floor(Math.random()* yRange);
          dataset.push([newNumber1,newNumber2]);//初始化随机数据集
       }
       let xScale = d3.scale.linear()
                            .domain([0,d3.max(dataset,function(d){return d[0];})])
                            .range([padding,w-padding*2])
                            .nice();//nice()告诉比例尺取得为range()设置的任何值域,把两端的值扩展到最接近的整数。如[0.2000011166,0.99999943]优化为[0.2,1]
        let yScale = d3.scale.linear()
                             .domain([0,d3.max(dataset,function(d){return d[1];})])
                             .range([h-padding,padding])
                             .nice();
        let rScale = d3.scale.linear()
                             .domain([0,d3.max(dataset,function(d){return d[1];})])
                             .range([2,5])
                             .nice();          
        // 数轴
     let xAxis = d3.svg.axis()
               .scale(xScale)
               .orient("bottom")
               .ticks(5); 
     let yAxis = d3.svg.axis()
               .scale(yScale)
               .orient("left")
               .ticks(5);              
        svg.selectAll("circle")
           .data(dataset)
           .enter()
           .append("circle")
           .attr("cx",function(d,i){
                return xScale(d[0]); //返回缩放后的值
           })
           .attr("cy",function(d){
               return yScale(d[1]);
           })
           .attr("r",function(d){
               return rScale(d[1]);
           });
           //添加标签     
            // svg.selectAll("text")
            // .data(dataset)
            // .enter()
            // .append('text')
            // .text(function(d){
            //     return d[0]+ "," + d[1];//设置标签内容
            // })
            // .attr({
            //     fill : "black",
            //     x : function(d) {return xScale(d[0])+10;},//将标签与散点位置一一对应
            //     y : function(d) {return yScale(d[1]);}
            // })
            // .style("font-size", "11px");
       //添加数轴
      svg.append("g")
         .attr("class","axis")
         .attr("transform","translate(0,"+(h-padding)+")")
         .call(xAxis);
      svg.append("g")
         .attr("class","axis")
         .attr("transform","translate("+padding+",0)")
         .call(yAxis);
    </script>
</body>


相关文章
|
6月前
|
测试技术 数据安全/隐私保护
【apipost】使用教程
【apipost】使用教程
116 1
|
JavaScript
NATAPP使用教程(内网穿透)
NATAPP使用教程(内网穿透)
891 0
|
域名解析 安全 应用服务中间件
手把手教你安装WordPress详细教程(图文)
如果还有不了解宝塔面板怎么使用的小伙伴,可以看下我总结的系列教程,保证从新手变老鸟:
1345 0
手把手教你安装WordPress详细教程(图文)
|
6月前
|
Linux 数据安全/隐私保护 Windows
[使用教程]xftp5中文版怎么使用?
[使用教程]xftp5中文版怎么使用?
|
域名解析 弹性计算 Linux
阿里云服务器怎么使用教程?图文操作教程
阿里云服务器怎么使用教程?图文操作教程,使用阿里云服务器快速搭建网站教程,先为云服务器安装宝塔面板,然后在宝塔面板上新建站点,阿里云服务器网以搭建WordPress网站博客为例,来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流程
812 0
|
机器学习/深度学习 决策智能 Windows
CTex完整、详细、亲测安装教程,初步使用教程
CTex完整、详细、亲测安装教程,初步使用教程
1094 0
|
弹性计算 运维 数据可视化
阿里云轻量应用服务器怎么使用?使用教程来了
阿里云轻量应用服务器远程连接教程、轻量服务器开放端口教程、更换操作系统及搭建网站教程
1511 1
阿里云轻量应用服务器怎么使用?使用教程来了
|
搜索推荐
StartAllBack使用教程
StartAllBack, Win11开始菜单增强工具,为Windows11恢复经典样式的Windows7主题风格开始菜单和任务栏,功能包括:自定义开始菜单样式和操作,个性化任务栏及资源管理器等
StartAllBack使用教程
|
监控 数据库
CANape的使用教程
CANape的使用教程
CANape的使用教程
|
iOS开发 MacOS
XMind 2022 使用教程
XMind 2022的安装 XMind 2022的使用 XMind 最新版 思维导图的安装使用 思维导图 XMind 2022的下载 XMind 2022 XMind 2022 Win/Mac 强大的思维导图软件
XMind 2022 使用教程