D3 Donut过渡,d,我得到了未定义

时间:2017-03-10 20:04:13

标签: d3.js donut-chart

        var arcMin = 75;        // inner radius of the first arc
        var arcWidth = 25;      // width
        var arcPad = 10;         // padding between arcs

        var arc = d3.arc()
                  .innerRadius(function(d, i) {
                    return  arcMin + i*(arcWidth) + arcPad;
                  })
                  .outerRadius(function(d, i) {
                    return arcMin + (i+1)*(arcWidth);
                  })
                  .startAngle(0 * (PI/180))
                  .endAngle(function(d, i) {
//                    console.log(d);       <----getting undefine under attrTween Call
                    return 2*PI*d.value/100;
                  });

        var path = g.selectAll('path')
          .data(pie(dataset))
          .enter()
          .append('path')
          .attr('d', arc)
          .attr('fill', function(d, i) { 
            return d.data.color;
          })
          .transition()
          .delay(function(d, i) {
            return i * 800;
          });
//          .attrTween('d', function(d) {
//            // This part make my chart disapear
//             var i = d3.interpolate(d.startAngle, d.endAngle);
//             return function(t) {
//               d.endAngle = i(t);
//               return arc(d);
//             }
//            // This part make my chart disapear
//          });

arc(d)总是返回&#34; M0,0Z&#34; ..

我发现原因是在arcTween下调用arc时,所有d,i都返回undefine。我该如何解决这个问题。

此处的代码:https://jsfiddle.net/m8oupfne/3/

最终产品:

1 个答案:

答案 0 :(得分:0)

夫妻俩:

  1. 乍一看,attrTween功能无效,因为arc功能同时依赖于d,i,您只能将d传递给它

  2. 但是,解决这个问题并不能使你的图表过渡得很好吗?为什么?因为你的弧功能似乎没有任何意义。您使用pie计算角度,然后在arc函数中覆盖它们。每次调用arc函数都会计算endAngle,因为它基于d.value

  3. 因此,如果您想要自定义角度计算,请完全不要致电pie,而是预先计算您的endAngle不要arc函数中执行此操作。

    arc变为:

    var arc = d3.arc()
      .innerRadius(function(d, i) {
        return  arcMin + i*(arcWidth) + arcPad;
      })
      .outerRadius(function(d, i) {
        return arcMin + (i+1)*(arcWidth);
      });
    

    预先计算数据:

    dataset.forEach(function(d,i){
      d.endAngle = 2*PI*d.value/100;
      d.startAngle = 0;
    });
    

    arcTween变为:

    .attrTween('d', function(d,i) {
      var inter = d3.interpolate(d.startAngle, d.endAngle);             
      return function(t) {
        d.endAngle = inter(t);
        return arc(d,i);
      }
    });
    

    运行代码:

    &#13;
    &#13;
     (function(d3) {
            'use strict';
    
     
            var dataset = [
              { label: 'a', value: 88, color : '#898989'},
              { label: 'b', value: 56 , color : '#898989'},
              { label: 'c', value: 20 , color : '#FDD000'},
              { label: 'd', value: 46 , color : '#898989'},
            ];
          
            var PI = Math.PI;
            var arcMin = 75;        // inner radius of the first arc
            var arcWidth = 25;      // width
            var arcPad = 10;         // padding between arcs
            var arcBgColor = "#DCDDDD";
          
            var width = 360;
            var height = 360;
            var radius = Math.min(width, height) / 2;
            var donutWidth = 15;                            // NEW
    
            var svg = d3.select('#canvas')
              .append('svg')
              .attr('width', width)
              .attr('height', height);
          
           var gBg = svg.append('g').attr('transform', 'translate(' + (width / 2) + 
                ',' + (height / 2) + ')');
           var g = svg.append('g')
              .attr('transform', 'translate(' + (width / 2) + 
                ',' + (height / 2) + ')');
    				
            var arc = d3.arc()
                      .innerRadius(function(d, i) {
                        return  arcMin + i*(arcWidth) + arcPad;
                      })
                      .outerRadius(function(d, i) {
                        return arcMin + (i+1)*(arcWidth);
                      });
    
            var arcBg = d3.arc()
                      .innerRadius(function(d, i) {
                        return  arcMin + i*(arcWidth) + arcPad;
                      })
                      .outerRadius(function(d, i) {
                        return arcMin + (i+1)*(arcWidth);
                      })
                      .startAngle(0 * (PI/180))
                      .endAngle(function(d, i) {
                        return 2*PI;
                      });
    			
            var pie = d3.pie()
              .value(function(d) { return d.value; })
              .sort(null);
    
          
            var pathBg = gBg.selectAll('path')
              .data(pie(dataset))
              .enter()
              .append('path')
              .attr('d', arcBg)
              .attr('fill', arcBgColor );
              
            dataset.forEach(function(d,i){
            	d.endAngle = 2*PI*d.value/100;
              d.startAngle = 0;
            });
            
            var path = g.selectAll('path')
              .data(dataset)
              .enter()
              .append('path')
              .attr('fill', function(d, i) { 
                return d.color;
              })
              .transition()
              .duration(800)
              .delay(function(d, i) {
               return i * 800;
              })
              .attrTween('d', function(d,i) {
                 var inter = d3.interpolate(d.startAngle, d.endAngle);             
                 return function(t) {
                   d.endAngle = inter(t);
                   return arc(d,i);
                 }
              });
    		
          })(window.d3);
    			
    &#13;
    <script src="https://cdn.jsdelivr.net/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/d3js/4.6.0/d3.min.js"></script>
       <div id="canvas"></div>
    &#13;
    &#13;
    &#13;