D3 js多级饼图动画

时间:2014-04-02 16:40:23

标签: javascript d3.js pie-chart

我创建了一个多级饼图但我在加载时无法设置动画。 这是我试过的JS。动画在图表的第一个圆圈上运行正常,但它隐藏了另外两个。

任何帮助都将不胜感激。谢谢:)

<script>
var dataset = {
  final: [7000],
  process: [1000, 1000, 1000, 7000],
  initial: [10000],
};

var width = 660,
    height = 500,
    cwidth = 75;

var color = d3.scale.category20();

var pie = d3.layout.pie()
    .sort(null);

var arc = d3.svg.arc();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("class","wrapper")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")

var gs = svg.selectAll("g.wrapper").data(d3.values(dataset)).enter()
        .append("g")
        .attr("id",function(d,i){
            return Object.keys(dataset)[i];
        });

var gsLabels = svg.selectAll("g.wrapper").data(d3.values(dataset)).enter()
        .append("g")
        .attr("id",function(d,i){
            return "label_" + Object.keys(dataset)[i];
        });

var count = 0;
var path = gs.selectAll("path")
    .data(function(d) { return pie(d); })
  .enter().append("path")
    .attr("fill", function(d, i) { return color(i); })
    .attr("d", function(d, i, j) { 
        if(Object.keys(dataset)[j] === "final"){
            return arc.innerRadius(cwidth*j).outerRadius(cwidth*(j+1))(d); 
        }
        else{
            return arc.innerRadius(10+cwidth*j).outerRadius(cwidth*(j+1))(d); 
        }
        })
    .transition().delay(function(d, i, j) {
            return i * 500; 
    }).duration(500)
    .attrTween('d', function(d,x,y) {
       var i = d3.interpolate(d.startAngle+0.1, d.endAngle);
       return function(t) {
           d.endAngle = i(t);
         return arc(d);
       }
    });


    </script>

1 个答案:

答案 0 :(得分:1)

主要问题是您为所有不同的饼段使用相同的圆弧生成器。这意味着在过渡之后,所有的段都将具有相同的内半径和外半径 - 它们就在那里,你只是看不到它们,因为它们被外部的蓝色部分遮挡了。

要解决此问题,请为不同级别使用不同的电弧生成器。您还需要将d属性初始化为零宽度(即开始和结束角度相同),以使动画正常工作。

我为此here实施了一个解决方案,我为每个饼图段保存了一个弧生成器,并为该段分配了数据。这有点浪费,因为每个级别的单个生成器就足够了,但实现起来更快。相关代码如下。

var path = gs.selectAll("path")
.data(function(d) { return pie(d); })
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", function(d, i, j) { 
    d._tmp = d.endAngle;
    d.endAngle = d.startAngle;
    if(Object.keys(dataset)[j] === "final"){
        d.arc = d3.svg.arc().innerRadius(cwidth*j).outerRadius(cwidth*(j+1)); 
    }
    else{
        d.arc = d3.svg.arc().innerRadius(10+cwidth*j).outerRadius(cwidth*(j+1)); 
    }
    return d.arc(d);
    })
.transition().delay(function(d, i, j) {
        return i * 500; 
}).duration(500)
.attrTween('d', function(d,x,y) {
   var i = d3.interpolate(d.startAngle, d._tmp);
   return function(t) {
       d.endAngle = i(t);
     return d.arc(d);
   }
});