d3.js-坐标轴 知识梳理学习

269 阅读2分钟

坐标轴:

想要系统学习d3.js绘图方法,这里记录一下基础相关教程,更多详尽教程请访问d3官网

坐标轴就是用于回执坐标轴显示的,X轴和Y轴,轴线的组成部分:

  • 一条直线,标示轴线
  • 一组沿着轴的刻度记号(ticks)
  • 每个刻度记号的标签(数字或文字)

1.png

通常我们会使用 < g > 这个 svg 的结构标签把整条轴线的元素包在一起,之后对 < g > 元素进行一些操作(例如:移动的时候,就能将整条轴线一起移动。)

2.png

  1. 建立坐标轴的知识点

    • 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);
      

3.jpg

    但是可以看出来跟我们常见的坐标轴的位置不同,这是因为svg绘制图片都是从左上角的原点(0,0)处开始绘制的,所以需要使用 margin(用来显示左右预留宽度) transform 来设置偏移量; 步骤如下:

    *   设定 widthheightmargin 变量

    *   设定把用 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()方法来设置坐标轴线
    ```

4.jpg

2.绘制轴线的几种方法:

```html
axisTop(scale)、axisBottom(scale)、axisRight(scale)、axisLeft(scale)
这是几种常用的用来绘制轴线的方法。scale比例尺是必须的,会根据比例尺生成对应的刻度, 关于scale如何设定,可以在d3官网详细查询
```

3.刻度位置:

*   axisTop ⇒ ticks 刻度在轴线上

5.jpg

*   axisBottom ⇒ ticks 刻度在轴线下方

6.jpg

*   axisRight ⇒ ticks 刻度在轴线右方

7.jpg

*   **axisLeft** ⇒ ticks 刻度在轴线左方

8.jpg

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为单位间隔)
    

9.png

  • 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])
    可以看到就是将设置的值设置为刻度内容,会按照刻度尺的比例进行位置定位和排序
    

10.png

  • 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);
    

11.png

  • axis.tickSize() axis.tickSizeInner() axis.tickSizeOuter() 用来设置刻度线的长度

    inner:表示内部刻度线的长度; outer 两侧的刻度线长度

    tickSize( ) ⇒ 內部+外部刻度一起设置
    tickSizeInner( ) ⇒ 设置内部刻度线长度
    tickSizeOuter( ) ⇒ 两侧的刻度线长度
    

12.jpg

默认的刻度线长度是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);

13.png

** 这里的 tickSizeOuter 或 tickSizeInner 需要一起设置,否则会出现刻度线不一致的情况,会挡住下面的刻度标签内容,如果需要单独设置其中一种,就需要设置 tickPadding。 注意这里的tickPadding 默认的距离是3。

14.png

画一个完整的坐标轴

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)`)

15.png