Fiddle: https://jsfiddle.net/vpkarep8/
I have three pie charts that are animating when updating with new data and I can't seem to get the labels to properly update. A fiddle is attached above.
To get the text to change, I've had to do another data join on the text (line 486-489), but then I am unable to use arc.centroid(). Narrowed it down to how I'm handing the update, but don't know the best way to handle all this. Seems centroid needs d, but to update the text needs d.values.
Any thoughts?
Tried the answers from Label outside arc (Pie chart) d3.js and How to update both the content and location of text labels on a D3 pie chart.
function drawESGraph() {
d3.selectAll('.ES__graph__container svg')
.remove();
d3.selectAll('.ES__buttons button')
.remove();
var $container = $('.ES__graph__container');
var width = $container.width() / 3;
var m = 40,
r = width / 3,
labelr = r + 20;
var arc = d3.svg.arc()
.outerRadius(r)
.innerRadius(r / 2);
var pie = d3.layout.pie()
.value(function(d) {
return +d.val;
})
.sort(null);
var allBrands = d3.set(data.map(function(d) {
return d.brand;
})).values();
var buttons = d3.select('.ES__buttons')
.selectAll('button')
.data(allBrands)
.enter()
.append('button')
.attr('class', function(d) {
return d + ' button';
})
.text(function(d) {
return d;
})
.on('click', function(d) {
updateChart(d);
})
.style('opacity', 0);
buttons.transition().duration(1000)
.style('opacity', 1);
d3.select('.brand1.button')
.attr('class', 'brand1 button active');
function updateChart(brand) {
var brandData = data.filter(function(d) {
return d.brand === brand;
});
var brandDataByYear = d3.nest()
.key(function(d) {
return d.year;
})
.entries(brandData);
var svg = d3.select('.ES__graph__container')
.selectAll('svg')
.data(brandDataByYear)
.enter()
.append('svg')
.style('margin-top', '25px')
.attr('width', (r + m) * 2)
.attr('height', (r + m) * 2)
.attr('id', function(d, i) {
return 'pie' + i;
})
.append('svg:g')
.attr('transform', 'translate(' + (r + m) + ',' + (r + m) + ')');
var pieLabel = svg.append('svg:text')
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.text(function(d) {
return d.key;
})
.style('fill', 'black')
.style('opacity', 0);
pieLabel.transition().duration(1000)
.style('opacity', 1);
var slice = svg.selectAll('.arc')
.data(function(d) {
return pie(d.values);
})
.enter()
.append('g')
.attr('class', 'arc');
var path = slice.append('svg:path')
.attr('d', arc)
.attr('class', function(d) {
return 'arc ' + d.data.platform;
})
.each(function(d) {
this._current = d;
});
var text = slice.append('text')
.text(function(d) {
if (d.data.val > 0) {
return d.data.val + '%';
}
})
.attr('transform', function(d) {
if (d.data.val > 3) {
return 'translate(' + arc.centroid(d) + ')';
} else {
var c = arc.centroid(d),
x = c[0],
y = c[1],
h = Math.sqrt(x * x + y * y);
return 'translate(' + (x / h * labelr) + ',' + (y / h * labelr) + ')';
}
})
.attr('text-anchor', function(d) {
if (d.data.val < 3) {
return (d.endAngle + d.startAngle) / 2 > Math.PI ? 'end' : 'start';
}
})
.attr('dx', function(d) {
return d.data.val > 3 ? -15 : 18;
})
.attr('dy', function(d) {
return d.data.val > 3 ? 5 : 3;
})
.style('fill', function(d) {
return d.data.val > 3 ? 'white' : 'black';
})
.attr('class', 'label');
change();
function change() {
var newdata = brandDataByYear;
for (x in newdata) {
var nslice = d3.select('#pie' + x)
.data(newdata);
var npath = nslice.selectAll('path')
.data(function(d) {
return pie(d.values);
})
.attr('class', function(d) {
return 'arc ' + d.data.platform;
});
npath.transition().duration(1000)
.attrTween('d', arcTween);
npath.exit()
.remove();
var ntext = nslice.selectAll('.label')
.data(function(d) {
return d.values;
})
.style('opacity', 0);
ntext.transition().duration(1000)
.style('opacity', 1)
.text(function(d) {
if (d.val > 0) {
return d.val + '%';
}
})
// .attr("transform", function(d) {
// return "translate(" +
// ( (radius - 12) * Math.sin( ((d.endAngle - d.startAngle) / 2) + d.startAngle ) ) +
// ", " +
// ( -1 * (radius - 12) * Math.cos( ((d.endAngle - d.startAngle) / 2) + d.startAngle ) ) +
// ")";
// })
// .style("text-anchor", function(d) {
// var rads = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
// if ( (rads > 7 * Math.PI / 4 && rads < Math.PI / 4) || (rads > 3 * Math.PI / 4 && rads < 5 * Math.PI / 4) ) {
// return "middle";
// } else if (rads >= Math.PI / 4 && rads <= 3 * Math.PI / 4) {
// return "start";
// } else if (rads >= 5 * Math.PI / 4 && rads <= 7 * Math.PI / 4) {
// return "end";
// } else {
// return "middle";
// }
// })
// ntext.exit()
// .remove();
}
}
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
}
}
}
updateChart('brand1');
}
drawESGraph();