简体   繁体   English

D3 JS多层饼图动画

[英]D3 js multi level pie chart animation

I created a multi-level pie chart but i am having trouble animate it on load. 我创建了一个多级饼图,但在加载时无法为其设置动画。 Here is the JS that i tryied.The animation works fine on the first circle of the chart , but it hides the other 2. 这是我尝试过的JS,动画在图表的第一个圆上工作正常,但隐藏了其他2。

Any help would be appreciated.Thanks:) 任何帮助将不胜感激。谢谢:)

<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>

The main problem is that you're using the same arc generator for all of the different pie segments. 主要问题是,您对所有不同的饼图段都使用了相同的电弧生成器。 That means that after the transition, all the segments will have the same inner and outer radii -- they are there, you just can't see them because they're obscured by the outer blue segment. 这意味着在过渡之后,所有线段都将具有相同的内部和外部半径-它们在那里,您看不到它们,因为它们被外部蓝色线段所遮盖。

To fix this, use different arc generators for the different levels. 要解决此问题,请对不同级别使用不同的电弧发生器。 You also need to initialise the d attribute to zero width (ie start and end angle the same) for the animation to work properly. 您还需要将d属性初始化为零宽度(即,开始角度和结束角度相同),动画才能正常工作。

I've implemented a solution for this here where I'm saving an arc generator for each pie chart segment with the data assigned to that segment. 我在这里实现了一个解决方案,其中为每个饼图段保存了一个弧生成器,并为其分配了数据。 This is a bit wasteful, as a single generator for each level would be enough, but faster to implement. 这有点浪费,因为每个级别只有一个生成器就足够了,但是实现起来更快。 The relevant code is below. 相关代码如下。

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);
   }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM