d3.js学习之(二)比例尺

431 阅读2分钟

书接上回,我们上次用d3实现了画出柱形,这次我们实现完整的柱形图。

基础概念

比例尺

比例尺,简而言之,就是将一组数据映射到另一组数据上,用法理解就是,把我们要展示的数据,映射成相应的像素,比如我们的x轴,位置从0到100即输出域,要展示的数据即输入域,最小值是20,最大值是80,那比例尺的作用就是将20按比例转成0,80按比例转成100。

这里主要用到两个函数

  • domain 设置输入域的指定数组
  • range 设置刻度的输出范围值的指定数组

这一次我们主要用到两种比例尺

scaleBand 序数比例尺

把离散的定义域映射到线性的定义域上,比如把[a,b,c],映射到[0,90]上,那a会被映射在0,b在45,c在90

1642932246.png

scaleLinear 线性比例尺

把连续的定义域映射到线性的定义域上

1642932430(1).png

开始制作

  1. 先定义好我们柱形图的数据,还有svg的宽高,边距
const dataset = [11, 31,14, 49, 24, 17, 88, 18, 65 ];

const w = 500;
const h = 300;

const margin = {
  padding: 20,
  bottom: 20,
  left: 30
}

  1. 创建一个svg
const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
  1. 建立两个比例尺,因为我要用数据的序号做x轴,所以一个用序数比例尺,一个用线性比例尺
let x = d3.scaleBand()
    .domain(dataset.map((item,index) => index))
    .range([margin.left,w - margin.left])
    .padding(0.1)

let y = d3.scaleLinear()
    .domain([0, d3.max(dataset)]).nice()
    .range([h-margin.bottom, margin.bottom])
  1. 创建x轴和y轴
xAxis = g => g.attr("transform", `translate(0,${h - margin.bottom})`)
    .call(d3.axisBottom(x).tickSizeOuter(0))

yAxis = g => g.attr("transform", `translate(${margin.left},0)`).call(d3.axisLeft(y))

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

svg.append("g")
      .call(yAxis);
  • axisBottom 构建一个刻度在下的坐标轴生成器,方向水平

  • axisLeft 构建一个刻度在左的坐标轴生成器,方向垂直

  • 同时用transform移动他们到合适的位置

现在可以看到效果

1642934067(1).png

  1. 接下来就是画上矩形
svg.append('g')
  .selectAll('rect')
  .data(dataset)
  .join('rect')
  .attr('height', d => y(0) - y(d))
  .attr('width', d => x.bandwidth())
  .attr('x', (d,index) => x(index))
  .attr('y', d => y(d))
  .attr("fill", "pink");
  1. 效果完成

1642934279(1).png