Q:

How do I externalize my d3 v4 pie chart labels?

I'm using d3 v4.  I want to move tabels out of my pie chart and have them point at the pie chart instead (because for small wedges it is not possible to read the labels).  I thought this would add external labels
// Now we'll draw our label lines, etc.
enteringLabels = labels.selectAll(".label").data(data).enter();
labelGroups = enteringLabels.append("g").attr("class", "label");
labelGroups.append("circle").attr({
    x: 0,
    y: 0,
    r: 2,
    fill: "#000",
    transform: function (d, i) {
        centroid = pied_arc.centroid(d);
        return "translate(" + pied_arc.centroid(d) + ")";
    },
        'class': "label-circle"
});

but the labels are not appearing externally -- https://jsfiddle.net/2df75xj0/1/ .  What else do I need to do to externalize the labels?

A:

var svg = d3.select("svg"),
    width = +500,
    height = +200,
    radius = Math.min(width, height) / 2,
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var labels = d3.select("#labels");

var color = d3.scaleOrdinal(["#98abc5", 
        "#8a89a6", 
        "#7b6888", 
        "#6b486b", 
        "#a05d56", 
        "#d0743c", 
        "#ff8c00",
        "#e34d01",
        "#ccff05",
        "#3e7eca",
        "#aa0092",
        "#b32e4f"]);

var pie = d3.pie()
    .sort(null)
    .value(function(d) { return d.market_cap; });

var path = d3.arc()
    .outerRadius(radius - 10)
    .innerRadius(0);

var outerArc = d3.arc()
     .innerRadius(radius * 0.9)
     .outerRadius(radius * 0.9);
 
      
var label = d3.arc()
    .outerRadius(radius - 40)
    .innerRadius(radius - 40);

var csvData = "currency,market_cap\n";
csvData += "Ethereum,28479743440\n"; 
csvData += "Ripple,8082383399\n"; 
csvData += "Bitcoin Cash,8767760760\n"; 
csvData += "Litecoin,3642098421\n"; 
csvData += "NEM,2514744000\n"; 
csvData += "Dash,2363329943\n"; 
csvData += "IOTA,1706859515\n"; 
csvData += "Ethereum Classic,1539824432\n"; 
csvData += "NEO,1138990000\n"; 
csvData += "Monero,1761024916\n"; 
csvData += "Stratis,569824176\n"; 
csvData += "Bitcoin,70807286162\n"; 
var data = d3.csvParse(csvData);
data.forEach(function(d) {
  d.market_cap = +d.market_cap;
  return d;
}); 

  var arc = g.selectAll(".arc")
    .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

      
      
  arc.append("path")
      .attr("d", path)
      .attr("fill", function(d) { return color(d.data.currency); });



// Now we'll draw our label lines, etc.

   
//--------------------------------------------

    arc.append("text")
      
      .attr("transform", function(d,i){
        var pos = outerArc.centroid(d);
        pos[0] = radius * (midAngle(d) < Math.PI ? 1.1 : -1.1);
        
    
  var percent = (d.endAngle - d.startAngle)/(2*Math.PI)*100
       if(percent<3){
       //console.log(percent)
       pos[1] += i*15
       }
        return "translate("+ pos +")";
      })
      .text(function(d) { return d.data.currency; })
      .attr("fill", function(d,i) { return color(i); })
      .attr("text-anchor", 'left')
      .attr("dx", function(d){
      var ac = midAngle(d) < Math.PI ? 0:-50
              return ac
      })
      .attr("dy", 5 )
      
      
     function midAngle(d) {
      return d.startAngle + (d.endAngle - d.startAngle) / 2;
    }

    var polyline = g.selectAll("polyline")
      .data(pie(data), function(d) {
        return d.data.currency;
      })
      .enter()
      .append("polyline")
      .attr("points", function(d,i) {
        var pos = outerArc.centroid(d);
            pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
         var o=   outerArc.centroid(d)
 var percent = (d.endAngle -d.startAngle)/(2*Math.PI)*100
       if(percent<3){
       //console.log(percent)
       o[1] 
       pos[1] += i*15
       }
       //return [label.centroid(d),[o[0],0[1]] , pos];
        return [label.centroid(d),[o[0],pos[1]] , pos];
      })
      .style("fill", "none")
      //.attr('stroke','grey')
      .attr("stroke", function(d,i) { return color(i); })
      .style("stroke-width", "1px");
<!DOCTYPE html>
<html>


<head>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script>

</head>

<svg width="700" height="400">
 <g id="labels" />
</svg>

</html>

