title: D3 update legend old data not removed
body: <p>I am a newbee in javascript, i followed an <a href="http://zeroviscosity.com/d3-js-step-by-step/step-3-adding-a-legend" rel="nofollow">example</a> to create a pie chart. I would like it to update with changes in select list. While the pie works, the legend list simply grows. </p>
  
  <p>I tried exit().remove() and selectAll("g").remove() and I saw in debug that "g" elements have been removed but the variable legend keeps growing in each update instead of removing the old data. Can anyone figure out why the code works with the pie while the legend won't work?</p>
  
  <p>Many thanks!</p>
  
  <p>Here is my code</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>    var app=angular.module("app",[]);
  
      // controller gets average json data and reform by host, produces executions
      app.controller("pieCtrl",function($scope,$http){
          $http.get("average.json").success(function(data){
              //executions- key:hostName, value:[listExecutions]
              var executions={};
              data.forEach(function(d){
                  if(!(d.hostName in executions)){
                      executions[d.hostName]={
                          hostName:d.hostName,
                          listExecutions:[]
                      }
                  }
                  executions[d.hostName].listExecutions.push(d);
              });
  
              //listHostnames for &lt;select&gt; [["host1"],["host2"]]
              $scope.ListHostnames=[];
              Object.keys(executions).forEach(function(hostName) {
                  $scope.ListHostnames.push(executions[hostName]);
              });
              //default value, bound to &lt;select&gt;
              $scope.selectedHostname = $scope.ListHostnames[2];
          }).error(function(err){
              throw err;
          });
      });
  
      app.directive("pie",function() {
          function link(scope,element,attr) {
              var wpie = 300;
              var hpie = 300;
              var outerRadius = wpie / 2;
              var innerRadius = outerRadius*0.5;
              var color = d3.scale.category10();
              var legendRectSize = 18;
              var legendSpacing = 4;
  
              scope.$watch('data', update);
  
              var pie = d3.layout.pie()
                      .value(function(d) {
                          return d.executionNum;
                      })
                      .sort(null);//prevent values from being sorted;
  
              var arc = d3.svg.arc()
                      .outerRadius(outerRadius)
                      .innerRadius(innerRadius);
            
              //svg must be outside update(), otherwise multiple charts will be created instead of updating one chart
              var svg = d3.select("#chart").append("svg")
                      .attr("width", wpie*2)
                      .attr("height", hpie*1.5)
                      .append("g")
                      .attr("transform", "translate(" + wpie / 2 + "," + hpie / 2 + ")");
  
              //tooltip
              var tooltip = d3.select('pie')
                      .append('div')
                      .attr('class', 'tooltip');
              tooltip.append('div')
                      .attr('class', 'date');
              tooltip.append('div')
                      .attr('class', 'num');
  
              function update(){
                  //clear what is left
                  svg.selectAll('path').remove();
  
                  //input data
                  if (!scope.$parent.selectedHostname){ return }
                  var data = scope.$parent.selectedHostname.listExecutions;
                  //bind data
                  var arcs = svg.selectAll("path")
                          .data(pie(data));
                  //append path for shapes
                  arcs.enter().append("path")
                          .attr("d", arc)
                          .attr("fill", function(d) {
                              return color((d.data.day));
                          })
                          .each(function(d){this._current=d;});// animation
  
                  //mouseover tooltip to show contents
                  arcs.on('mouseover', function(d) {
                      var num=(d.enabled)? d.data.executionNum :0;
                      tooltip.select('.date').html('Date: '+d.data.day+' / '+d.data.month);
                      tooltip.select('.num').html('Number of executions: '+num);
                      tooltip.style('display', 'block');
                  });
                  arcs.on('mouseout', function() {
                      tooltip.style('display', 'none');
                  });
  
                  //add labels
                  arcs.enter().append("text")
                          .attr("transform", function(d) {
                              return "translate(" + arc.centroid(d) + ")";
                          })
                          .attr("dy", ".35em")
                          .style("text-anchor", "middle")
                          .text(function(d) {
                              return d.data.executionNum;
                          })
                          .attr("fill","black");
  
                  svg.selectAll(".legend").remove();
                  svg.selectAll("g").remove();
                  svg.selectAll("g.legend").remove();
  
                  var legend = svg.selectAll('.legend')
                          .data(color.domain());
  
                  legend.exit().remove();
                
                  legend.enter()
                          .append('g')
                          .attr('class', 'legend')
                          .attr('transform', function(d, i) {
                              var height = legendRectSize + legendSpacing;
                              var offset =  height * color.domain().length / 2;
                              var horz = 10 * legendRectSize;
                              var vert = i * height - offset;
                              return 'translate(' + horz + ',' + vert + ')';
                          });
  
                  legend.append('circle')
                          .attr('cx', legendRectSize)
                          .attr('cy', legendRectSize)
                          .attr('r',8)
                          .style('fill', color)
                          .style('stroke', color)
                          .attr('class', 'legend');
  
                  legend.append('text')
                          .attr('x', legendRectSize + 4*legendSpacing)
                          .attr('y', legendRectSize +4)
                          .text(function(d) { return d; })
                          .attr('class', 'legend');
                  legend.exit().remove();
  
              }
          }
  
          return{
              link: link,
              restrict: 'E',
              scope: { data : '='}
  
          };
  
      })</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head lang="en"&gt;
      &lt;meta charset="UTF-8"&gt;
      &lt;title&gt;dynamic pie&lt;/title&gt;
  &lt;/head&gt;
  &lt;body ng-app="app" ng-controller="pieCtrl"&gt;
  &lt;h1&gt; Dynamic pie chart &lt;/h1&gt;
  &lt;div id="list"&gt;
  &lt;select ng-model="selectedHostname" ng-options="hostName as hostName.hostName for hostName in ListHostnames"&gt;&lt;/select&gt;
  &lt;/div&gt;
  &lt;div id="chart"&gt;
  &lt;pie data="selectedHostname"&gt;&lt;/pie&gt;
  &lt;/div&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>I'm using an angular controller to query the data and d3 code is in the pie directive. update function is called to refresh the chart. original data is a json file.
  <code>[{"durationSec":515,"month":2,"day":15.0,"executionNum":8,"hostName":"monitoring02"},{"durationSec":515,"month":2,"day":17.0,"executionNum":3,"hostName":"monitoring02"},{"durationSec":521,"month":2,"day":16.0,"executionNum":5,"hostName":"monitoring02"},{"durationSec":515,"month":2,"day":18.0,"executionNum":6,"hostName":"monitoring02"},{"durationSec":739,"month":2,"day":18.0,"executionNum":7,"hostName":"apple-pc"},{"durationSec":1140,"month":2,"day":19.0,"executionNum":7,"hostName":"apple-pc"},{"durationSec":1117,"month":2,"day":20.0,"executionNum":6,"hostName":"apple-pc"},{"durationSec":1125,"month":2,"day":21.0,"executionNum":3,"hostName":"monitoring01"},{"durationSec":1169,"month":2,"day":22.0,"executionNum":5,"hostName":"monitoring01"}]</code></p>