D3JsDay25圈圈圆圆圈圈,甜甜黏黏甜甜—圆饼图与环圈图

圆饼图(环圈图)简介

圆饼图和环圈图常出现在我们统计图表当中,一般用来表示各个分类的数量所占的百分比,由几个扇形的圆形统计图表,这些扇形区域合起来刚好是一个完全的圆。

圆在svg的困难处

我们在SVG使用的时候要绘制出矩形的图只要对笛卡尔座标的X轴和Y轴的绝对位置有一定的熟悉程度,一般而言可以自行透过描述点的方式绘制出来,但是如果像是圆形或是拥有扇形区域具有曲线的线条想要凭藉着写入点座标绘制来说相对困难许多,因此d3拥有一些图形生成器来将一些资料给转换成适合被svg绘制的数值,在我们绘制圆饼图的时候会使用到pie()arc()这两个函式,下一部分将会介绍这些函式的使用方式。

arc()函式

官方表示这个函式主要的作用是将输入内角外角开始角度结束角度即可产生一个路径的数值

d3.arc()官方文件

具体所需要的物件如官方范例所示如下图

https://ithelp.ithome.com.tw/upload/images/20211010/20125095eFhtM5Tnp9.png

因此我们可以自己尝试看看撰写如下程序码,与官方不同的地方是我们 endAngle带入2π也就是360度的意思

const arc = d3.arc();
const obj = {innerRadius: 0,
            outerRadius: 100,
            startAngle: 0,
            endAngle: 2*Math.PI}
console.log(arc(obj));

这时候我们console.log()会得到一串数值如下

https://ithelp.ithome.com.tw/upload/images/20211010/20125095H0Rif0dxgj.png

是否觉得似曾相识,这些数值和英文字母组成是我们先前介绍svg的path的时候所需要的内容,因此我们尝试着将这个数值复制起来撰写到html的svg里面的path中程序码如下

<svg width="400" height="400">
    <path d="M6.123233995736766e-15,-100A100,100,0,1,1,-6.123233995736766e-15,100A100,100,0,1,1,6.123233995736766e-15,-100Z"></path>
</svg>

这时候应当会看到如下图

https://ithelp.ithome.com.tw/upload/images/20211010/20125095pPBI5tBIEX.png

由於他所绘制的以(0,0)为中心,因此我们通常都会使用transform的translate来移动显示整个圆形,因为宽和高是400,所以我们使用transform="translate(200,200)"位移,最後应当可以看到如下图

<svg width="400" height="400">
      <path transform="translate(200,200)" d="M6.123233995736766e-15,-100A100,100,0,1,1,-6.123233995736766e-15,100A100,100,0,1,1,6.123233995736766e-15,-100Z"></path>
</svg>

https://ithelp.ithome.com.tw/upload/images/20211010/20125095CDi6Hw2zhb.png

除了可以使用物件的方式带入进arc()修改角度以外,也可以使用arc底下的方法链将角度传入进arc()里面,
程序码如下

const arc = d3.arc().innerRadius(0).outerRadius(100).startAngle(0).endAngle(2*Math.PI);
函式 设置内容
innerRadius() 圆形的内半径
outerRadius() 圆形的外半径
startAngle() 圆形起始角度
endAngle() 圆形结束角度
cornerRadius() 圆角的边角半径

pie()函式

了解arc()带入的内容所需要的是开始角度**startAngle()和endAngle()**等等的内容时,必须思考一个问题是一般我们真实的世界的资料不会有这些属性名称刚好对应到arc所需该怎麽办?

因此我们需要pie()来将原始资料转成适合arc()使用的资料

官方说明提到关於这些数据可以传递给arc()所用
如下图

https://ithelp.ithome.com.tw/upload/images/20211010/201250954CpxLAJXk9.png

d3 Pies官方API

接下来我们撰写程序码来尝试使用pie()函式并且console.log()看看呈现什麽内容

 const data = [1, 1, 2, 3, 5, 8, 13, 21];
const pie = d3.pie();
console.log(pie(data));

