坐标轴:
想要系统学习d3.js绘图方法,这里记录一下基础相关教程,更多详尽教程请访问d3官网
坐标轴就是用于回执坐标轴显示的,X轴和Y轴,轴线的组成部分:
- 一条直线,标示轴线
- 一组沿着轴的刻度记号(ticks)
- 每个刻度记号的标签(数字或文字)
通常我们会使用 < g > 这个 svg 的结构标签把整条轴线的元素包在一起,之后对 < g > 元素进行一些操作(例如:移动的时候,就能将整条轴线一起移动。)
-
建立坐标轴的知识点
-
DOM 元素 (path、line、text 等等)
我們必須要有一整組DOM元素,才能绘制出坐标轴 -
比例尺
除了 DOM 元素,也要搭配比例尺去計算出轴线的最大和最小值,才知道轴线要画多长、刻度要怎么计算<div class="demo1"></div> // js d3.select('.demo1') .append('svg') .attr("width", 500) .attr("height", 200) .append('g') // 设置比例尺 const scale = d3.scaleLinear() .domain([0, 100]) .range([0, 500]); // 建立坐标轴 let axis = d3.axisBottom(scale); d3.select('svg g') .call(axis);
-
但是可以看出来跟我们常见的坐标轴的位置不同,这是因为svg绘制图片都是从左上角的原点(0,0)处开始绘制的,所以需要使用 margin(用来显示左右预留宽度) transform 来设置偏移量; 步骤如下:
* 设定 width、height、margin 变量
* 设定把用 transform 移到 x = margin、y = 高度,扣掉marigin\*2的地方,再开始绘制轴线
* 将输入域的范围设定成 svg 宽度扣掉 margin\*2 (左右两边的margin),这样绘制出来的轴线左右才有距离
```htm
let width = 500,
height = 200,
margin = 10;
// 建立坐标轴
d3.select('.demo1')
.append('svg')
.attr("width", width)
.attr("height", height)
.append('g')
.attr('transform', `translate(${margin}, ${height-(margin*2)})`)
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, `${width-(margin*2)}`]);
let axis = d3.axisBottom(scale);
d3.select('svg g')
.call(axis);
// 这里是需要使用selection.call()方法来设置坐标轴线
```
2.绘制轴线的几种方法:
```html
axisTop(scale)、axisBottom(scale)、axisRight(scale)、axisLeft(scale)
这是几种常用的用来绘制轴线的方法。scale比例尺是必须的,会根据比例尺生成对应的刻度, 关于scale如何设定,可以在d3官网详细查询
```
3.刻度位置:
* axisTop ⇒ ticks 刻度在轴线上
* axisBottom ⇒ ticks 刻度在轴线下方
* axisRight ⇒ ticks 刻度在轴线右方
* **axisLeft** ⇒ ticks 刻度在轴线左方
4.ticks刻度的设置
一般我们可以自定义的设置主要是如下几种:
-
axis.ticks() => 调整ticks数量
let scale = d3.scaleLinear().domain([0, 100]).range([0, 500]); let axis = d3.axisBottom(scale); axis.ticks(20);// axis.tixks(12) 但要注意的是,即使我们定义好想要的特定刻度数量,如果刻度的值并非完整的数值的话,D3会自行调整刻度数量,让 ticks value 是漂亮的数字 (例如以10为单位间隔)
-
axid.ticks() => 设置刻度的内容
let width = 500, height = 200, margin = 10; d3.select('.demo1') .append('svg') .attr("width", width) .attr("height", height) .append('g') .attr('transform', `translate(${margin}, ${height - (margin * 2)})`) let scale = d3.scaleLinear().domain([0, 100]).range([0, 500]); let axis = d3.axisBottom(scale); axis.ticks(12); axis.tickValues([12,32,43,55]) 可以看到就是将设置的值设置为刻度内容,会按照刻度尺的比例进行位置定位和排序
-
axis.tickFormat( ) => 调整tick label的文字
let width = 700, height = 200, margin = 20; d3.select('.demo1') .append('svg') .attr("width", width) .attr("height", height) .append('g') .attr('transform', `translate(${margin}, ${height - (margin * 2)})`) let scale = d3.scaleLinear().domain([0, 100]).range([0, 500]); let axis = d3.axisBottom(scale); axis.ticks(12); axis.tickFormat(function(d) { return d + "单位"; }); d3.select('svg g') .call(axis);
-
axis.tickSize() axis.tickSizeInner() axis.tickSizeOuter() 用来设置刻度线的长度
inner:表示内部刻度线的长度; outer 两侧的刻度线长度
tickSize( ) ⇒ 內部+外部刻度一起设置 tickSizeInner( ) ⇒ 设置内部刻度线长度 tickSizeOuter( ) ⇒ 两侧的刻度线长度
默认的刻度线长度是6.可以自行设置:
let width = 700,
height = 200,
margin = 20;
d3.select('.demo1')
.append('svg')
.attr("width", width)
.attr("height", height)
.append('g')
.attr('transform', `translate(${margin}, ${height - (margin * 2)})`)
let scale = d3.scaleLinear().domain([0, 100]).range([0, 500]);
let axis = d3.axisBottom(scale);
axis.ticks(12);
axis.tickFormat(function(d) {
return d + "单位";
});
axis.tickSize(20)
d3.select('svg g')
.call(axis);
** 这里的 tickSizeOuter 或 tickSizeInner 需要一起设置,否则会出现刻度线不一致的情况,会挡住下面的刻度标签内容,如果需要单独设置其中一种,就需要设置 tickPadding。 注意这里的tickPadding 默认的距离是3。
画一个完整的坐标轴
let width = 700,
height = 300,
margin = 20;
const svg = d3.select('.demo1')
.append('svg')
.attr("width", width)
.attr("height", height)
let scale1 = d3.scaleLinear().domain([0, 100]).range([0, 500]);
let scale2 = d3.scaleLinear().domain([0, 50]).range([280, 0]); // y轴这里的值域需要倒着写,因为y轴是从上到下依次递增的,
let axis = d3.axisBottom(scale1).tickSizeOuter(0)
let yxis = d3.axisLeft(scale2).tickSizeOuter(0)
axis.ticks(5);
axis.tickFormat(function(d) {
return d + "单位";
});
// axis.tickSizeOuter(30);
// axis.tickPadding(30)
svg.append("g").call(axis).attr('transform', `translate(${margin}, ${height - margin})`)
svg.append("g").call(yxis).attr('transform', `translate(20,0)`)