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) always return "M0,0Z"..
I found that the reason is when calling arc under arcTween, all d,i return undefine. How can i solve this.
Codes here: https://jsfiddle.net/m8oupfne/3/
Final product:
Couple things:
At first glance your attrTween
function doesn't work because your arc
function is dependent on both d,i
and you only pass d
to it.
But, fixing that doesn't make your chart transition nicely? Why? Because your arc function doesn't seem to make any sense. You use pie
to calculate angles and then overwrite them in your arc
function. And each call to the arc
function calculates endAngle
the same since it's based on d.value
.
So, if you want a custom angle calculation, don't call pie
at all, but pre-calculate your endAngle
and don't do it in your arc
function.
arc
becomes:
var arc = d3.arc()
.innerRadius(function(d, i) {
return arcMin + i*(arcWidth) + arcPad;
})
.outerRadius(function(d, i) {
return arcMin + (i+1)*(arcWidth);
});
Pre-calculate the data:
dataset.forEach(function(d,i){
d.endAngle = 2*PI*d.value/100;
d.startAngle = 0;
});
arcTween
becomes:
.attrTween('d', function(d,i) {
var inter = d3.interpolate(d.startAngle, d.endAngle);
return function(t) {
d.endAngle = inter(t);
return arc(d,i);
}
});
Running code:
(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);
<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>