2014-01-24 47 views
0

我一直在建立一个圆弧发芽谱图的饼图。电影补间动画不是动画

我有一个演示工作,但圆弧补间是对齐而不是动画顺利。如果有人能够帮助提升它,那么它会变得很棒,而不是捕捉周围的弧线。

http://jsfiddle.net/BxLHd/9/

我硬编码的选择门槛。这些弧线似乎并不正确 - 看起来似乎很快。

var arcGenerator = { 
    radius: 100, 
    oldData: "", 
    init: function(data){ 
     var clone = jQuery.extend(true, {}, data); 
     this.oldData = this.setData(clone, false); 
     this.setup(this.setData(data, true));   
    }, 
    update: function(data){ 
     var clone = jQuery.extend(true, {}, data);   
     this.animate(this.setData(data, true));   
     this.oldData = this.setData(clone, false); 
    }, 
    animate: function(data){ 
     var that = this; 

     var chart = d3.select(".arcchart"); 
     that.generateArcs(chart, data); 
    }, 
    setData: function(data, isSorted){ 

     var diameter = 2 * Math.PI * this.radius; 

     var localData = new Array(); 

     var innerPieSliceTotal = 0; 
     for (x in data) { 
      innerPieSliceTotal += data[x].value; 
     } 

     var displacement = 0; 
     var oldBatchLength = 0; 

     if(isSorted){ 
      data.sort(function(a, b) { 
       return b.value - a.value; 
      }); 
     }   

     $.each(data, function(index, value) {    
      var riseLevels = value.riselevels; 
      var machineType = value.label;    
      var innerPieSliceValue = value.value; 

      var ratioToWorkWith = innerPieSliceValue/innerPieSliceTotal; 
      var riseLevelCount = riseLevels.length; 

      if(oldBatchLength !=undefined){    
       displacement+=oldBatchLength; 
      } 

      var arcBatchLength = (2*ratioToWorkWith)*Math.PI; 
      var arcPartition = arcBatchLength/riseLevelCount; 

       $.each(riseLevels, function(ri, value) { 
        var startAngle = (ri*arcPartition); 
        var endAngle = ((ri+1)*arcPartition); 

        if(index!=0){ 
         startAngle+=displacement; 
         endAngle+=displacement; 
        } 

        riseLevels[ri]["startAngle"] = startAngle; 
        riseLevels[ri]["endAngle"] = endAngle; 
        riseLevels[ri]["machineType"] = machineType;      
       }); 

      oldBatchLength = arcBatchLength; 

      localData.push(riseLevels); 
     }); 

     var finalArray = new Array(); 

     $.each(localData, function(index, value) { 
      $.each(localData[index], function(i, v) { 
       finalArray.push(v); 
      }); 
     }); 

     return finalArray; 

    }, 
    generateArcs: function(chart, data){ 

     var that = this; 

     //append previous value to it.   
     $.each(data, function(index, value) {    
      data[index]["previousEndAngle"] = that.oldData[index].endAngle; 
     });  

     var arcpaths = chart.selectAll("path") 
       .data(data); 

      arcpaths.enter().append("svg:path") 
       .attr("class", function(d, i){ 
        return d.machineType; 
       }) 
       .style("fill", function(d, i){ 
        return d.color; 
       }) 
       .transition() 
       .ease("elastic") 
       .duration(750) 
       .attrTween("d", arcTween); 

      arcpaths.transition() 
       .ease("elastic") 
       .duration(750) 
       .attrTween("d",arcTween); 

      arcpaths.exit().transition() 
       .ease("bounce") 
       .duration(750) 
       .attrTween("d", arcTween) 
       .remove(); 

     function arcTween(b) { 
      var i = d3.interpolate({value: b.endAngle-0.1}, b); 

      return function(t) { 
       return that.getArc()(i(t)); 
      }; 
     }   
    }, 
    setup: function(data){  
     var chart = d3.select("#threshold").append("svg:svg") 
       .attr("class", "chart") 
       .attr("width", 420) 
       .attr("height", 420) 
        .append("svg:g") 
        .attr("class", "arcchart") 
        .attr("transform", "translate(200,200)"); 

     this.generateArcs(chart, data);  
    }, 
    getArc: function(){ 
     var that = this; 

     var arc = d3.svg.arc() 
       .innerRadius(that.radius) 
       .outerRadius(function(d){ 
        var maxHeight = 100; 
        var ratio = (d.height/maxHeight * 100)+that.radius; 
        return ratio; 
       }) 
       .startAngle(function(d, i){ 
        return d.startAngle; 
       }) 
       .endAngle(function(d, i){ 
        return d.endAngle; 
       }); 

     return arc; 
    } 
} 
+2

你的jsfiddle有超过1200行的代码。你能把它缩小到一个简单的例子吗?我很难搞清楚从何时何地调用什么。 –

+0

Lars,我压缩了插件/饼图代码。如果您可以检查arcGenerator函数http://jsfiddle.net/BxLHd/12/谢谢 –

+0

我的评论的要点是让事情更容易理解。我仍然不知道你在哪里更新图表的那一部分 - 更新函数似乎根本没有选择“#threshold”。 –

回答

1

您的arcTween函数在错误值之间插值。在这种情况下,需要的是数据元素与endAnglepreviousEndAngle(因为您已经在计算)和未修改的元素之间的插值。以下代码实现了这一点。

function arcTween(b) { 
    var prev = JSON.parse(JSON.stringify(b)); 
    prev.endAngle = b.previousEndAngle; 
    var i = d3.interpolate(prev, b); 

    return function(t) { 
    return that.getArc()(i(t)); 
    }; 
} 

完整示例here