前言
上一篇文章 咱们讲了 D3.js
中一些常见的 API
,并且通过一个 demo 理解了 D3.js
是如何工作的。铺垫完之后,这篇文章咱们正儿八经的来实现一个柱状图。
注释
比例尺
比例尺是 D3.js
中一个重要的概念,它用于在值和坐标之间的互相转换。本文中呈现的相干 API 如下
API | 阐明 |
---|---|
scaleBand | 个别用于将一组离散值映射到间断范畴的值 |
scaleLinear | 线性转换,将间断的输出域映射到间断的输入范畴 |
设想一下,咱们须要在一个 800 x 600 宽高的容器内绘制一个坐标系。通常状况下,坐标的数值不会与理论的宽高齐全对应。因而,咱们须要一种工具来将理论的宽高与坐标系中的数值进行映射。
对于 scaleLinear
这个线性转换函数,能够用上面的公式来形容:
$y = mx + b(b 为任意常量)$
通过输出 $x$(通常是一个数值),咱们能够取得元素在页面上的高度或宽度。
绘制坐标系
首先咱们先增加初始代码:引入 D3.js
& 设置根底款式
<html><head> <title>Bar</title> <style> #bar { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; } </style></head><body><div id="bar"></div></body><script src="<https://d3js.org/d3.v7.min.js>"></script></html>
紧接着咱们来创立一个 svg,宽高为:800 x 600
const width = 800; const height = 600; const data = Array.from({length: 26}).map((_, i) => ({ name: String.fromCharCode(65 + i), value: Math.random() * 100 })) const svg = d3.select('#bar') .append('svg') .attr('width', width) .attr('height', height)
此时页面上仍旧是赤裸裸的一片,没关系,咱们先把 x 轴加上:
const xScale = d3.scaleBand().domain(data.map(item => item.name)).range([0, 500]).padding(0.1)const xAxis = d3.axisBottom(xScale)svg.append('g').call(xAxis)
此时,页面曾经呈现了咱们须要的 x 轴
随后咱们把 y 轴也加到页面上:
const yScale = d3.scaleLinear().domain([0, 100]).range([500, 0])const yAxis = d3.axisLeft(yScale)svg.append('g').call(yAxis)
此时页面就会呈现一个奇怪的坐标系
当然如果你看完了上一篇文章,你就晓得这是因为坐标原点在左上角导致的
因而咱们在绘制 x 轴的时候还须要把它的地位调整一下
svg.append('g').attr('transform', `translate(0, 500)`).call(xAxis
那么写到这里,咱们就失去了一个长得挺难看的坐标系
增加柱状图
增加坐标系之后,咱们就能够开始增加柱状图了。
在此之前有一些细节须要阐明:咱们能够利用 xScale
或 yScale
来依据网页上理论须要展现的值,来决定柱状图的展现地位。比方,上面这段代码:
const xScale = d3.scaleBand().domain(data.map(item => item.name)).range([0, 500]).padding(0.1)
执行之后,咱们能够通过 name → value
的映射,来获取 x 轴上每一个离散点的具体位置,同理 y 轴也是如此。
依据这点,咱们就不须要再花太多工夫计算每个矩形的的 x、y 坐标了,而是能间接通过 xScale
、yScale
这些函数来进行简略的换算来达到咱们想要的成果。代码如下:
svg.selectAll('rect') .data(data) .join('rect') .attr('x', item => xScale(item.name)) .attr('y', item => yScale(item.value)) .attr('width', xScale.bandwidth()) .attr('height', item => 500 - yScale(item.value)) .attr('fill', 'steelblue')
成果如下
补充动画
D3.js
中的动画逻辑是这样的:
- 设置初始值,比方 x、y
- 增加动画配置,比方动画函数、持续时间等等
- 设置最终值,比方
width
、height
svg.selectAll('rect') .data(data) .join('rect') // 设置 x 坐标,避免动画时呈现抖动 .attr('x', item => xScale(item.name)) .attr('y', 500) // 设置宽度,柱状图的宽度在这里始终放弃不变即可 .attr('width', xScale.bandwidth()) // 为了有动画成果,这里先设置高度为 0 .attr('height', 0) .transition() // 设置提早 .delay((item, i) => i * 20) // 增加动画函数 .ease(d3.easeCubic) // 设置动画时长 .duration(1000) // 最终的成果 .attr('y', item => yScale(item.value)) .attr('height', item => 500 - yScale(item.value)) .attr('fill', 'steelblue')
总结
本文中咱们理解了比例尺并且相熟了 D3.js
中一些与之相干的 API
,并且通过一系列步骤理解了怎么通过 D3.js
来实现一个柱状图。
想要理解更多前端常识,欢送关注我的公众号:tony老师的前端补习班
系列文章:
- D3.js —— 绘制柱状图(一)
- D3.js —— 绘制柱状图(二)