Search code examples
javascriptd3.jsappendenter

D3: data, enter, append pattern adds data to outer block


I'm using the D3 javascript library to render some basic web charts. I want to add three <path> elements to an <svg> block, but D3 is adding the elements to the end of the <html> block instead. Here's the complete html source:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="d3.v2.js"></script>
<script>
var chartData = [ 1, 2, 3 ];
d3.select("html").select("body").append("svg")
  .data(chartData, function(d) { console.log("data d:", d); return d; })
  .enter()
    .append("path")
      .attr("d", function(d) { return d; });
</script>
</body>

Chrome's developer console shows the resulting html to be:

<html><head><meta charset="utf-8">
<style type="text/css"></style></head><body>
<script src="d3.v2.js"></script>
<script>
var chartData = [ 1, 2, 3 ];
d3.select("html").select("body").append("svg")
  .data(chartData, function(d) { console.log("data d:", d); return d; })
  .enter()
    .append("path")
      .attr("d", function(d) { return d; });
</script><svg></svg>
</body><path d="1"></path><path d="2"></path><path d="3"></path></html>

The <svg> block was created, but for some reason, the <path> blocks are outside of it. How can I correct this error, and put them inside the <svg> where they belong?


Solution

  • First off, you should have a high-level variable that only refers to the svg. Secondly, you should specify the height and width of the SVG when creating it. You don't need to specify a select of html, so:

    var width = 400,
        height = 300;
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    

    Now you can use the svg variable to append paths. It is recommended that you group the paths together (hence the "g" appended first). And you should also do a selectAll for paths, because you want to bind the data you are adding to the path elements. So:

    svg.append("g").selectAll("path")
        .data(chartData)
      .enter().append("path")
        .attr("d", function(d) { return d; });
    

    I recommend the D3 tutorials here: http://alignedleft.com/tutorials/d3/