title: How to avoid multiple svg elements from being created?
body: <p>I am trying to build a D3 chart in angular2 component. When ever I click on the link to create D3 chart it creates a new instance of it. Please notice the HTML where multiple copies of SVG tags are created. any ideas why is it happening and how to avoid it?
  <a href="https://i.stack.imgur.com/6dcao.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6dcao.png" alt="enter image description here"></a>
  every time i click on the link to create a D3 chart, it should clear/null the existing instance and create a fresh chart component.</p>
  
  <p>Code to create the new instance from the parent component,</p>
  
  <pre><code>import { Component } from '@angular/core';
  import { BubbleChart } from '../Charts/BubbleChart';
  
  @Component({
      template: `
  &lt;div id="divBubbleChart"&gt;
      &lt;bubble-chart&gt;&lt;/bubble-chart&gt;
  &lt;/div&gt;
  `,
      directives: [BubbleChart]
  })
  
  export class CacheVisualization {
      constructor() {
          console.log("CacheVisualization component being called");
      }
  }
  </code></pre>
  
  <p>the child d3 component</p>
  
  <pre><code>import { Component, ViewEncapsulation } from '@angular/core';
  import { HTTP_PROVIDERS, Http } from '@angular/http';
  import { Configuration } from '../Configuration/Configuration';
  
  declare var d3: any;
  
  @Component({
      selector: 'bubble-chart',
      styleUrls: ['css/BubbleChart.css'],
      providers: [Configuration, HTTP_PROVIDERS],
      template: ``,
      encapsulation: ViewEncapsulation.None 
  })
  export class BubbleChart {
      public resultData: any;
      public chartData: any;
      margin = 5;
      diameter = 660;
  
      constructor(private _Configuration: Configuration) {
          console.log("In constructor of BubbleChartComponent");
          this.DrawBubbleChart();
      }
  
      private DrawBubbleChart(): void {
          console.log("Inside DrawBubbleChart in BubbleChartComponent");
          //console.log(this.resultData);
  
          var color = d3.scale.linear()
              .domain([-1, 5])
              .range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])
              .interpolate(d3.interpolateHcl);
  
          var pack = d3.layout.pack()
              .padding(2)
              .size([this.diameter - this.margin, this.diameter - this.margin])
              .value(function (d) { return d.size; })
  
          var svg = d3.select("body").append("svg")
              .attr("width", this.diameter)
              .attr("height", this.diameter)
              .append("g")
              .attr("transform", "translate(" + this.diameter / 2 + "," + this.diameter / 2 + ")");
  
          var chart = d3.json(this._Configuration.BLUESKYDATACACHEAPI_GETEXTRACTORQUEUESLATEST, (error, root) =&gt; {
              if (error) throw error;
  
              var focus = root,
                  nodes = pack.nodes(root),
                  view;
  
              var circle = svg.selectAll("circle")
                  .data(nodes)
                  .enter().append("circle")
                  .attr("class", function (d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
                  .style("fill", (d) =&gt; { return d.children ? color(d.depth) : null; })
                  .on("click", (d) =&gt; { if (focus !== d) zoom.call(this, d), d3.event.stopPropagation(); });
  
              var text = svg.selectAll("text")
                  .data(nodes)
                  .enter().append("text")
                  .attr("class", "label")
                  .style("fill-opacity", function (d) { return d.parent === root ? 1 : 0; })
                  .style("display", function (d) { return d.parent === root ? "inline" : "none"; })
                  .text(function (d) { return d.name; });
  
              var node = svg.selectAll("circle,text");
  
              d3.select("body")
                  .style("background", "white")
                  //.style("vertical-align", "top")
                  //.style("background", color(-1))
                  .on("click", () =&gt; { zoom.call(this, root); });
  
              zoomTo.call(this, [root.x, root.y, root.r * 2 + this.margin]);
  
              function zoom(d) {
                  var focus0 = focus; focus = d;
  
                  var transition = d3.transition()
                      .duration(d3.event.altKey ? 7500 : 750)
                      .tween("zoom", (d) =&gt; {
                          var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + this.margin]);
                          return (t) =&gt; { zoomTo.call(this, i(t)); };
                      });
  
                  transition.selectAll("text")
                      .filter(function (d) { return d.parent === focus || this.style.display === "inline"; })
                      .style("fill-opacity", function (d) { return d.parent === focus ? 1 : 0; })
                      .each("start", function (d) { if (d.parent === focus) this.style.display = "inline"; })
                      .each("end", function (d) { if (d.parent !== focus) this.style.display = "none"; });
              }
  
              function zoomTo(v) {
                  var k = this.diameter / v[2]; view = v;
                  node.attr("transform", function (d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
                  circle.attr("r", function (d) { return d.r * k; });
              }//end zoomTo
  
          });//end chart
  
      }//end DrawBubbleChart
  
  }
  </code></pre>
  
  <p>After assigning the ID to the component created, it creates ID for the parent html tag and not for the "svg" tag. refer the snapshot below<a href="https://i.stack.imgur.com/1Fgvd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1Fgvd.png" alt="enter image description here"></a></p>