title: D3: How to use exit().remove() for Multi-Series Line Chart
body: <p>For the Multi-Series Line Chart of d3 (<code>d3.v4.js</code>):</p>
  
  <p><a href="https://bl.ocks.org/mbostock/3884955" rel="nofollow noreferrer">https://bl.ocks.org/mbostock/3884955</a></p>
  
  <p>how has the <code>exit().remove()</code> functionality to be applied, if I want to redraw the chart with different input data?</p>
  
  <pre><code>function myGraphic(myData) {
      var svg = d3.select("svg"),
          margin = {top: 20, right: 80, bottom: 30, left: 50},
          width = svg.attr("width") - margin.left - margin.right,
          height = svg.attr("height") - margin.top - margin.bottom,
          g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
  
      var x = d3.scaleTime().range([0, width]),
          y = d3.scaleLinear().range([height, 0]),
          z = d3.scaleOrdinal(d3.schemeCategory10);
  
      var line = d3.line()
          .x(function (d) {
              return x(d.date);
          })
          .y(function (d) {
              return y(d.temperature);
          });
  
      //noinspection JSUnresolvedVariable
      var data = myData.dataList;
  
      //noinspection JSUnresolvedVariable
      data.columns = ["date", "value1", myData.referenceName];
  
      var cities = data.columns.slice(1).map(function (id) {
          return {
              id: id,
              values: data.map(function (d) {
                  return {date: d.date, temperature: d[id]};
              })
          };
      });
  
  
      x.domain(d3.extent(data, function (d) {
          return d.date;
      }));
  
      y.domain([
          d3.min(cities, function (c) {
              return d3.min(c.values, function (d) {
                  return d.temperature;
              });
          }),
          d3.max(cities, function (c) {
              return d3.max(c.values, function (d) {
                  return d.temperature;
              });
          })
      ]);
  
      z.domain(cities.map(function (c) {
          return c.id;
      }));
  
      var xAxisScale2 = d3.scaleTime()
          .domain([new Date(2014, 0, 1), new Date(2016, 0, 1, 0)])
          .rangeRound([20, width - 20]);
  
      var xAxis = d3.axisBottom(x);
  
  
      g.append("g")
          .attr("class", "axis axis--x")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis.ticks(d3.timeYear));
  
      g.append("g")
          .attr("class", "axis axis--y")
          .call(d3.axisLeft(y))
          .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", "0.71em")
          .attr("fill", "#000")
          .text("Temperature");
  
  
      var city = g.selectAll(".city")
          .data(cities)
          .enter().append("g")
          .attr("class", "city");
  
  
      city.append("path")
          .attr("class", "line")
          .attr("d", function (d) {
              return line(d.values);
          })
          .style("stroke", function (d) {
              return z(d.id);
          });
  
      city.append("text")
          .datum(function (d) {
              return {id: d.id, value: d.values[d.values.length - 1]};
          })
          .attr("transform", function (d) {
              return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
          })
          .attr("x", 3)
          .attr("dy", "0.35em")
          .style("font", "10px sans-serif")
          .text(function (d) {
              return d.id;
          });
  
      city.exit().remove();
  
  }
  </code></pre>
  
  <p><strong><em>UPDATE:</em></strong></p>
  
  <p>I tried to incorporate the proposal <a href="https://stackoverflow.com/a/42729725">of @Gerardo Furtado</a>  but something seems still to be wrong here:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;style&gt;
  
      .axis--x path {
          display: none;
      }
  
      .line {
          fill: none;
          stroke: steelblue;
          stroke-width: 1.5px;
      }
  
  &lt;/style&gt;
  &lt;button&gt;Click me&lt;/button&gt;
  &lt;svg width="960" height="500"&gt;&lt;/svg&gt;
  &lt;!--&lt;script src="//d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;--&gt;
  &lt;script src="d3.v4.js"&gt;&lt;/script&gt;
  
  &lt;!--&lt;script src="v03-exit-funktioniert-3-evolution.js"&gt;&lt;/script&gt;--&gt;
  
  &lt;script&gt;
  
      var svg = d3.select("svg"),
          margin = {top: 20, right: 80, bottom: 30, left: 50},
          width = svg.attr("width") - margin.left - margin.right,
          height = svg.attr("height") - margin.top - margin.bottom,
          g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
      var parseTime = d3.timeParse("%Y%m%d");
  
      var x = d3.scaleTime().range([0, width]),
          y = d3.scaleLinear().range([height, 0]),
          z = d3.scaleOrdinal(d3.schemeCategory10);
  
      var line = d3.line()
          .curve(d3.curveBasis)
          .x(function (d) {
              return x(d.date);
          })
          .y(function (d) {
              return y(d.temperature);
          });
  
      var data = [
          {"date": "1136156400000", "New York": 63.4, "San Francisco": 62.7, "Austin": 72.2},
          {"date": "1167692400000", "New York": 58.0, "San Francisco": 59.9, "Austin": 67.7},
          {"date": "1199228400000", "New York": 53.3, "San Francisco": 59.1, "Austin": 69.4},
          {"date": "1230850800000", "New York": 55.7, "San Francisco": 58.8, "Austin": 68.0},
          {"date": "1262386800000", "New York": 62.3, "San Francisco": 55.1, "Austin": 71.9}];
  
      var data2 = [
          {"date": "1136156400000", "New York": 163.4, "San Francisco": 262.7, "Austin": 372.2},
          {"date": "1167692400000", "New York": 158.0, "San Francisco": 259.9, "Austin": 367.7},
          {"date": "1199228400000", "New York": 153.3, "San Francisco": 259.1, "Austin": 369.4},
          {"date": "1230850800000", "New York": 155.7, "San Francisco": 258.8, "Austin": 368.0},
          {"date": "1262386800000", "New York": 162.3, "San Francisco": 255.1, "Austin": 371.9}];
  
  
      // d3.tsv("data.tsv", type, function (error, data) {
      //     if (error) throw error;
  
      data.columns = ["date", "New York", "San Francisco", "Austin"];
  
      var cities = data.columns.slice(1).map(function (id) {
          return {
              id: id,
              values: data.map(function (d) {
                  return {date: d.date, temperature: d[id]};
              })
          };
      });
  
      x.domain(d3.extent(data, function (d) {
          return d.date;
      }));
  
      y.domain([
          d3.min(cities, function (c) {
              return d3.min(c.values, function (d) {
                  return d.temperature;
              });
          }),
          d3.max(cities, function (c) {
              return d3.max(c.values, function (d) {
                  return d.temperature;
              });
          })
      ]);
      g.append("g")
          .attr("class", "axis axis--x")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));
      g.append("g")
          .attr("class", "axis axis--y")
          .call(d3.axisLeft(y))
          .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", "0.71em")
          .attr("fill", "#000")
          .text("Temperature, ºF");
      update();
      d3.select("button").on("click", function () {
          // cities.splice(0, 1);
          data = data2;
          console.log(cities);
  //            console.log(JSON.stringify(cities));
          update();
      });
  
      function update() {
          data.columns = ["date", "New York", "San Francisco", "Austin"];
          cities = data.columns.slice(1).map(function (id) {
              return {
                  id: id,
                  values: data.map(function (d) {
                      return {date: d.date, temperature: d[id]};
                  })
              };
          });
  
  
          x.domain(d3.extent(data, function (d) {
              return d.date;
          }));
          y.domain([
              d3.min(cities, function (c) {
                  return d3.min(c.values, function (d) {
                      return d.temperature;
                  });
              }),
              d3.max(cities, function (c) {
                  return d3.max(c.values, function (d) {
                      return d.temperature;
                  });
              })
          ]);
          z.domain(cities.map(function (c) {
              return c.id;
          }));
          var city = g.selectAll(".city")
              .data(cities);
          city.exit().remove();
          var cityEnter = city.enter().append("g")
              .attr("class", "city");
          cityEnter.append("path")
              .attr("class", "line")
              .attr("d", function (d) {
                  return line(d.values);
              })
              .style("stroke", function (d) {
                  return z(d.id);
              });
          cityEnter.append("text")
              .datum(function (d) {
                  return {id: d.id, value: d.values[d.values.length - 1]};
              })
              .attr("transform", function (d) {
                  return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
              })
              .attr("x", 3)
              .attr("dy", "0.35em")
              .style("font", "10px sans-serif")
              .text(function (d) {
                  return d.id;
              });
      }
      // });
  
      function type(d, _, columns) {
          d.date = parseTime(d.date);
          for (var i = 1, n = columns.length, c; i &lt; n; ++i) d[c = columns[i]] = +d[c];
          return d;
      }
  
  
  &lt;/script&gt; 
  </code></pre>
  
  <p><strong><em>UPDATE2:</em></strong></p>
  
  <p>There is (hopefully) just one topic open regarding label names and their position:</p>
  
  <pre><code>&lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
  &lt;style&gt;
      .axis--x path {
          display: none;
      }
  
      .line {
          fill: none;
          stroke: steelblue;
          stroke-width: 1.5px;
      }
  
  &lt;/style&gt;
  &lt;button&gt;Click me&lt;/button&gt;
  &lt;svg width="960" height="500"&gt;&lt;/svg&gt;
  &lt;!--&lt;script src="//d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;--&gt;
  &lt;script src="d3.v4.js"&gt;&lt;/script&gt;
  
  &lt;!--&lt;script src="v03-exit-funktioniert-3-evolution.js"&gt;&lt;/script&gt;--&gt;
  
  &lt;script&gt;
      var svg = d3.select("svg"),
          margin = {
              top: 20,
              right: 80,
              bottom: 30,
              left: 50
          },
          width = svg.attr("width") - margin.left - margin.right,
          height = svg.attr("height") - margin.top - margin.bottom,
          g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
      var parseTime = d3.timeParse("%Y%m%d");
  
      var x = d3.scaleTime().range([0, width]),
          y = d3.scaleLinear().range([height, 0]),
          z = d3.scaleOrdinal(d3.schemeCategory10);
  
      var line = d3.line()
          .curve(d3.curveBasis)
          .x(function (d) {
              return x(d.date);
          })
          .y(function (d) {
              return y(d.temperature);
          });
  
      var data = [{
          "date": "1136156400000",
          "Old York": 63.4,
          "San Francisco": 62.7,
          "Austin": 72.2
      }, {
          "date": "1167692400000",
          "Old York": 58.0,
          "San Francisco": 59.9,
          "Austin": 67.7
      }, {
          "date": "1199228400000",
          "Old York": 53.3,
          "San Francisco": 59.1,
          "Austin": 69.4
      }, {
          "date": "1230850800000",
          "Old York": 55.7,
          "San Francisco": 58.8,
          "Austin": 68.0
      }, {
          "date": "1262386800000",
          "Old York": 62.3,
          "San Francisco": 55.1,
          "Austin": 71.9
      }];
  
      var data2 = [{
          "date": "1136156400000",
          "New York": 263.4,
          "San Francisco": 262.7,
          "Austin": 372.2
      }, {
          "date": "1167692400000",
          "New York": 458.0,
          "San Francisco": 259.9,
          "Austin": -367.7
      }, {
          "date": "1199228400000",
          "New York": 153.3,
          "San Francisco": 259.1,
          "Austin": 369.4
      }, {
          "date": "1230850800000",
          "New York": 155.7,
          "San Francisco": 258.8,
          "Austin": 368.0
      }, {
          "date": "1262386800000",
          "New York": 162.3,
          "San Francisco": 255.1,
          "Austin": 371.9
      }];
  
  
      // d3.tsv("data.tsv", type, function (error, data) {
      //     if (error) throw error;
  
      data.columns = ["date", "Old York", "San Francisco", "Austin"];
  
      var cities = data.columns.slice(1).map(function (id) {
          return {
              id: id,
              values: data.map(function (d) {
                  return {
                      date: d.date,
                      temperature: d[id]
                  };
              })
          };
      });
  
      x.domain(d3.extent(data, function (d) {
          return d.date;
      }));
  
      y.domain([
          d3.min(cities, function (c) {
              return d3.min(c.values, function (d) {
                  return d.temperature;
              });
          }),
          d3.max(cities, function (c) {
              return d3.max(c.values, function (d) {
                  return d.temperature;
              });
          })
      ]);
      g.append("g")
          .attr("class", "axis axis--x")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));
      g.append("g")
          .attr("class", "axis axis--y")
          .call(d3.axisLeft(y))
          .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", "0.71em")
          .attr("fill", "#000")
          .text("Temperature, ºF");
      update();
      d3.select("button").on("click", function () {
          // cities.splice(0, 1);
          data = data2;
          data.columns = ["date", "New York", "San Francisco", "Austin"];
          //            console.log(JSON.stringify(cities));
          update();
      });
  
      function update() {
          cities = data.columns.slice(1).map(function (id) {
              return {
                  id: id,
                  values: data.map(function (d) {
                      return {
                          date: d.date,
                          temperature: d[id]
                      };
                  })
              };
          });
  
  
          x.domain(d3.extent(data, function (d) {
              return d.date;
          }));
          y.domain([
              d3.min(cities, function (c) {
                  return d3.min(c.values, function (d) {
                      return d.temperature;
                  });
              }),
              d3.max(cities, function (c) {
                  return d3.max(c.values, function (d) {
                      return d.temperature;
                  });
              })
          ]);
          z.domain(cities.map(function (c) {
              return c.id;
          }));
          var city = g.selectAll(".city")
              .data(cities);
  
          city.exit().remove();
  
          var cityEnter = city.enter().append("g")
              .attr("class", "city");
  
          cityEnter.append("path")
              .attr("class", "line")
              .attr("d", function (d) {
                  return line(d.values);
              })
              .style("stroke", function (d) {
                  return z(d.id);
              });
  
          cityEnter.append("text")
              .datum(function (d) {
                  return {
                      id: d.id,
                      value: d.values[d.values.length - 1]
                  };
              })
              .attr("transform", function (d) {
                  return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
              })
              .attr("x", 3)
              .attr("dy", "0.35em")
              .style("font", "10px sans-serif")
              .text(function (d) {
                  return d.id;
              });
  
          city = cityEnter.merge(city);
  
          city.select("path").attr("d", function (d) {
              return line(d.values);
          });
  
          svg.select(".axis--y").call(d3.axisLeft(y))
      }
      // });
  
      function type(d, _, columns) {
          d.date = parseTime(d.date);
          for (var i = 1, n = columns.length, c; i &lt; n; ++i) d[c = columns[i]] = +d[c];
          return d;
      }
  
  &lt;/script&gt;
  </code></pre>
  
  <p><strong><em>UPDATE3:</em></strong>
  Try for the label (Old York vs. New York) - not working yet... </p>
  
  <pre><code>&lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
  &lt;style&gt;
      .axis--x path {
          display: none;
      }
  
      .line {
          fill: none;
          stroke: steelblue;
          stroke-width: 1.5px;
      }
  
  &lt;/style&gt;
  &lt;button&gt;Click me&lt;/button&gt;
  &lt;svg width="960" height="500"&gt;&lt;/svg&gt;
  &lt;!--&lt;script src="d3.v4.js"&gt;&lt;/script&gt;--&gt;
  
  &lt;script&gt;
      var svg = d3.select("svg"),
          margin = {
              top: 20,
              right: 80,
              bottom: 30,
              left: 50
          },
          width = svg.attr("width") - margin.left - margin.right,
          height = svg.attr("height") - margin.top - margin.bottom,
          g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
      var parseTime = d3.timeParse("%Y%m%d");
  
      var x = d3.scaleTime().range([0, width]),
          y = d3.scaleLinear().range([height, 0]),
          z = d3.scaleOrdinal(d3.schemeCategory10);
  
      var line = d3.line()
          .curve(d3.curveBasis)
          .x(function (d) {
              return x(d.date);
          })
          .y(function (d) {
              return y(d.temperature);
          });
  
      var data = [{
          "date": "1136156400000",
          "Old York": 63.4,
          "San Francisco": 62.7,
          "Austin": 72.2
      }, {
          "date": "1167692400000",
          "Old York": 58.0,
          "San Francisco": 59.9,
          "Austin": 67.7
      }, {
          "date": "1199228400000",
          "Old York": 53.3,
          "San Francisco": 59.1,
          "Austin": 69.4
      }, {
          "date": "1230850800000",
          "Old York": 55.7,
          "San Francisco": 58.8,
          "Austin": 68.0
      }, {
          "date": "1262386800000",
          "Old York": 62.3,
          "San Francisco": 55.1,
          "Austin": 71.9
      }];
  
      var data2 = [{
          "date": "1136156400000",
          "New York": 263.4,
          "San Francisco": 262.7,
          "Austin": 372.2
      }, {
          "date": "1167692400000",
          "New York": 458.0,
          "San Francisco": 259.9,
          "Austin": -367.7
      }, {
          "date": "1199228400000",
          "New York": 153.3,
          "San Francisco": 259.1,
          "Austin": 369.4
      }, {
          "date": "1230850800000",
          "New York": 155.7,
          "San Francisco": 258.8,
          "Austin": 368.0
      }, {
          "date": "1262386800000",
          "New York": 162.3,
          "San Francisco": 255.1,
          "Austin": 371.9
      }];
  
  
      // d3.tsv("data.tsv", type, function (error, data) {
      //     if (error) throw error;
  
      data.columns = ["date", "Old York", "San Francisco", "Austin"];
  
      var cities = data.columns.slice(1).map(function (id) {
          return {
              id: id,
              values: data.map(function (d) {
                  return {
                      date: d.date,
                      temperature: d[id]
                  };
              })
          };
      });
  
      x.domain(d3.extent(data, function (d) {
          return d.date;
      }));
  
      y.domain([
          d3.min(cities, function (c) {
              return d3.min(c.values, function (d) {
                  return d.temperature;
              });
          }),
          d3.max(cities, function (c) {
              return d3.max(c.values, function (d) {
                  return d.temperature;
              });
          })
      ]);
      g.append("g")
          .attr("class", "axis axis--x")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));
      g.append("g")
          .attr("class", "axis axis--y")
          .call(d3.axisLeft(y))
          .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", "0.71em")
          .attr("fill", "#000")
          .text("Temperature, ºF");
  
      update();
      d3.select("button").on("click", function () {
          // cities.splice(0, 1);
          data = data2;
          data.columns = ["date", "New York", "San Francisco", "Austin"];
          //            console.log(JSON.stringify(cities));
          update();
      });
  
      function update() {
  //        data.columns = ["date", "New York", "San Francisco", "Austin"];
          cities = data.columns.slice(1).map(function (id) {
              return {
                  id: id,
                  values: data.map(function (d) {
                      return {
                          date: d.date,
                          temperature: d[id]
                      };
                  })
              };
          });
  
  
          x.domain(d3.extent(data, function (d) {
              return d.date;
          }));
          y.domain([
              d3.min(cities, function (c) {
                  return d3.min(c.values, function (d) {
                      return d.temperature;
                  });
              }),
              d3.max(cities, function (c) {
                  return d3.max(c.values, function (d) {
                      return d.temperature;
                  });
              })
          ]);
          z.domain(cities.map(function (c) {
              return c.id;
          }));
  
          var city = g.selectAll(".city")
              .data(cities);
  
          city.append("text")
              .datum(function (d) {
                  return {
                      id: d.id,
                      value: d.values[d.values.length - 1]
                  };
              })
              .attr("transform", function (d) {
                  return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
              })
              .attr("x", 3)
              .attr("dy", "0.35em")
              .style("font", "10px sans-serif")
              .text(function (d) {
                  return d.id;
              });
  
          // var text = g.selectAll(".text")
          //     .data(texts);
  
          city.exit().remove();
  
          var cityEnter = city.enter().append("g")
              .attr("class", "city");
  
          cityEnter.append("path")
              .attr("class", "line")
              .attr("d", function (d) {
                  return line(d.values);
              })
              .style("stroke", function (d) {
                  return z(d.id);
              });
  
  
          city = cityEnter.merge(city);
  
          cityEnter.append("text")
          //        city.append("text")
              .datum(function (d) {
                  return {
                      id: d.id,
                      value: d.values[d.values.length - 1]
                  };
              })
              .attr("transform", function (d) {
                  return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
              })
              .attr("x", 3)
              .attr("dy", "0.35em")
              .style("font", "10px sans-serif")
              .text(function (d) {
                  return d.id;
              });
  
  
          city.select("path")
          //            .transition().duration(1000)
              .attr("d", function (d) {
                  return line(d.values);
              });
  
          city.select("text").datum(function (d) {
              return {
                  id: d.id,
                  value: d.values[d.values.length - 1]
              };
          })
          //            .transition().duration(1000)
              .attr("transform", function (d) {
                  return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
              });
  
          svg.select(".axis--y")
          //            .transition().duration(1000)
              .call(d3.axisLeft(y));
      }
  
  &lt;/script&gt;
  </code></pre>