2016-02-25 86 views
1

一直在尝试构建一个平滑渐变的饼图/圆环图,但发现它很难做出来。已经花了很多时间,如何解决这个问题仍然没有任何运气。我使用d3js库d3js饼图梯度

我有类似这样

enter image description here

的东西,想与渐变填充它,正是这样

enter image description here

任何意见,如何使它更接近它。也许你们中有人已经面对这个问题,并且有一些关于它的知识。

将不胜感激任何答案和建议。

+0

我同意,这是不是在所有琐碎的(除非有真可谓是一个SVG建 - 这样做,我很确定没有)。即使在Photoshop中这样做也是一个挑战。我能想到的达到这种效果的唯一方法是将弧分解成一堆具有固体填充或方向角与弧的切线角相匹配的线性梯度的较小弧段。可行,但不是微不足道的。 – meetamit

+0

你想要在每个“切片”上的渐变或整个事物的渐变? – Mark

+0

@标记是的,正好在整个馅饼上,顺利地从一个切片溢出到另一个切片,但它们之间有间隙。 –

回答

2

作为@meetamit在他的评论中说,没有内置的SVG方式,我可以找到产品圆形像你显示的渐变。但是,如果我们建立在这个优秀的answer上,我们可以很好地复制您的图表。

诀窍是制作一个360弧度的甜甜圈(每个度数一个)来自己创建渐变。然后我们可以使用pie计算,不包括弧在那里我们片填充应该是:

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" 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>