饼图
https://www.d3js.org.cn/document/d3-shape/#pies
定义一个布局:
var pie = d3.pie();
返回值赋给变量 pie,此时 pie 可以当做函数使用。
var piedata = pie(dataset);
将数组 dataset 作为 pie() 的参数,返回值给 piedata。如此一来,
piedata 就是转换后的数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wrzSgd1j-1587639740183)(/Users/imaginexie/Library/Application Support/typora-user-images/image-20200423182708947.png)]
如上图所示,5 个整数被转换成了 5 个对象(Object) ,每个对象都有变量起始角度(startAngle)和终止角度(endAngle),还有原数据(属性名称为 data)。这些都是绘图需要的数据。
记住:布局是为了得到绘图所需的数据。
绘制图形
为了根据转换后的数据 piedata 来作图,还需要一样工具:生成器
SVG 有一个元素,叫做路径 path,是 SVG 中功能最强的元素,它可以表示其它任意的图形。
顾名思义,路径元素就是通过定义一个段“路径”,来绘制出各种图形。
但是,路径是很难计算的,通过布局转换后的数据 piedata 仍然很难手动计算得到路径值。为我们完成这项任务的,就是生成器。
这里要用到的叫做弧生成器,能够生成弧的路径,因为饼图的每一部分都是一段弧。https://www.d3js.org.cn/document/d3-shape/#arcs
arc
生成器用来在饼图或圆环图中生成 circular(圆形) 或 annular(环形) 扇形。
var outerRadius = 150; //外半径 var innerRadius = 0; //内半径,为0则中间没有空白 var arc_generator = d3.arc() .innerRadius(0) .outerRadius(100);
弧生成器返回的结果赋值给 arc。此时,arc 可以当做一个函数使用,把 piedata 作为参数传入,即可得到路径值。
接下来,可以在 SVG 中添加图形元素了。先在 svg 里添加足够数量(5个)个分组元素(g),每一个分组用于存放一段弧的相关元素。
var g = svg.append("g") .attr("transform","translate("+marge.top+","+marge.left+")"); var gs = g.selectAll(".g") .data(pieData) .enter() .append("g") .attr("transform","translate("+width/2+","+height/2+")")//位置信息
接下来对每个 g 元素,添加 path 。
gs.append("path") .attr("d",function(d){ return arc_generator(d);//往弧形生成器中出入数据 }) .attr("fill",function(d,i){ return colorScale(i); });
因为 arcs 是同时选择了 5 个 g 元素的选择集,所以调用 append(“path”) 后,每个 g 中都有 path 。路径值的属性名称是 d,调用弧生成器后返回的值赋值给它。要注意,arc(d) 的参数 d 是被绑定的数据。
另外,color 是一个颜色比例尺,它能根据传入的索引号获取相应的颜色值,定义如下。
//设置一个color的颜色比例尺,为了让不同的扇形呈现不同的颜色 var colorScale = d3.scaleOrdinal() .domain(d3.range(dataset.length)) .range(d3.schemeCategory10);
然后在每一个弧线中心添加文本:
gs.append("text") .attr("transform",function(d){//位置设在中心处 return "translate("+arc_generator.centroid(d)+")"; }) .attr("text-anchor","middle") .text(function(d){ return d.data; })
arc.centroid(d) 能算出弧线的中心。要注意,text() 里返回的是 d.data ,而不是 d 。因为被绑定的数据是对象,里面有 d.startAngle、d.endAngle、d.data 等,其中 d.data 才是转换前的整数的值。
完整代码:
<body> <svg width="500" height="500"></svg> <script> var marge = {top:60,bottom:60,left:60,right:60} var svg = d3.select("svg") var width = svg.attr("width") var height = svg.attr("height") var g = svg.append("g") .attr("transform","translate("+marge.top+","+marge.left+")"); var dataset = [ 30 , 10 , 43 , 55 , 13 ]; //设置一个color的颜色比例尺,为了让不同的扇形呈现不同的颜色 var colorScale = d3.scaleOrdinal() .domain(d3.range(dataset.length)) .range(d3.schemeCategory10); //新建一个饼状图 var pie = d3.pie(); //新建一个弧形生成器 var innerRadius = 0;//内半径 var outerRadius = 100;//外半径 var arc_generator = d3.arc() .innerRadius(0) .outerRadius(100); //将原始数据变成可以绘制饼状图的数据, var pieData = pie(dataset); //在浏览器的控制台打印pieData console.log(pieData); //在有了绘制饼状图必须的数据后,我们就可以开始绘制了 var gs = g.selectAll(".g") .data(pieData) .enter() .append("g") .attr("transform","translate("+width/2+","+height/2+")")//位置信息 //绘制饼状图的各个扇形 gs.append("path") .attr("d",function(d){ return arc_generator(d);//往弧形生成器中出入数据 }) .attr("fill",function(d,i){ return colorScale(i); }); //绘制饼状图上面的文字信息 gs.append("text") .attr("transform",function(d){//位置设在中心处 return "translate("+arc_generator.centroid(d)+")"; }) .attr("text-anchor","middle") .text(function(d){ return d.data; }) </script> </body>