Omnomnious
Omnomnious

Reputation: 345

How to select an existing SVG container in D3 without creating that container using D3?

This is question is more to satisfy my own curiosity than anything else. I'm wondering how to select an SVG element that already exists in the body of an HTML document using d3 WITHOUT creating that SVG element using d3 first. I would expect the following snippet to work yet it doesn't and it's causing me considerable frustration.

<html lang="en">

    <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.1/d3.min.js">
    </script>
    <script type="text/javascript">

      // If the below is changed to append instead of select it works
      // but what if I don't want to create the SVG using d3
      var svg = d3.select("body").select("svg")


      var circle = svg.append("circle")
          .attr("cx", 50)
          .attr("cy", 50)
          .attr("r", 20)

    </script>
    <style>



    </style>


  </head>


  <body>

  <svg>
  </svg>

  </body>


</html>

Upvotes: 0

Views: 4102

Answers (2)

datafunk
datafunk

Reputation: 636

To be absolutely sure, listen to DOMContentLoaded like

document.addEventListener('DOMContentLoaded', function(){
    init();
})

function init(){
    var svg = d3.select("svg");

    var circle = svg.append("circle")
        .attr("cx", 50)
        .attr("cy", 50)
        .attr("r", 20)
        .style("color", "green");
}

At this point you have much more flexibility of when and where you inject your script in relation to the page as well as the target element

Upvotes: 4

Nick Cordova
Nick Cordova

Reputation: 754

So this is a classic JavaScript issue. It wasn't working because the page elements had not finished loading. The fix is to move the d3 code from the head to just before the closing body tag.

<html lang="en">

    <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.1/d3.min.js">
    </script>

    <style>



    </style>


  </head>


  <body>

  <svg>
  </svg>

    <script type="text/javascript">

      // If the below is changed to append instead of select it works
      // but what if I don't want to create the SVG using d3
      var svg = d3.select("body").select("svg");


      var circle = svg.append("circle")
          .attr("cx", 50)
          .attr("cy", 50)
          .attr("r", 20)
          .style("color", "green");

    </script>

  </body>


</html>

Upvotes: 5

Related Questions