共计 2505 个字符,预计需要花费 7 分钟才能阅读完成。
前言
上一篇文章 咱们讲了 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 —— 绘制柱状图(二)