Using the SVG Coordinate Space


The Goal

In this section, you will use D3.js to add SVG elements to specific coordinates in a graph based on data.

Our Goal is to take the following data set:

1var spaceCircles = [30, 70, 110];

and transform it to this data visualization using D3.js:

Three Circles in SVG Coordinate Space generated by D3.js


Mathematical / Graph Coordinate Space

Before we get into using D3.js to add SVG elements to specific coordinates in a graph based on data, let us talk about the coordinate space.

We learned about basic mathematical graphs in basic mathematics.

These graphs are a 2-dimensional flat space represented as a rectangle.

These graphs have a coordinate space where x=0 and y=0 coordinates fall on the bottom left.

Mathematical Cartesian Coordinate Space Graph

These graphs have the X coordinate growing from left to right.

These graphs also have the Y coordinate growing from bottom to top.

Which means, when we talk about drawing a circle with x=30 and y=30 coordinates, we go 30 units from the bottom left to the right and then we go 30 units up.

Mathematical Cartesian Coordinate Space Graph Circle Drawing


SVG Coordinate Space

SVG Coordinate Space works in the same way that mathematical graph coordinate space works except for two important features:

1 - SVG Coordinate space has x=0 and y=0 coordinates fall on the top left.

2 - SVG Coordinate space has the Y coordinate growing from top to bottom.

SVG Coordinate Space Graph

Which means as Y increases, the coordinates move down, not up.

So when we talk about drawing a circle with x=30 and y=30 coordinates in SVG Coordinate Space, we go 30 units from the top left to the right and then we go down 30 units up.

SVG Coordinate Space Graph Circle Drawing


.append('svg') as a Coordinate Space

When we have created a D3.js visualization, so far we have started with the following code

1var svgContainer = d3.select("body").append("svg")
2                                    .attr("width", 200)
3                                    .attr("height", 200);

Which gives us this the following HTML SVG element:

SVG element added with D3.js to our Web page

Until now, we had glossed over how to think about this SVG element. No longer!

We can think of this SVG element as a graph 200 units wide and 200 units tall.

And with what we learned from the above section ( SVG Coordinate Space ), we now know that the X and Y zero coordinates are at the top left.

We also now know that as the Y coordinate grows, it will move from the top to the bottom of our graph.

To clarify what this looks like, we can style our SVG element by adding some style to it like this:

1var svgContainer = d3.select("body").append("svg")
2                                    .attr("width", 200)
3                                    .attr("height", 200)
4                                    .style("border", "1px solid black");

Which gives us this:

SVG element container border

This is useful for thinking about how the data visualization takes shape given the inverted Y coordinate system.


Position SVG Elements in the SVG Coordinate Space

When we create an SVG Circle element in the following fashion:

1<svg width="50" height="50">
2  <circle cx="25" cy="25" r="25" fill="purple" />
3</svg>

The cx tells us to move 25 units from the left to the right of the SVG element.

The cy tells us to move 25 units from the top to the bottom of the SVG element.

Recall how we created an SVG circle with D3.js before:

1var circleSelection = svgSelection.append("circle")
2                                  .attr("cx", 25)
3                                  .attr("cy", 25)
4                                  .attr("r", 25)
5                                  .style("fill", "purple");

The .attr("cx", 25) and .attr("cy", 25) allow us to set the attributes of the SVG circle.

And as we saw later in the Creating SVG Elements Based on Data section, we can programmatically set these attributes:

1var circleAttributes = circles
2                       .attr("cx", 50)
3                       .attr("cy", 50)
4                       .attr("r", function (d) { return d; });

Except, this time, instead of using a function in the "radius" r attribute, we will use a function in the cx and cy attributes.


Create an SVG Element to Hold SVG Elements

Start with a basic webpage:

1<!DOCTYPE html>
2<html>
3  <head>
4    <script type="text/javascript" src="d3.v2.min.js"></script>
5  </head>
6  <body>
7  </body>
8</html>

Open the JavaScript Console with the HTML elements visible.

Then type the following into the JavaScript Console:

1var spaceCircles = [30, 70, 110];
2
3var svgContainer = d3.select("body").append("svg")
4                                    .attr("width", 200)
5                                    .attr("height", 200);

This gives us the data set and an SVG element to hold the SVG Circles we will add shortly:

SVG element added with D3.js to our Web page


Bind Data to SVG Circles

The next step will be to take the data and bind it to our SVG Circle elements.

 1var spaceCircles = [30, 70, 110];
 2
 3var svgContainer = d3.select("body").append("svg")
 4                                    .attr("width", 200)
 5                                    .attr("height", 200);
 6
 7var circles = svgContainer.selectAll("circle")
 8                          .data(spaceCircles)
 9                          .enter()
10                          .append("circle");

This gives us the three SVG circle elements in our webpage:

SVG Circles created using D3.js

Which is great - though the circles don't appear. This is because have not specified the attributes for each circle.


Use Bound Data to Alter SVG Circle Coordinates

Now that the data is bound to the SVG Circle Elements, we can use it to specify the attributes for the x-coordinate and y-coordinate.

D3.js allows us to use a function in the "cx" and "cy" attributes:

 1var spaceCircles = [30, 70, 110];
 2
 3var svgContainer = d3.select("body").append("svg")
 4                                    .attr("width", 200)
 5                                    .attr("height", 200);
 6
 7var circles = svgContainer.selectAll("circle")
 8                          .data(spaceCircles)
 9                          .enter()
10                          .append("circle");
11
12var circleAttributes = circles
13                       .attr("cx", function (d) { return d; })
14                       .attr("cy", function (d) { return d; })
15                       .attr("r", 20 );

As you can see from the above code, we added the attributes to our circle selection. The data set specifies the circle center's x-coordinate and y-coordinate, so we use D3.js to update the "cx" and "cy" SVG Circle Element attribute for each SVG Circle.

If we run this in the JavaScript Console we get:

Used D3.js to create three circles in the SVG Coordinate Space

We are getting close. We now have three SVG Circle Elements and their coordinates correspond to the coordinates given in the the data set. The last thing we have to do is to color the SVG Circle based on the data.


Styling SVG Elements Based on Data Revisited

If you recall the Creating SVG Elements Based on Data section, we used the bound data to alter the SVG element's style.

As we saw before, D3.js lets us use a function inside of the .style() operator - which means we can write the following:

 1var spaceCircles = [30, 70, 110];
 2
 3var svgContainer = d3.select("body").append("svg")
 4                                    .attr("width", 200)
 5                                    .attr("height", 200);
 6
 7var circles = svgContainer.selectAll("circle")
 8                          .data(spaceCircles)
 9                          .enter()
10                          .append("circle");
11
12var circleAttributes = circles
13                       .attr("cx", function (d) { return d; })
14                       .attr("cy", function (d) { return d; })
15                       .attr("r", 20 )
16                       .style("fill", function(d) {
17                         var returnColor;
18                         if (d === 30) { returnColor = "green";
19                         } else if (d === 70) { returnColor = "purple";
20                         } else if (d === 110) { returnColor = "red"; }
21                         return returnColor;
22                       });

Running the above JavaScript code in the JavaScript Console gives us this:

Created three colored circles using D3.js in SVG Coordinate Space

Congratulations - You created, styled, and placed SVG elements in the SVG Coordinate Space based on data from a data set!

If you found this D3 Tutorial helpful, you'll enjoy these FREE videos: