score:3

Accepted answer

This is an interesting question: normally, the answer here would be just "select the div you want by ID or any other CSS selector that suits you" (or, since that this has been answered many many times, just a comment and a vote to close). The basis for that answer is that this...

var svg = d3.select("body").append("svg")

... will append the SVG at the end of the body. So far, nothing new or difficult.

But why did I said that this is an interesting question?

Because of the funny way (if you don't mind me saying so) you tried to select the div: you thought that D3 would create the chart inside that div just by putting the respective script inside it.

Of course putting the script inside the container div is not the way of doing this. But just for the sake of curiosity, there is a way of doing what you thought you were doing (again, selecting the element that contains the script): by using document.currentScript, which:

Returns the element whose script is currently being processed.

So, all we need in your situation is:

var container = document.currentScript.parentNode;
var svg = d3.select(container)
    .append("svg")
    //etc...

Which appends the SVG in the <div> (or any other containing element) that contains the <script>.

Here is a basic demo:

<script src="https://d3js.org/d3.v5.min.js"></script>
<div>
  <h3>I am div 1</h3>
</div>
<div>
  <h3>I am div 2, I have a chart</h3>
  <script>
    var container = document.currentScript.parentNode;
    var svg = d3.select(container)
      .append("svg");
    var data = d3.range(10).map(d => Math.random() * 150);
    var scale = d3.scaleBand()
      .domain(data)
      .range([0, 300])
      .padding(0.4);
    var bars = svg.selectAll(null)
      .data(data)
      .enter()
      .append("rect")
      .style("fill", "steelblue")
      .attr("x", d => scale(d))
      .attr("width", scale.bandwidth())
      .attr("height", d => 150 - d)
      .attr("y", Number)
  </script>
</div>
<div>
  <h3>I am div 3</h3>
</div>
<div>
  <h3>I am div 4</h3>
</div>

Note that document.CurrentScript doesn't work on IE (if you care for IE, just give the div an ID and select it).


Related Query

More Query from same tag