I am trying to figure out how to arrange shortcuts so that they do not overlap. Here is a chart image

As you can see, with really small values, text labels overlap. I tried iterating over each text element and changing its position, but this does not seem to work. At the bottom of this function, you can see the position of each text element, and then change it. What am I doing wrong? I have been with him for hours.
_renderDonutChart() { let self = this; // console.log("Donut Chart is beginning render") let textOffset = 14; self.graph.data[0].forEach(function (d) { d.value = +d.value; }) console.log(self.graph.data[0]) let boxSize = (self.options.radius + self.options.padding) * 2; let parent = d3.select(self.ui.parent); //let color = d3.scaleOrdinal(['#dc8710', '#9e3400', '#f19b12']); let color = d3.scaleOrdinal(d3.schemeCategory20c); let svg = parent.append('svg') .attr('width', boxSize * 2) .attr('height', boxSize) .attr('transform', 'translate(-111,0)') .append('g') .attr('transform', 'translate(' + boxSize + ',' + boxSize / 2 + ')'); svg.append('g') .attr('class', 'slices') svg.append("g") .attr("class", "labelName") svg.append("g") .attr("class", "labelValue") svg.append("g") .attr("class", "lines") svg.append("div") .attr("class", "progress-circle__box progress-circle__box--victorytype") let arc = d3.arc() .innerRadius(self.options.radius - self.options.border) .outerRadius(self.options.radius); let outerArc = d3.arc() .innerRadius((self.options.radius - self.options.border) * 1.2) .outerRadius((self.options.radius) * 1.2); let legendRectSize = self.options.radius * 0.05; let legendSpacing = self.options.radius * 0.02; let pie = d3.pie() .value(function(d) { return d.value; }) .sort(null); let slice = svg.select('.slices') .selectAll('path.slice') .data(pie(self.graph.data[0])) .enter() .append('path') .attr("class", "slice") .attr('d', arc) .attr('fill', function(d, i) { return color(d.data.label); }) .transition().duration(1000) .attrTween("d", function(d) { this._current = this._current || 0; var interpolate = d3.interpolate(this._current, d); this._current = interpolate(0); return function(t) { return arc(interpolate(t)); }; }) function midAngle(d){ return d.startAngle + (d.endAngle - d.startAngle)/2; } let text = svg.select(".labelName").selectAll("text") .data(pie(self.graph.data[0])) .enter() .append("text") .attr('class', 'label') .attr("dy", ".35em") .attr('transform', function(d) { // effectively computes the centre of the slice. // see https://github.com/d3/d3-shape/blob/master/README.md#arc_centroid var pos = outerArc.centroid(d); // changes the point to be on left or right depending on where label is. pos[0] = self.options.radius * 0.97 * (midAngle(d) < Math.PI ? 1 : -1); return 'translate(' + pos + ')'; }) .style('text-anchor', function(d) { // if slice centre is on the left, anchor text to start, otherwise anchor to end return (midAngle(d)) < Math.PI ? 'start' : 'end'; }) .style("fill", "white") .text(function(d) { return (" " + d.data.label+": " +d.value+""); }) .transition().duration(1000) .attrTween("transform", function(d) { this._current = this._current || d; var interpolate = d3.interpolate(this._current, d); this._current = interpolate(0); return function(t) { var d2 = interpolate(t); var pos = outerArc.centroid(d2); pos[0] = self.options.radius * (midAngle(d2) < Math.PI ? 1 : -1); return "translate("+ pos +")"; }; }) .styleTween("text-anchor", function(d){ this._current = this._current || d; var interpolate = d3.interpolate(this._current, d); this._current = interpolate(0); return function(t) { var d2 = interpolate(t); return midAngle(d2) < Math.PI ? "start":"end"; }; }) .text(function(d) { return (d.data.label+": "+d.value+"%"); }) let polyline = svg.select(".lines").selectAll("polyline") .data(pie(self.graph.data[0])) .enter() .append("polyline") .attr('points', function(d) { var pos = outerArc.centroid(d); pos[0] = self.options.radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1); return [arc.centroid(d), outerArc.centroid(d), pos] }) .style("fill", "none") .style("stroke", "white") .style("stroke-width", "1px"); let prev; text.each(function(d, i) { if(i > 0) { let thisbb = this.getBoundingClientRect(), prevbb = prev.getBoundingClientRect(); // move if they overlap console.log(thisbb.left); console.log(prevbb.right); if(!(thisbb.right < prevbb.left || thisbb.left > prevbb.right || thisbb.bottom < prevbb.top || thisbb.top > prevbb.bottom)) { var ctx = thisbb.left + (thisbb.right - thisbb.left)/2, cty = thisbb.top + (thisbb.bottom - thisbb.top)/2, cpx = prevbb.left + (prevbb.right - prevbb.left)/2, cpy = prevbb.top + (prevbb.bottom - prevbb.top)/2, off = Math.sqrt(Math.pow(ctx - cpx, 2) + Math.pow(cty - cpy, 2))/2; d3.select(this).attr("transform", "translate(" + Math.cos(((d.startAngle + d.endAngle - Math.PI) / 2)) * (self.options.radius + textOffset + off) + "," + Math.sin((d.startAngle + d.endAngle - Math.PI) / 2) * (self.options.radius + textOffset + off) + ")"); } } prev = this; }); // console.log("Donut Chart is ending render") }