d3js饼图渐变

d3js Pie chart gradient

一直在尝试构建一个具有平滑渐变的 pie/donut 图表,但发现它很难制作。已经花了很多时间,但仍然没有运气如何解决该问题。我正在使用 d3js 库

我有类似的东西

并且想用渐变填充它,就像这样

任何建议如何使它更接近它。也许你们中的某些人已经面对过这个问题并且对此有所了解。

如有任何答案和建议,我们将不胜感激。

正如@meetamit 在他的评论中所说,没有内置的 SVG 方法可以像您展示的那样生成 circular 渐变。但是,如果我们以这个出色的 answer 为基础,我们可以很好地复制您的图表。

诀窍是制作一个 360 弧形圆环(每个弧度一个)来自己创建渐变。然后我们可以使用 pie 计算来不包括我们的切片填充应该是的弧:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  </head>

  <body>
    <script>
    
      // sample data
      var data = [10,20,30,40,50];
    
      var height = 500,
          width = 500,
          radius = 200,
          padding = 0.04;
      
      var svg = d3.select('body')
        .append('svg')
        .attr('width', width)
        .attr('height', height)
        .append('g')
        .attr('transform', 'translate(' + width/2 + ',' + width/2 + ')');
        
      var arc = d3.svg.arc()
        .innerRadius(radius - 100)
        .outerRadius(radius);
      
      // pie the data
      var pie = d3.layout.pie()
        .sort(null)
        .value(function(d) { return d; });
      data = pie(data);

      // create our gradient
      var colors = [],
          slice = 0,
          inPad = false;
      // 360 degrees
      d3.range(360).forEach(function(d, i) {
        // convert to radians
        var start = i * (Math.PI / 180),
            end = (i + 1) * (Math.PI / 180);
        // if we are in a padding area
        if ( Math.abs(data[slice].startAngle - start) < padding || 
            Math.abs(data[slice].endAngle - start) < padding ) {
          inPad = true;
        } else {
          // when to move to next slice
          if (inPad){
            // move to next slice
            slice++;
            // "stick" on last slice
            if (slice >= data.length) slice = 4;
          }
          inPad = false;
        }
        // only push if not in padding
        if (!inPad){
          colors.push({
            startAngle: start,
            endAngle: end,
            fill: d3.hsl(i, 1, .5).toString()
          });
        }
      });
      // add arcs
      svg.selectAll('.arc')
        .data(colors)
        .enter()
        .append('path')
        .attr('class', 'arc')
        .attr('d', arc)
        .style('fill', function(d){
          return d.fill;
        })
        .style('stroke',function(d){
          return d.fill;
        });
    </script>
  </body>

</html>