I am using angular and d3 to create a donut (in a directive).
I can quite simply give the filled area a colour (in this plunker it is blue). But what i want to do is have the SVG change its colours smoothly from:
0% - 33.3% - red
33.4% - 66.66% - orange
66.7% - 100% green
Directive:
app.directive('donutDirective', function() {
return {
restrict: 'E',
scope: {
radius: '=',
percent: '=',
text: '=',
},
link: function(scope, element, attrs) {
var radius = scope.radius,
percent = scope.percent,
percentLabel = scope.text,
format = d3.format(".0%"),
progress = 0;
var svg = d3.select(element[0])
.append('svg')
.style('width', radius/2+'px')
.style('height', radius/2+'px');
var donutScale = d3.scale.linear()
.domain([0, 100])
.range([0, 2 * Math.PI]);
//var color = "#5599aa";
var color = "#018BBB";
var data = [
[0,100,"#b8b5b8"],
[0,0,color]
];
var arc = d3.svg.arc()
.innerRadius(radius/6)
.outerRadius(radius/4)
.startAngle(function(d){return donutScale(d[0]);})
.endAngle(function(d){return donutScale(d[1]);});
var text = svg.append("text")
.attr("x",radius/4)
.attr("y",radius/4)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.attr("font-size","14px")
.style("fill","black")
.attr("text-anchor", "middle")
.text(percentLabel);
var path = svg.selectAll("path")
.data(data)
.enter()
.append("path")
.style("fill", function(d){return d[2];})
.attr("d", arc)
.each(function(d) {
this._current = d;
// console.log(this._current)
;});
// update the data!
data = [
[0,100,"#b8b5b8"],
[0,percent,color]
];
path
.data(data)
.attr("transform", "translate("+radius/4+","+radius/4+")")
.transition(200).duration(2150).ease('linear')
.attrTween("d", function (a) {
var i = d3.interpolate(this._current, a);
var i2 = d3.interpolate(progress, percent)
this._current = i(0);
// console.log(this._current);
return function(t) {
text.text( format(i2(t) / 100) );
return arc(i(t));
};
});
}
};
});
Plunker: http://plnkr.co/edit/8qGMeQkmM08CZxZIVRei?p=preview
Assuming that you want a color transition/scale like this one:
See working code for this: http://codepen.io/anon/pen/vLVmyV
You can smothly make the color transition using a d3 linear scale like this:
Then, when you update the path (with the attrTween) to make the filling animation, take only the Path the represents the filled part of the donut, lets call it colorPath and change the fill of it adding the following like in the tween:
Your attrTween will look like this:
Please note that we only update the data for the colorPath:
colorPath.data([[0,percent,color]])
The whole working example is right here: http://plnkr.co/edit/ox82vGxhcaoXJpVpUel1?p=preview
First give Id to the path like this:
Then inside the tween pass the condition and change the color of the path
Working code here
EDIT
Inside your directive you can make
gradient
inside yourdefs
like this:Then in the path you can define the gradient like this:
Working code here
Hope this helps!