d3之饼图

一、需求
制定数据结构,用饼图可视化数据。
1.渲染饼图并带有顺时针旋转展示效果
2.鼠标经过每一项时,该项半径变大,离开时恢复
3.鼠标经过在鼠标位置出现tip 框(我用backbone实现,不作为讲解重点)
4.图例legend
二、分析需求
1.需要的数据:
{ type 图表类型 title 图表名称 legend 图例数据 tooltip 提示 durationTime 动画持续时间 series 图表数据 }
三、数据结构
** 所有图形的数据结构都暂定为如下格式,对于饼图xAxis、yAxis则为null**

'pie':{
            type:'pie',
            title:{
                text:'this is a demo'  //图标名称
            },
            legend:{
                orient:'vertical',//horizontal||vertical   横排或者竖排
                x:300, //在svg中的位置
                y:100,
                width:16,
                height:16,
                padding:5,
                // data:['直接访问','邮件销售','联盟广告','视频广告','搜索引擎']
            },
            tooltip:{
                dataLabels:{
                    color:'#fff',
                    bgColor:'red'
                }
            },
            durationTime:100, //动画的持续时间
            xAxis:null, //x轴数据
            yAxis:null, //y轴数据
            series:{
                title:'数据来源',
                radius:{
                    outerRadius:70,
                    innerRadius:0
                },
                center:{
                    x:100,
                    y:100
                },
                data:[
                    {value:10,data:'直接访问'},
                    {value:20,data:'邮件销售'},
                    {value:30,data:'联盟广告'},
                    {value:30,data:'视频广告'},
                    {value:30,data:'搜索引擎'}
                ]
            }
        }

四、分解
1.渲染饼图
2.添加动画
3.增加hover效果
3.渲染legend
五、实现
1.渲染饼图
在渲染饼图时我们需要做:
1.1、用d3提供的 layout将数据转换为pie所需要的数据格式

this._pie = d3.layout.pie()
                 .sort()
                .value(function(d){
                        return d.value
                })
                .startAngle()
                .endAngle()

sort:和js 中的sort方法一直,接受一个排序函数。不一样之处为它的排序对每一项数据的startAngle和endAngle起作用。
value 是用来划分每一项在圆环上所占的比例
startAngle和endAngle分别表示整个饼图的起始弧度和终止弧度
1.2、设置arc

this._arc = d3.svg.arc()
           .innerRadius()
           .outerRadius()
           .padRadius()
          .startAngle()
          .endAngle()

我们可以想想一下:
但我们画圆环时,是不是需要用svg 的path实现,path标签的d属性时不时会很难,d3.svg.arc()可以根据pie转换后的数据计算出d的取值。
1.3、设置颜色构造器

this._color = d3.scale.category20()

1.4、绘制

    d3.svg.append('g')
                .append('path)
                .attr({
                       d:function(d,i){
                             return self._arc(d)
                       }
                      color:function(d,i){
                            return  self._color(i)
                      }
                })

上面演示了 arc 和color的用法
1.5、动画

    .transition()
    .delay()
    .duration()
    .ease('linear')
    .attrTween('d',function(d,i){
        var fn = d3.interpolateObject({
                endAngle:d.startAngle
            },d)
        return function(t){
                 return self._arc(fn(t))
        }
    })

为了制作连贯的动画,需要在startAngle和endAngle中间插入一些过度值,d3提供了interpolateObject(a,b)方法,根据a,b在a,b之间插入中间值。
1.6、legend
legend制作的难点在于 如果将所有的图例都水平排列,如果确定每一个图例的大小,由于svg 在绘制每一个元素时都是以左上角为起始,需要translate,因此我们需要获得每一个图例的宽度。

svg中的g类似与div 它的宽高为其内容的宽高,但是不能够用$(div).width()获得,d3提供了这样的方法。

 d3.select('g').getBBox().width

你可能感兴趣的:(d3之饼图)