Tutorial SVG Data Visualization 1: SVG charts

SVG charts

Check this example in your browser

The code for this line chart

The comments in the code are numbered. The numbers correspondent with the numbers in the explanation which you'll find beneath the code section.

<!doctype html>
  <html>
  <head>
  <meta charset="UTF-8">
  <title>Example 1 ::  Example 1 :: SVG line chart</title>
  <!-- 1. Including the D3 library in your web page-->
  <script src="http://d3js.org/d3.v3.min.js"></script>
  <style> 
  /* 8. Add  CSS classes to style the elements that you will be drawing*/
  path {
  stroke: red;
  stroke-width: 3;
  fill: none;
  }
  line {
  stroke: black;
  }
  .xGrids {
  stroke: lightgray;
  }
  .yGrids {
  stroke: lightgray;
  }
  text {
  font-family: Verdana;
  font-size: 9pt;
  font-style:italic;
  fill:#666;
  }
  .axisArrow {
  stroke: black;
  stroke-width: 1;
  fill: black; 
  }
</style>
  </head>
<body>
<div>
  <h3>Example 1 :: SVG line chart</h3>
  <script>
  //2. Define width, height and margins
  w = 400;
  h = 300;
  margin_x = 32;
  margin_y = 20;

//3. Define the data input array
  var data = [ {x:0,y:31},{x:1,y:41},{x:2,y:98},
  {x:3,y:41},{x:4,y:120},{x:5,y:79},
  {x:6,y:147},{x:7,y:105},{x:8,y:187	}]; 
  
  //Putting the x-data and y-data in two different arrays
  var ax = [];
  var ay = [];
 
data.forEach(function(d,i){
  ax[i] = d.x;
  ay[i] = d.y;
  })

var xMax = d3.max(ax);
  var yMax = d3.max(ay);
  var xLowLim = 0;
  var xUpLim = d3.max(ax);
  var yUpLim = 1.2 * d3.max(ay);
  var yLowLim = 0.8 * d3.min(ay);

//4. Defining the scales, domains, and ranges
  y = d3.scale.linear().domain([yLowLim, yUpLim]).range([0 + margin_y, h - margin_y]);
  x = d3.scale.linear().domain([xLowLim, xUpLim]).range([0 + margin_x, w - margin_x]);
//5. Define the chart line witch you will be drawing later on by using the SVG path element
  var line = d3.svg.line()
  .x(function(d) {  return x(d.x); })
  .y(function(d) { return -y(d.y); })

//6. add SVG element and its attributes
  var svg = d3.select("body")
  .append("svg:svg")
  .attr("width", w)
  .attr("height", h)
  
  //7. adding a <g> to the <svg> element and apply a transformation to this group <g> of elements. In this case, the transformation consists of a
  //translation of the coordinate grid, moving it down by h pixels.
  var g = svg.append("svg:g")
  .attr("transform", "translate(0," + h + ")");
//9 Draw the xLabels and the yLabels 
  //draw the xLabels 
  g.selectAll(".xLabel")
  .data(x.ticks(5))
  .enter().append("svg:text")
  .attr("class", "xLabel")
  .text(String)
  .attr("x", function(d) { return x(d) })
  .attr("y", 0)
  .attr("text-anchor", "middle");
  
  // draw the yLabels 
  g.selectAll(".yLabel")
  .data(y.ticks(5))
  .enter().append("svg:text")
  .attr("class", "yLabel")
  .text(String)
  .attr("x", 25)
  .attr("y", function(d) { return -y(d) })
  .attr("text-anchor", "end");
//10 Draw the x ticks and the y ticks
  //draw the x ticks 
  g.selectAll(".xTicks")
  .data(x.ticks(5))
  .enter().append("svg:line")
  .attr("class", "xTicks")
  .attr("x1", function(d) { return x(d); })
  .attr("y1", -y(yLowLim))
  .attr("x2", function(d) { return x(d); })
  .attr("y2", -y(yLowLim)-5)
  
  // draw the y ticks 
  g.selectAll(".yTicks")
  .data(y.ticks(5))
  .enter().append("svg:line")
  .attr("class", "yTicks")
  .attr("y1", function(d) { return -y(d); })
  .attr("x1", x(xLowLim))
  .attr("y2", function(d) { return -y(d); })
  .attr("x2", x(xLowLim)+5)
