Exercise 1 - Single Line-Chart
Step 1: Create index.html
First of all, create the index.html where you want to display the line chart. You have to consider the following aspects:
- The index.html file should comply with the HTML5 standard
- Include a div-tag that will contain the line chart
- Give the div-tag an unique id-attribute
Step 2: Create index.js and import in index.html
You will be creating a single JavaScript file with all necessary code and import it into the index.html file.
- Create a JS file (e.g. index.js)
- In this JS file, import the entire D3 library (from "https://cdn.jsdelivr.net/npm/d3@7/+esm")
- Import this JS file into the index.html with the script-tag (import type should be "module")
Step 3: Create a function for plotting the line chart
You have to create a single function that will create the line chart and bind it to the on-load event of the HTML body.
- Define an asynchronous function (e.g. lineChart)
- Bind this function to the on-load event of the HTML body:
document.querySelector('body').onload = lineChart();
Step 4: Prepare the chart canvas and load data
To start with, you need to add a svg-tag (which will contain the chart) and load the data.
- First, since the REST-API unfortunately does not allow access from localhost, download the data and save it (e.g. data.json)
- Select the div from your index.html and add a svg-tag
- Initially define some variables for formatting:
var margin = {top: 10, right: 30, bottom: 30, left: 60}, width = 600 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; - Select the div-tag and add a svg-tag as well as a g-tag (grouping) with respective attributes
var svg = d3.select("#line") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
- Initially define some variables for formatting:
- Finally, load the data you just downloaded (thankfully, D3.js has included a function to fetch data and you could use the same function to get data from a RESTful API - CAUTION: it's an asynchronous function)
var data = await d3.json("../data.json");
Step 5: Data preparation
Check and prepare data for the subsequent chart creation.
- Always check data as a first step - take a look at the raw json-file and the containing data and structure
- To work with time series, you need to format the coresponding data:
data['datapoints'].map((d,i) => { let temp_time = new Date(d.time); data['datapoints'][i] = {...d, time: temp_time }; })
Step 6: Add axis to the chart
As mentioned in the lecture, the svg-tag has no concept of charts or plots. Hence, we have to add the respective elements "by hand".
- Prepare the data for the x-axis - there are always two parts: domain (what values will be covered by the axis) and range (the "size", e.g. width or height of the axis). Since we are looking at a time series, the x-axis needs to have a suitable scale.
//note scale that is used - scaleTime() xScale = d3.scaleTime() .domain(d3.extent(data['datapoints'], function(d) { return d.time})) .range([ 0, width ]); - Add the x-axis to the svg-element
//here we have to add a grouping element, inserting every single tick is done by d3 - d3.axisBottom(xScale) svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(xScale)); - Pretty much the same has to be done for the y-axis, but this time it's a linear scale and not a time scale.
//note the changed scale here - scaleLinear() var yScale = d3.scaleLinear() .domain([0, d3.max(data['datapoints'], function(d){return d.actPressure})]) .range([ height, 0 ]); svg.append("g") .call(d3.axisLeft(yScale));
Step 7: Add the line to the line chart
The last step is to add the Line to the line chart. Therefore, a path-element can be added to the svg canvas.
//first, add the path and select the data svg.append("path") .datum(data['datapoints']) //D3.js takes care of drawing the line (d3.line()) - you have to define the values for the axis (x(), y()) .attr("d", d3.line() .x(function(d) { return xScale(d.time)}) .y(function(d) { return yScale(d.actPressure)}) )
Step 8: Now it's your turn
If you just followed the steps above, your chart does not quite look like what is displayed to the left of this box. Hence, try to modify / extend the code to achieve the same result. E.g.
- Change the chart as to remove the filling of the path element
- Try to transform the text on the x-axis to rotate by 90 degrees
- Experiment with additional styling on your own