HattrickNZ HattrickNZ - 5 months ago 16
Javascript Question

How do i append a number of svgs each with an id to the body using d3?

How do i append a number of svgs each with an id to the body using d3?

<body>
<svg id="1" width="200" height="200"></svg>
<svg id="2" width="200" height="200"></svg>
<svg id="3" width="200" height="200"></svg>
<svg id="4" width="200" height="200"></svg>
<svg id="5" width="200" height="200"></svg>
</body>


This is my first attempt that works for drawing 1 svg:

// draw 1 svg

d3.select("body").append("svg")
.attr("width",201)
.attr("height",202)
.attr("id",202)


This is my attempt for drawing multiple svgs given an arbitrary array to draw an svg per element.

// my attempt to draw multiple svg - not working

var arr =[10,20,30,40,50]

d3.select("body").selectAll("svg")
.data(arr)
.enter()
.append("svg")
.attr("width",201)
.attr("height",202)
.attr("id",function(d){ return d;})


see my Fiddle here (right click on view and inspect to see Elelemnts tab)

Note: A bigger question I am working towards in the array would be an array of filenames where I want to put a graph in each svg using the data from each file to feed the graph

Answer

Your body already has 4 svgs.

You doing

<body>
        <svg id="1" width="200" height="200"></svg>
        <svg id="2" width="200" height="200"></svg>
        <svg id="3" width="200" height="200"></svg>
        <svg id="4" width="200" height="200"></svg>
        <svg id="5" width="200" height="200"></svg>
</body>

it should have been:

<body>

</body>

Now in this case the following function will append svg to body:

var arr =[10,20,30,40,50]

d3.select("body").selectAll("svg")
                 .data(arr)
                 .enter()
                 .append("svg")
                 .attr("width",201)
                 .attr("height",202)
                 .attr("id",function(d){ return d;})

Imagine your html like this

CASE 1

<body>

</body>

Now when you do:

d3.select("body").selectAll("svg")//this will return an empty selection as there is no svg.

d3.select("body").selectAll("svg")
                 .data(arr)
// This will associate the data to the selection.

d3.select("body").selectAll("svg")
                 .data(arr)
                 .enter()
                 .append("svg")
//this will append 5 new svg to the body as the data arr has 5 elements BUT the selection has no svg.

CASE 2

Now when your body has 5 svg elements:

<body>
        <svg id="1" width="200" height="200"></svg>
        <svg id="2" width="200" height="200"></svg>
        <svg id="3" width="200" height="200"></svg>
        <svg id="4" width="200" height="200"></svg>
        <svg id="5" width="200" height="200"></svg>
</body>

d3.select("body").selectAll("svg")//this will return 5 svg selection.

d3.select("body").selectAll("svg")
                 .data(arr)
// This will associate the data to the selection.

d3.select("body").selectAll("svg")
                 .data(arr)
                 .enter()
                 .append("svg")
//this will append a new svg to the body now the data arr has 5 elements and the selection has 5 elements so no svg will be appended.

CASE 3

Now when your body has 3 svg elements:

<body>
        <svg id="1" width="200" height="200"></svg>
        <svg id="2" width="200" height="200"></svg>
        <svg id="3" width="200" height="200"></svg>
</body>

d3.select("body").selectAll("svg")//this will return 3 svg selection.

d3.select("body").selectAll("svg")
                 .data(arr)
// This will associate the data to the selection.

d3.select("body").selectAll("svg")
                 .data(arr)
                 .enter()
                 .append("svg")
//this will append 2 svg to the body now the data arr has 5 elements and the selection has 3 elements so 2 svg will be appended.

And it will look like this:

<body>
        <svg id="1" width="200" height="200"></svg>
        <svg id="2" width="200" height="200"></svg>
        <svg id="3" width="200" height="200"></svg>
        <svg id="40" width="200" height="200"></svg>
        <svg id="50" width="200" height="200"></svg>
</body>

Hope this clears all your doubts.

working code here