//11 Draw the x grid and the y grid 
  //draw the x grid 
  g.selectAll(".xGrids")
  .data(x.ticks(5))
  .enter().append("svg:line")
  .attr("class", "xGrids")
  .attr("x1", function(d) { return x(d); })
  .attr("y1", -y(yLowLim))
  .attr("x2", function(d) { return x(d); })
  .attr("y2", -y(yUpLim))
  
  // draw the y grid 
  g.selectAll(".yGrids")
  .data(y.ticks(5))
  .enter().append("svg:line")
  .attr("class", "yGrids")
  .attr("y1", function(d) { return -y(d); })
  .attr("x1", x(xUpLim)+20)
  .attr("y2", function(d) { return -y(d); })
  .attr("x2", x(xLowLim))
//12 Draw the x axis and the y axis 
  // draw the x axis
  g.append("svg:line")
  .attr("x1", x(xLowLim))
  .attr("y1", -y(yLowLim))
  .attr("x2", 1.2*x(xUpLim))
  .attr("y2", -y(yLowLim))
  
  // draw the y axis 
  g.append("svg:line")
  .attr("x1", x(xLowLim))
  .attr("y1", -y(yLowLim))
  .attr("x2", x(xLowLim))
  .attr("y2", -1.2*y(yUpLim))
// 13 Draw the x axis arrow and y axis arrow
  g.append("svg:path")
  .attr("class", "axisArrow")
  .attr("d", function() { 
  var x1 = x(xUpLim)+23, x2 = x(xUpLim)+30;
  var y2 = -y(yLowLim),y1 = y2-3, y3 = y2+3
  return 'M'+x1+','+y1+','+x2+','+y2+','+x1+','+y3;
  });
g.append("svg:path")
  .attr("class", "axisArrow")
  .attr("d", function() { 
  var y1 = -y(yUpLim)-13, y2 = -y(yUpLim)-20;
  var x2 = x(xLowLim),x1 = x2-3, x3 = x2+3
  return 'M'+x1+','+y1+','+x2+','+y2+','+x3+','+y1;
  });

//14 draw the line of data points
  g.append("svg:path").attr("d", line(data));

//15 place  the chart caption and the text along the x and y axis and
//The caption
  g.append("svg:text")
  .attr("x", (w / 2 )+60) 
  .attr("y", -h + margin_y -5 )
  .attr("text-anchor", "middle") 
  .style("font-size", "14px") 
  .text("Line chart1 made with D3.js");
//text along the y axis
  g.append("svg:text")
  .attr("x", 25) 
  .attr("y", -h + margin_y)
  .attr("text-anchor", "end") 
  .style("font-size", "11px") 
  .text("[v]");

//text along the x axis
  g.append("svg:text")
  .attr("x", w - 40) 
  .attr("y", -8 )
  .attr("text-anchor", "end") 
  .style("font-size", "11px") 
  .text("time [s]"); 
 
</script>
  </body>
  </html>

Creating a line chart with D3.js

1. Include the D3 library in your web page

2. Define width, height and margins

The w and h variables are the width and height of the chart; the margins are used to create room at the edges of the chart.

3. Define the data input array

var data = [ {x:0,y:31},{x:1,y:41},{x:2,y:98},
    {x:3,y:41},{x:4,y:120},{x:5,y:79},
    {x:6,y:147},{x:7,y:105},{x:8,y:187	}]; 

4. Define the scales, domains, and ranges

The domains

On the x-axis as well as on the y axis you will have a minimum value and a maximum value. The values between the minimum and the maximum value we call the domain.

On the x-axis the minimum value is xLowLim = 0 and the maximum value =xUpLim=d3.max(ax) = 8.
Thus the domain on the x-axis is [ xLowLim, xUpLim] ie [0,8]