打开主控台可以发现他会将原本的阵列中的各个数值自动转换成圆饼图所需要占比的角度,换句话说是自动分配每笔数据所比例并且回传成arc所需要的资料
如下图

https://ithelp.ithome.com.tw/upload/images/20211010/20125095fsJv2WFA4V.png

开始绘图

接下来我们将开始利用这些资料进行绘图

由於我们的pie函式帮我们转换出来只有startAngle和endAngle,因此必须给予内圆半径和外圆半径的数值
这边我们内半径改设置50、外半径改设置100试试看,具体程序码如下

const arc = d3.arc().innerRadius(50).outerRadius(100)	

接下来我们将着手开始绘图,记得使用transform:translate位移圆的位置,与先前教过的资料绑定一样使用data()资料绑定然後join("path")函式

这边主要需要注意的地方是绑定的资料是刚刚进行pie()转换後的资料,而在绘制path的属性d所带的数值是使用arc转换data的值,程序码如下

const width = 400;
const height = 400;
d3.select("body").append("svg").attr("width", width);
const svg = d3.select("svg").attr("width", width).attr("height", height);
const arc = d3.arc().innerRadius(50).outerRadius(100);

const data = [1, 1, 2, 3, 5, 8, 13, 21];
const pie = d3.pie();

svg.append("g")
.attr("transform", `translate(${width / 2}, ${height / 2})`)
.selectAll("path")
.data(pie(data))
.join("path")
.attr("d", (data) => arc(data))

将会呈现下图

https://ithelp.ithome.com.tw/upload/images/20211010/20125095gscuskgGkz.png

加入stroke间隔、cornerRadius()

这时候环圈图将如期呈现,但是每笔资料的间隙太相近了,因此我们可以加入stroke属性并设定和背景一样的白色,另外可以添加cornerRadius()数值观看其呈现效果

最後完整程序码如下

const width = 400;
const height = 400;
d3.select("body").append("svg").attr("width", width);
const svg = d3.select("svg").attr("width", width).attr("height", height);
const arc = d3.arc().innerRadius(50).outerRadius(100).cornerRadius(5)	;
const data = [1, 1, 2, 3, 5, 8, 13, 21];
const pie = d3.pie();
svg.append("g")
    .attr("transform", `translate(${width / 2}, ${height / 2})`)
    .selectAll("path")
    .data(pie(data))
    .join("path")
    .attr("d", (data) => arc(data))
    .attr("stroke", "white")
    .attr("stroke-width", "1");

最後应该如下图

https://ithelp.ithome.com.tw/upload/images/20211010/201250954AHmKo33En.png

总结

本日介绍了arc产生器和pie产生器,要绘制圆饼图具体步骤如下

  1. 宣告一个变数来存放arc()的转换函式并且设定内径和外径例如const arc = d3.arc().innerRadius(50).outerRadius(100)
  2. 宣告一个变数来存放pie()的转换函式用来预备将原始资料转换给arc()使用,换句话说将原始资料转换生成startAngleendAngle的资料(这也是arc所需要的资料内容)
  3. 在svg绘图,绑定的资料是由pie()将原始资料转换後的数值,path属性的d所带入的数值是arc()转换刚刚绑定的资料
  4. 依据生成图形适当的添加stroke属性、颜色等等

本日githubPage
githubPage


<<:  自己做个好用的pysdie 2 cheat sheet

>>:  Day 28 - 创意构想2 - 电子礼券存摺

Day 25:Ansible Playbook

昨天有成功使用 Ansible 执行一个 echo 印出东西了,这在 Ansible 里面称作 ad...

初次遇见 .NET

安装 .NET SDK 去 .NET官网下载, 可以选择 .NET 5, 或 .NET Core 3...

结语

谁再叫我写这种东西,我真的会翻脸。(大概过半年就忘记这句话了) 感谢团队的互相扶持,我们撑完了这30...

自动化 End-End 测试 Nightwatch.js 与 BrowserStack

前文介绍了 BrowserStack 本篇写一些在撰写测项的写法与一些要注意的小地方 首先 Brow...

Day 1. 开场

前言: 在去年挑战了Hashicorp 0 到 0.003 介绍Hashicorp Consul, ...