饼图这个功能,就像下面这样,比较常见。想要完成这个功能在如今的社会,不难。因为很多优秀的第三方库都帮我们实现了,只需要调用一下就可以了。比如 echarts、highCharts、d3、plot、antv全家桶等等。
那接下来的系列文章,我们就来看看D3是如何处理饼图的!
在讲解之前,我们还是要说一下图形化里有关于圆的一些内容。
一、计算机如何表示角度?
描述角度有2种方式,一种是角度制、一种是弧度制。
既然有了角度制,为啥还要有弧度制?
计算机认识3度吗?那肯定不认识,它都不认识这个单位。
那计算机认识啥?认识一切实数(0,1,2,3,4,5等等),所以为了能让计算机识别“度数单位”,“弧度制”出现了,它是“角度制”的一种测量方式。
那上面就是从计算机这个角度来理解“角度”与“弧度”。
二、如何理解弧度?
根据百度百科我们知道,“弧度的绝对值 = 弧长 / 半径”。弧度要加绝对值是因为弧长有正负之分,顺时针弧长是正数,逆时针弧长是负数。
一圈的弧长是“2兀*半径”,所以根据公式,一圈对应的弧度就是2兀(单位是rad,表示弧度单位)。
因为360度也可以表示一圈,所以有了下面的等式:
所以30度是多少弧度?左侧✖️30即可得出对应的弧度,因此根据角度求弧度的公式如下:
三、弧度与弧长?
这两个绝对不是一个东西。
刚才我们说了,“弧度的绝对值 = 弧长 / 半径”,那么弧长的公式自然就是 “弧度✖️ 半径”。
所以我们学习跟圆弧、三角函数相关的API的时候,要格外注意入参是什么,是弧度、还是弧长等等。
四、D3是如何画饼图的?
看下面的代码:
<canvas
id='canvas'
width='800'
height='500'
></canvas>
<script>
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
const context = document.queryElementById('canvas').getContext('2d');
const data = [10, 11, 22];
const colors = ['#1f77b4', '#ff7f0e', '#2ca02c'];
const pieCreator = d3.pie();
const arcs = pieCreator(data);
const drawArc = d3.arc().outerRadius(100).innerRadius(30).context(context)
context.translate(width / 2, height / 2);
arcs.forEach(item => {
context.beginPath();
drawArc(item);
context.fillStyle = colors[i];
context.fill();
context.globalAlpha = 1;
context.strokeStyle = '#000';
context.stroke();
})
</script>
将上面代码copy运行一下,你应该会得到下图的效果:
咱们可以在arcs打一个断点,此时就会发现,arcs是一个数组,数组里体现的是当前value在总sum里的占比,只不过这个占比他不是百分比,而是采用了弧度的方式,注意,是弧度,不是弧长!
这种方式确实更好,因为 canvas.arc 的参数就是起始弧度、结束弧度。
画饼弧是比较轻松的,我们只需要将画笔moveTo到起始弧度的起点上,然后外圆弧顺时针或者逆时针都可以,但是内圆弧必须是相反的方向去画,最后stroke描边就可以了。
核心代码如下:
// 外圆半径
const outerRadius = 100
// 内圆半径
const innerRadius = 30
function drawArc(obj) {
const { startAngle, endAngle } = obj;
const drawDirection = startAngle < endAngle;
const positionXOfStartAngle = outerRadius * Math.cos(startAngle);
const positionYOfStartAngle = outerRadius * Math.sin(startAngle);
context.moveTo(positionXOfStartAngle, positionYOfStartAngle);
context.arc(0, 0, outerRadius, startAngle, endAngle, !drawDirection);
context.arc(0, 0, innerRadius, endAngle, startAngle, drawDirection);
}
五、最后
好啦,本期内容到这里就结束啦,接下来的文章会在此基础上来拆解一下D3是如何实现padAngle、cornRadius。
希望我的分享对你有帮助,我们下期再见~~