On the y-axis the minimum value is yLowLim= 0.8 * d3.min(ay)=0.8 x 31 =24.8, and the maximum value is yUpLim = 1.2 * d3.max(ay)=244.4.
Thus the domain on the y-axis is [ yLowLim, yUpLim] ie [24.8,244.4]

The Ranges

The Range is formed by the values between 0 en the lenght of the axisof the the chart on the screen.

Thus the range on the x-axis is [0 + margin_x, w - margin_x] ie [32,368].
Thus the range on the y-axis is [0 + margin_y, h - margin_y] ie [20,280].

The Scale

The scale is lineair since on both axes there is a lineair conversion between the domain and the scale

Because the input data array is one-dimensional and contains the values that you want to represent on the y-axis, you can extend the domain from 0 to the maximum value of the array. You don’t need to use a for loop to find this value. D3 provides a specific function called max(date), where the argument passed is he array in which you want to find the maximum:

y = d3.scale.linear().domain([yLowLim, yUpLim]).range([0 + margin_y, h - margin_y]);
x = d3.scale.linear().domain([xLowLim, xUpLim]).range([0 + margin_x, w - margin_x]);

5. Define the chart line witch you will be drawing later on by using the SVG path element

Another fundamental thing you need in order to create a line chart is the path element. This path is filled with the data using the d attribute. The manual entry of all these values is too arduous and in this regard D3 provides you with a function that does it for you: d3.svg.line. So, in the vode listing below you declare a variable called line in which every data is converted into a point (x, y).

var line = d3.svg.line()
.x(function(d) {  return x(d.x); })
.y(function(d) { return -y(d.y); })

As you’ll see in all the cases where you need to make a scan of an array (a for loop), in D3 such a scan is handled differently through the use of the parameters d and i. The index of the current item of the array is indicated with i, whereas the current item is indicated with d. Recall that you translated the y-axis down with a transformation. You need to keep in mind; if you want to draw a line correctly, you must use the negative values of y. This is why you multiply the d values by -1.

6. Add the SVG element and its attributes

Now is the time to begin adding SVG elements. The first element to add is the <svg> element that represents
the root of all the other elements you’re going to add. The function of the <svg> tag is somewhat similar to that of the
canvas in jQuery and jqPlot. As such, you need to specify the canvas size with w and h.


var svg = d3.select("body")<
.append("svg:svg")
.attr("width", w)
.attr("height", h)

7. Add a <g> element to the <svg> element and apply a transformation to this group <g> of elements.

In this case, the transformation consists of a translation of the coordinate grid, moving it down by h pixels.

var g = svg.append("svg:g")
.attr("transform", "translate(0," + h + ")");

8. Add CSS classes to style the elements that you will be drawing

If you stopped here and launch the web browser on the page, you would get the image shown image 2


Image 2 The default behavior of an SVG path element is to draw filled areas

This seems to be wrong somehow, but you must consider that in the creation of images with SVG, the role managed by CSS styles is preponderant. In fact, you can simply add the CSS classes in in the listing below to have the line of data.

path {
  stroke: red;
  stroke-width: 3;
  fill: none;
}
line {
  stroke: red;
}
//rules below are meant for the axes, text and grids, which we will discuss in and from point 9, see below.
  .xGrids {
  stroke: lightgray;
}
  .yGrids {
  stroke: lightgray;
}
text {
  font-family: Verdana;
  font-size: 9pt;
  font-style:italic;
  fill:#666;
}
.axisArrow {
  stroke: black;
  stroke-width: 1;
  fill: black; 
}

9. Draw the xLabels and the yLabels

10. Draw the x ticks and the y ticks

11. Draw the x grid and the y grid

12. Draw the x axis and the y axis

13. Draw the x axis arrow and y axis arrow

14. Draw the line of data points

15. Place the chart caption and the text along the x and y axis and

SVG line chart
SVG line chart

Check this example in your browser

Leave a comment