当前位置:   article > 正文

D3.js上手——饼状图

d3js 饼图 内拐角大小

饼状图是数据统计中经常用到的另一类图表,饼图可以直观地显示一个数据系列中各项的大小与各项总和的比例,本文将使用D3上手制作一个简单的饼状图

什么是布局

布局是D3中非常重要的内容,有了布局D3才能画出复杂的矢量图。但布局并不是直接绘制图形,只是将初始数据转换成容易画图的图形语言,画图工具能读懂图形语言来进行绘制。

在绘制饼状图中,例如有一组数据[1, 2, 3],只依靠这些数据是画不出的,需要将这些数据转化为圆形的起始角度和终止角度,第一块的角度区域为[0, π/3],第二块的角度区域为[π/3, π]……绘制工具能根据这些角度值进行绘制。布局只进行数据转换

D3还提供其他常用图表的布局函数,比如力导向图(Force)、弦图(Chord)、树状图(Tree)、直方图(Histogram)、分区图(Partition)等,每种布局有对应的API

确定数据

表格数据是来自w3schools的2016年9月的浏览器使用率

浏览器占比
Chrome72.5%
IE5.3%
Firefox16.3%
Safari3.5%
Opera1.0%
Others1.4%

对此设定以下二维数组装载这些数据

  1. var dataset = [['Chrome', 72.5], ['IE', 5.3], ['Firefox', 16.3], ['Safari', 3.5], ['Opera', 1.0], ['Others', 1.4]];
  2. 复制代码

建立布局

  • d3.pie() 构造一个新的饼布局

构建一个饼布局并接收数据

  1. var pie = d3.pie()
  2. .sort(null) // 在创建布局的时候,默认排序数据从大到小,设为null可以按照数组默认顺序排序
  3. .value(function(d){
  4. return d[1]
  5. });
  6. 复制代码

把数据转换为饼图绘制所需要的数据

  1. var piedata = pie(dataset);
  2. console.log(piedata);
  3. 复制代码

在控制台输出piedata,看看转换后的数据

可以看到,原来的数据已经被转换成6组适合画图的数据

  • data —— 保留原有数据
  • index —— 序号
  • startAngle —— 一段弧的起始角度
  • endAngle —— 一段弧的终止角度

生成弧生成器

虽然有了角度,但目前还是很难画出我们想要的饼图,还要用到D3中的路径生成器。在svg中,path标签的路径数值往往十分复杂,手动去生成是不现实的,尤其是要生成各种复杂曲线的时候,好在D3提供了基本的路径生成器,有线段、区域、弧生成器等。画饼图的时候需要用到弧生成器,帮助我们把转换后的数据真正绘制出来

  • d3.arc() 创建一个新的弧生成器
  • arc.innerRadius([radius]) 设置内部半径
  • arc.outerRadius([radius]) 设置外部半径

这里把画布的四分之一作为外部半径,内部半径设为0就是饼图,没错,设置大于0就是圆环图

  1. var outerRadius = width / 4;
  2. var innerRadius = 0;
  3. var arc = d3.arc()
  4. .outerRadius(outerRadius)
  5. .innerRadius(innerRadius);
  6. 复制代码

绘制饼图

跟之前一样,创建g组合标签后,把piedata数据绑定至g标签,这里要用到D3的内置颜色,d3.schemeCategory10选了10种颜色,方便我们随时使用,为饼图的不同区域填色,不必为想不出好的颜色搭配而烦恼,当然也可以自定义颜色

  1. var arcs = svg.selectAll('g')
  2. .data(piedata)
  3. .enter()
  4. .append('g')
  5. .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
  6. // 调用内置颜色序列
  7. var colors = d3.schemeCategory10;
  8. arcs.append('path')
  9. .attr('fill', function(d, i){
  10. return colors[i];
  11. })
  12. .attr('d', function(d){
  13. return arc(d);
  14. });
  15. 复制代码

在path标签中,给d属性赋予数据经过弧生成器处理的值,这样一个没有标注的饼图就完成了

添加标注

  • arc.centroid(arguments…) 获取弧中心坐标

接下来给饼图加一些标注,以便更好地阅读图形,主要用到弧中心的概念,如下图,黑点就是每个弧的中心,利用**arc.centroid()**可以获取弧中心的坐标,并且这个坐标是相对圆形的相对坐标。有了这个坐标,可以很方便地在每个弧上添加文字标注

arc.centroid(d)是一个包含横坐标和纵坐标的数组[x, y],给坐标乘以2倍以上的数值就把文字移到圆形外边

  1. arcs.append('text')
  2. .attr('transform', function(d, i){
  3. var x = arc.centroid(d)[0] * 2.8;
  4. var y = arc.centroid(d)[1] * 2.8;
  5. return 'translate(' + x + ', ' + y + ')';
  6. })
  7. .attr('text-anchor', 'middle')
  8. .text(function(d){
  9. var percent = Number(d.value) / d3.sum(dataset, function(d){
  10. return d[1];
  11. }) * 100;
  12. return d.data[0] + ' ' + percent.toFixed(1) + '%';
  13. })
  14. 复制代码

最后再加一些连线

  1. arcs.append('line')
  2. .attr('stroke', 'black')
  3. .attr('x1', function(d){ return arc.centroid(d)[0] * 2; })
  4. .attr('y1', function(d){ return arc.centroid(d)[1] * 2; })
  5. .attr('x2', function(d, i){
  6. return arc.centroid(d)[0] * 2.5;
  7. })
  8. .attr('y2', function(d, i){
  9. return arc.centroid(d)[1] * 2.5;
  10. });
  11. 复制代码

由于最后几个数据太小,标注文字会重叠到一起,这里做了一个判断处理来错开数据值较小的文字,最后的效果图如下所示

查看完整示例代码

转载于:https://juejin.im/post/5cac3f03f265da035b6175f5

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/132598
推荐阅读
相关标签
  

闽ICP备14008679号