基于 D3.js 的饼图的实现

2,227 阅读3分钟

  在前面的几篇文章里,我已经介绍过怎样用柱状图、折线图、散点图和气泡图这四种基本图表。这四种图表都是有坐标轴的,现在来说一种没有坐标轴的图表——饼图。

  还是和之前一样,我们先把简单的画图框架搭起来,添加SVG画布。但是这里需要注意的是,为了方便后面画饼图上的弧形,我们把组合这些元素的g元素移动到画布的中心:



    
        
        饼图
        
            .container {
                margin: 30px auto;
                width: 600px;
                height: 300px;
                border: 1px solid #000;
            }
        
    
    
        

模拟数据并转化

  为了画饼图,我们模拟了一些这样的数据。

// 模拟数据
var dataset = [
    {name: '购物', value: 983},
    {name: '日常饮食', value: 300},
    {name: '医药', value: 1400},
    {name: '交通', value: 402},
    {name: '杂费', value: 134}
];

  在柱状图等有坐标轴的图表中,我们通过创建合适的比例尺来将模拟好的数据转化成适合画图的数据,那在饼图里,又用什么来转化呢?看这里~

// 转换原始数据为能用于绘图的数据
var pie = d3.layout.pie()
                .sort(null)
                .value(function(d) {
                    return d.value;
                });
// pie是一个函数    
var pieData = pie(dataset);

  layout叫做布局,在D3.js中它提供了一些转化成特定图表数据的函数,如其中就包括饼图。它提供一个基础的转化函数,在此基础上我们根据自己的需要再对该函数进行进一步的设置,就得到了如上述代码中pie变量保存的函数一样的转化工具,通过把原始的数据dataset传入pie中就能得到绘图数据pieData。具体的变化我们可以看下图。

  左边是转化前的原始的数据结构,右边是转化后的适合绘图的数据结构。可以看到,在保留原本的数据的基础上,转化后的数据新增了该项在整个饼图中的起始角度(startAngle和endAngle),以及弧形之间的间隙角度(padAngle)。

计算弧形路径

  在饼图中,我们用SVG中的path元素来表示每一块弧形,而从pieData到path元素的d属性还是有一定的距离,所以我还需要再通过一步操作来用pieData计算出d属性可用的值。

// 创建计算弧形路径的函数
var radius = 100;
var arc = d3.svg.arc()
        .innerRadius(0)
        .outerRadius(radius);  

添加弧形

  上面的代码用svg.arc()创建了一个计算弧形路径的函数,通过这个函数就可以计算出path的d属性的值,就像下面这样。

// 添加弧形
main.selectAll('g')
        .data(pieData)
        .enter()
        .append('path')
        .attr('fill', function(d, i) {
            return getColor(i);
        })
        .attr('d', function(d){
            return arc(d);
        });

好了,饼图就这样画好了。

  给大家(虽然我知道目前没有什么人看这个但是我还是要像个神经病一样的装作有人看 =_= )留个小小的拓展,如何加上下图这样的文字标签。答案就在pie.html里。