title: d3 donut chart with labels
body: <p>I am new to d3.js any one help me ,I want donut revenue chart with total value at centre with two label separate outside circle.but ,I cannot add one more label outside the circle and middle total value.
  Here is my code,</p>
  
  <pre><code>&lt;script src="http://d3js.org/d3.v3.min.js"&gt;&lt;/script&gt;
  
    &lt;div id="pie-chart"&gt;&lt;/div&gt;
  
  &lt;script&gt;
  
      var div = d3.select("body").append("div").attr("class", "toolTip");
  
      var w = 650;
      var h = 400;
      var r = 100;
      var ir = 75;
      var textOffset = 24;
      var tweenDuration = 1050;
  
      //OBJECTS TO BE POPULATED WITH DATA LATER
      var lines, valueLabels, nameLabels;
      var pieData = [];    
      var oldPieData = [];
      var filteredPieData = [];
  
      //D3 helper function to populate pie slice parameters from array data
      var donut = d3.layout.pie().value(function(d){
        return d.itemValue;
      });
  
      //D3 helper function to create colors from an ordinal scale
      var color = d3.scale.category20c();
  
      //D3 helper function to draw arcs, populates parameter "d" in path object
      var arc = d3.svg.arc()
        .startAngle(function(d){ return d.startAngle; })
        .endAngle(function(d){ return d.endAngle; })
        .innerRadius(ir)
        .outerRadius(r);
  
      ///////////////////////////////////////////////////////////
      // GENERATE FAKE DATA /////////////////////////////////////
      ///////////////////////////////////////////////////////////
  
      var data;
      var dataStructure = [
         {
            "data":[
               {
  
                  "itemLabel":"Suv",
  
                  "itemValue":7165.0
               },
               {
  
                  "itemLabel":"Sedans",
                  "itemValue":2430.0
               },
               {
  
                   "itemLabel":"Hatchback",
                  "itemValue":1998.0
               },
               {
  
                  "itemLabel":"VAN",
                  "itemValue": 898.0
  
               },
            ],
            "label":"2007"
         }, 
      ];
  
      ///////////////////////////////////////////////////////////
      // CREATE VIS &amp; GROUPS ////////////////////////////////////
      ///////////////////////////////////////////////////////////
  
      var vis = d3.select("#pie-chart").append("svg:svg")
        .attr("width", w)
        .attr("height", h);
  
      //GROUP FOR ARCS/PATHS
      var arc_group = vis.append("svg:g")
        .attr("class", "arc")
        .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
  
      //GROUP FOR LABELS
      var label_group = vis.append("svg:g")
        .attr("class", "label_group")
        .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
  
      //GROUP FOR CENTER TEXT  
      var center_group = vis.append("svg:g")
        .attr("class", "center_group")
        .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
  
      //PLACEHOLDER GRAY CIRCLE
      // var paths = arc_group.append("svg:circle")
      //     .attr("fill", "#EFEFEF")
      //     .attr("r", r);
  
      ///////////////////////////////////////////////////////////
      // CENTER TEXT ////////////////////////////////////////////
      ///////////////////////////////////////////////////////////
  
      //WHITE CIRCLE BEHIND LABELS
      var whiteCircle = center_group.append("svg:circle")
        .attr("fill", "white")
        .attr("r", ir);
  
      ///////////////////////////////////////////////////////////
      // STREAKER CONNECTION ////////////////////////////////////
      ///////////////////////////////////////////////////////////
  
      // to run each time data is generated
      function update(number) {
  
        data = dataStructure[number].data;
  
        oldPieData = filteredPieData;
        pieData = donut(data);
  
        var sliceProportion = 0; //size of this slice
        filteredPieData = pieData.filter(filterData);
        function filterData(element, index, array) {
          element.name = data[index].itemLabel;
          element.value = data[index].itemValue;
          sliceProportion += element.value;
          return (element.value &gt; 0);
        }
  
          //DRAW ARC PATHS
          paths = arc_group.selectAll("path").data(filteredPieData);
          paths.enter().append("svg:path")
            .attr("stroke", "white")
            .attr("stroke-width", 0.5)
            .attr("fill", function(d, i) { return color(i); })
            .transition()
              .duration(tweenDuration)
              .attrTween("d", pieTween);
          paths
            .transition()
              .duration(tweenDuration)
              .attrTween("d", pieTween);
          paths.exit()
            .transition()
              .duration(tweenDuration)
              .attrTween("d", removePieTween)
            .remove();
  
      paths.on("mousemove", function(d){
          div.style("left", d3.event.pageX+10+"px");
                div.style("top", d3.event.pageY-25+"px");
                div.style("display", "inline-block");
          div.html((d.data.itemLabel)+"&lt;br&gt;"+(d.data.itemValue));
      });
  
      paths.on("mouseout", function(d){
          div.style("display", "none");
      });
  
  
  
  
          //DRAW TICK MARK LINES FOR LABELS
          lines = label_group.selectAll("line").data(filteredPieData);
          lines.enter().append("svg:line")
            .attr("x1", 0)
            .attr("x2", 0)
            .attr("y1", -r-3)
            .attr("y2", -r-18)
            .attr("stroke", "gray")
            .attr("transform", function(d) {
              return "rotate(" + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + ")";
            });
          lines.transition()
            .duration(tweenDuration)
            .attr("transform", function(d) {
              return "rotate(" + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + ")";
            });
          lines.exit().remove();
      //DRAW LABELS WITH PERCENTAGE VALUES
          valueLabels = label_group.selectAll("text.value").data(filteredPieData)
            .attr("dy", function(d){
              if ((d.startAngle+d.endAngle)/2 &gt; Math.PI/2 &amp;&amp; (d.startAngle+d.endAngle)/2 &lt; Math.PI*1.5 ) {
                return 5;
              } else {
                return -7;
              }
            })
            .attr("text-anchor", function(d){
              if ( (d.startAngle+d.endAngle)/2 &lt; Math.PI ){
                return "beginning";
              } else {
                return "end";
              }
            })
            .text(function(d){
              var percentage = (d.value/sliceProportion)*100;
              return percentage.toFixed(1) + "%";
            });
  
          valueLabels.enter().append("svg:text")
            .attr("class", "value")
            .attr("transform", function(d) {
              return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")";
            })
            .attr("dy", function(d){
              if ((d.startAngle+d.endAngle)/2 &gt; Math.PI/2 &amp;&amp; (d.startAngle+d.endAngle)/2 &lt; Math.PI*1.5 ) {
                return 5;
              } else {
                return -7;
              }
            })
            .attr("text-anchor", function(d){
              if ( (d.startAngle+d.endAngle)/2 &lt; Math.PI ){
                return "beginning";
              } else {
                return "end";
              }
            }).text(function(d){
              var percentage = (d.value/sliceProportion)*100;
              return percentage.toFixed(1) + "%";
            });
          valueLabels.transition().duration(tweenDuration).attrTween("transform", textTween);
  
          valueLabels.exit().remove();
  
          //DRAW LABELS WITH ENTITY NAMES
          nameLabels = label_group.selectAll("text.units").data(filteredPieData)
            .attr("dy", function(d){
              if ((d.startAngle+d.endAngle)/2 &gt; Math.PI/2 &amp;&amp; (d.startAngle+d.endAngle)/2 &lt; Math.PI*1.5 ) {
                return 17;
              } else {
                return 5;
              }
            })
            .attr("text-anchor", function(d){
              if ((d.startAngle+d.endAngle)/2 &lt; Math.PI ) {
                return "beginning";
              } else {
                return "end";
              }
            }).text(function(d){
              return d.name;
            });
  
          nameLabels.enter().append("svg:text")
            .attr("class", "units")
            .attr("transform", function(d) {
              return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")";
            })
            .attr("dy", function(d){
              if ((d.startAngle+d.endAngle)/2 &gt; Math.PI/2 &amp;&amp; (d.startAngle+d.endAngle)/2 &lt; Math.PI*1.5 ) {
                return 18;
              } else {
                return 5;
              }
            })
            .attr("text-anchor", function(d){
              if ((d.startAngle+d.endAngle)/2 &lt; Math.PI ) {
                return "beginning";
              } else {
                return "end";
              }
            }).text(function(d){
              return d.name;
            });
  
          nameLabels.transition().duration(tweenDuration).attrTween("transform", textTween);
  
          nameLabels.exit().remove();
  
      }
  
  
  
      ///////////////////////////////////////////////////////////
      // FUNCTIONS //////////////////////////////////////////////
      ///////////////////////////////////////////////////////////           
      // Interpolate the arcs in data space.
      function pieTween(d, i) {
        var s0;
        var e0;
        if(oldPieData[i]){
          s0 = oldPieData[i].startAngle;
          e0 = oldPieData[i].endAngle;
        } else if (!(oldPieData[i]) &amp;&amp; oldPieData[i-1]) {
          s0 = oldPieData[i-1].endAngle;
          e0 = oldPieData[i-1].endAngle;
        } else if(!(oldPieData[i-1]) &amp;&amp; oldPieData.length &gt; 0){
          s0 = oldPieData[oldPieData.length-1].endAngle;
          e0 = oldPieData[oldPieData.length-1].endAngle;
        } else {
          s0 = 0;
          e0 = 0;
        }
        var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
        return function(t) {
          var b = i(t);
          return arc(b);
        };
  
  
      }
  
      function removePieTween(d, i) {
        s0 = 2 * Math.PI;
        e0 = 2 * Math.PI;
        var i = d3.interpolate({startAngle: d.startAngle, endAngle: d.endAngle}, {startAngle: s0, endAngle: e0});
        return function(t) {
          var b = i(t);
          return arc(b);
        };
      }
  
      function textTween(d, i) {
        var a;
        if(oldPieData[i]){
          a = (oldPieData[i].startAngle + oldPieData[i].endAngle - Math.PI)/2;
        } else if (!(oldPieData[i]) &amp;&amp; oldPieData[i-1]) {
          a = (oldPieData[i-1].startAngle + oldPieData[i-1].endAngle - Math.PI)/2;
        } else if(!(oldPieData[i-1]) &amp;&amp; oldPieData.length &gt; 0) {
          a = (oldPieData[oldPieData.length-1].startAngle + oldPieData[oldPieData.length-1].endAngle - Math.PI)/2;
        } else {
          a = 0;
        }
        var b = (d.startAngle + d.endAngle - Math.PI)/2;
  
        var fn = d3.interpolateNumber(a, b);
        return function(t) {
          var val = fn(t);
          return "translate(" + Math.cos(val) * (r+textOffset) + "," + Math.sin(val) * (r+textOffset) + ")";
  
  
        };
  
      }
      update(0);
      &lt;/script&gt;
  
  
  
      css:
      body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        margin: auto;
        position: relative;
        font-weight: 300;
      }
  
      #pie-chart {
        background-color: #ffffff;
        /*border: 1px solid gray;*/
        font: 10px sans-serif;
        height: 400px;
        text-shadow: none;
        width: 650px;
        margin-left: auto;
        margin-right:auto;
      }
      #pie-chart .total{
        font-size: 18px;
        font-weight: bold;
      }
      #pie-chart .units{
        fill: gray;
        font-size: 12px;
      }
      #pie-chart .label{
        fill: #CCC;
        font-size: 12px;
      }
      #pie-chart .value{
        font-size: 14px;
      }
  
      #slider label {
          position: absolute;
          width: 20px;
          margin-left: -20px;
          text-align: center;
          margin-top: 30px;
          font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      }
  
      .toolTip {
          position: absolute;
          display: none;
          width: auto;
          height: auto;
          background: none repeat scroll 0 0 white;
          border: 0 none;
          border-radius: 8px 8px 8px 8px;
          box-shadow: -3px 3px 15px #888888;
          color: black;
          font: 12px sans-serif;
          padding: 5px;
          text-align: center;
      }
  </code></pre>