问题
Have been trying to build a pie/donut chart with smooth gradient on it but figured out that it's quite difficult to make. Already spent a lot of time and still haven't any luck how to resolve that problem. I'm using d3js library
I have something similar to this
And want to fill it with gradient, exactly like this
Any advice how to make it more close to it. Maybe someone of you have already faced with that issue and have some knowledge about it.
Will be appreciate for any answers and advices.
回答1:
As @meetamit says in his comment, there's no built-in SVG way I can find to product a circular gradient like you show. However, if we build on this excellent answer we can replicate your chart pretty well.
The trick is to make a donut of 360 arcs (one for each degree) to create the gradient ourselves. We can then use the pie
calculation to not include the arcs where our slice padding should be:
<!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>
来源:https://stackoverflow.com/questions/35639290/d3js-pie-chart-gradient