前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【D3使用教程】(4) 添加数轴

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

作者头像
前端修罗场
发布2023-10-07 17:13:03
2100
发布2023-10-07 17:13:03
举报
文章被收录于专栏:Web 技术Web 技术
(1)设置数轴

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

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

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

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

代码语言:javascript
复制
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类。

代码语言:javascript
复制
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变换:

代码语言:javascript
复制
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轴。

代码语言:javascript
复制
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)优化 为了证明新坐标轴是可动态伸缩的,我们把静态的数据集改成随机生成的:

代码语言:javascript
复制
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把数值当成百分比,同时保留一位小数等等。

代码语言:javascript
复制
let formatAsPercentage = d3.format(".1%");
xAxis.tickFormat(formatAsPercentage);

##(5)附完整代码

代码语言:javascript
复制
<!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>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (2)修整数轴
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档