Link Search Menu Expand Document

In-class programming—D3 line chart

Due T 2022-02-15, 11:59pm EST 2pts 45 min

Please ask any questions about this assignment in class, or later today on Canvas in Discussion: In-class programming—D3 line chart.

You are welcome to work with other students on this assignment.

Table of Contents

Change log

  • 2022-02-15: Changed var to let in example code.
  • 2022-02-10: The due date was wrong on this but correct on GradeScope. A student got a bug bounty! +2 pts

Aim of the assignment

In this activity, you are going to create a line chart using D3, HTML, CSS, JavaScript, git, GitHub, and GitHub Pages to familiarize yourself with these technologies.

Instructions

If you have trouble running any of these steps, see the tips, tricks, and troubleshooting section below.

Setup

  1. Accept the GitHub Classroom assignment invitation by clicking this link to get your repository:

    https://classroom.github.com/a/HMw5bP1r

    For reference, this is the template repository your repository is being created from: https://github.com/NEU-DS-4200-S22/In-Class-Programming--D3_Line_Chart.

    Recall our general instructions and policies on GitHub Classroom assignments.

  2. Clone your GitHub-Classroom-generated repository to your local machine.

    E.g., in your terminal / command prompt CD to where you want this the folder for this activity to be. Then run: git clone <YOUR_REPO_URL>

    Warning: Under no circumstances should you be editing files via the GitHub website user interface. Do all your edits locally after cloning the repository.

  3. CD or open a terminal / command prompt window into the cloned folder.

  4. Start a simple python webserver. E.g., python -m http.server, python3 -m http.server, or py -m http.server. If you are using python 2 you will need to use python -m SimpleHTTPServer instead, but please switch to python 3 as Python 2 was sunset on 2020-01-01.

  5. Wait for the output: Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/).

  6. Now open your web browser (Firefox or Chrome) and navigate to the URL: http://localhost:8000.

JavaScript loading

  1. Open index.html. Just below this HTML comment:

     <!-- Load the d3.js library (version 7 minified) -->
    

    add this line to load the D3 JavaScript code (note the version number v7. D3 has many versions and they are not compatible):

     <script src='lib/d3.v7.3.0/d3.min.js'></script>
    
  2. You also have a file linechart.js. We want to load this JavaScript code as well. In index.html, just below this HTML comment:

     <!-- Load the linechart.js file -->
    

    add this line:

     <script src='linechart.js'></script>
    

Both of these should be at the end of the <body>.

Data loading and parsing

  1. Open the file data.csv with a plain-text editor and see what is inside. It is comma-separated. You will see a header row followed by several data rows with a date in the MM/D/YYYY format, e.g., 10/6/2018, and a price, e.g., 33.9. Note that you can open CSV files with Excel or other clever tools but they can make mistakes with parsing the data into their own formats.

  2. In linechart.js we are going to load this CSV file. Add this line to use D3 to load the file and then pass it to a callback function inside then:

     d3.csv('data.csv').then(function(data) {
       console.log(data);
     });
    

Once the data is loaded from the CSV file it is stored in the data variable. Your entire code for creating the line chart will go here inside the then function which happens after the data is asynchronously loaded.

  1. In your browser (Firefox or Chrome), open the browser developer tools by pressing CTRL+SHIFT+I (Windows/Linux) or Cmd+Opt+I and select the Console view. Here is where you see any output from console.log or any other console messages such as errors. The browser developer tools and the Console view are very useful for debugging. Here you can see that your code logged an array of 50 objects to the console. If you see this, your data has loaded!

  2. However, if you interact with the object by clicking the triangles you will notice that the date and price are enclosed in double-quotes (“) and are thus strings. This is not the format that we want our data to be in for us to interpret it properly. Hence we need to parse the data into the formats we want. To learn about date parsing visit this site: http://learnjsdata.com/time.html

  3. To parse our date data to the format we want, we are going to define a variable called parseDate before the step where we loaded our data:

     let parseDate = d3.timeParse('%m/%d/%Y');
    

Because our dates use forward slashes / as delimiters, our format string includes them. If our date was instead 02-02-2009, we would parse it using %m-%d-%Y.

  1. Now we can use parseDate to parse our dates and we can use the built-in unary + operator to parse our numbers. Modify your call to d3.csv like so, passing an anonymous row conversion function that does the parsing:

     d3.csv('data.csv', function(d) {
       return {
         date: parseDate(d.date),
         price: +d.price
       };
     }).then(function(data) {
       console.log(data);
     });
    

Line chart

  1. Instead of writing everything inside the then function of d3.csv, lets create a new function that creates our line chart given some data:

     function lineChart(data){
       console.log(data);
     }
    

    and replace the anonymous function inside then with our new function, like so:

     d3.csv('data.csv', function(d) {
       return {
         date: parseDate(d.date),
         price: +d.price
       };
     }).then(lineChart);
    
  2. In order to have the proper scales for your line chart, you need to know the max and min of your data. This is easy to do manually for static, small datasets but in general this is cumbersome, error-prone, and can be done instead algorithmically. Add these lines after the console.log in lineChart:

       let maxDate  = d3.max(data, function(d) { return d.date; });
       let minDate  = d3.min(data, function(d) { return d.date; });
       let maxPrice = d3.max(data, function(d) { return d.price;});
       console.log(maxDate, minDate, maxPrice);
    
  3. In your browser Console view check whether those variables have been set. The console.log is for your own assurance that your variable is indeed returning the value that you are asking for. You can remove this later.

  4. Check to see if you can see those variables in the browser debugger instead (Debugger in Firefox, Sources in Chrome). Open linechart.js in the debugger. Click on the line number beside the closing parenthesis } of the lineChart function to create a breakpoint. Refresh the browser page. You should see the variable values at this point inside the Scopes view (Firefox) or Scope view (Chrome). Chrome also shows the values in-line. You can click the Resume button (right-facing triangle, e.g. a play button) to resume execution. Remove the breakpoint by clicking the line number again.

  5. Define the width and height for the svg you will use:

     let width  = 600;
     let height = 500;
     let margin = {
       top   : 30,
       bottom: 30,
       left  : 30,
       right : 30
     };
    

For each of the following steps, you can save your file and reload the page in your web browser to see what has changed.

  1. Now, create your svg inside the body in the DOM by using D3 to select the body and append the svg, giving it a width, height, and background color:

     let svg = d3.select('body')
       .append('svg')
         .attr('width' , width)
         .attr('height', height)
         .style('background', '#efefef');
    
  2. Then create an SVG group g for all the elements that will make up our line chart.

     let chartGroup = svg
       .append('g')
         .attr('transform','translate(' + margin.left +',' + margin.top + ')');
    
  3. Now we will define two scales for the x (d3.scaleTime) and y (d3.scaleLinear) axes and set their domain (in the data) and range (on the screen):

     let xScale = d3.scaleTime()
         .domain([minDate, maxDate])
         .range([0, width - margin.left - margin.right]);
    
     let yScale = d3.scaleLinear()
         .domain([0, maxPrice])
         .range([height - margin.bottom - margin.top, 0]);
    
  4. Then we can draw our axes using these scales:

     let xAxis = d3.axisBottom(xScale);
     chartGroup.append('g')
         .attr('class', 'x axis')
         .attr('transform', 'translate(0, ' + (height - margin.bottom - margin.top) + ')')
         .call(xAxis);
    
     let yAxis = d3.axisLeft(yScale);
     chartGroup.append('g')
         .attr('class', 'y axis')
         .attr('transform', 'translate(0, 0)')
         .call(yAxis);
    
  5. Finally, we will draw the line:

     let line = d3.line()
         .x(function (d) { return xScale(d.date); })
         .y(function (d) { return yScale(d.price);})
    
     chartGroup.append('path')
         .attr('d', line(data));
    
  6. At this point, if you save and reload in your browser you will see that your line looks rather bizarre. This is because by default the line is filled with black and it is trying to close the polygon. Let’s add CSS to fix this.

  7. First, add a CSS class to the lines we want to style (adding to the original code):

     chartGroup.append('path')
       .attr('d', line(data))
       .attr('class', 'dataLine');
    

    Then, in linechart.css add these lines:

     .dataLine{
       stroke: #0000BB;
       stroke-width: 1px;
       fill: none;
     }
    

Congratulations! You should now have a line chart. What else can you do with this by playing with JavaScript, HTML, and CSS?

Pages & validation

  1. Commit and push your files to GitHub and test whether your website looks the same on GitHub pages. Note: the GitHub Pages site won’t show up until you make your first commit & push to the remote repository, and it may take up to a minute for it to finish deploying. You would normally need to turn on GitHub pages in the settings for your repository, but we have set that up for you so you’re using the gh-pages branch by default.

  2. Edit the last line of your README.md file to include a clickable hyperlink to the GitHub page website for your repo., replacing the <insert your clickable hyperlink here> code with your markdown.

  3. Make any edits necessary to ensure your code passes the W3 validator. You can see whether it passes with the red X or green check mark ✓ in the GitHub interface by your commit ID.

  4. Commit and push your files to GitHub again.

Submission instructions

  1. Commit all your local files and push them to the remote repository on GitHub which was generated by GitHub Classroom. We will grade based on what is visible on the GitHub Page.
  2. Submit a PDF containing the URL of your repository to the assignment In-class programming—D3 line chart in GradeScope.

    Warning: Do not put a link to a personal repository. It must be within our class GitHub organization. Do not submit a link to the GitHub Page.

Grading

This is a satisfactory grading assignment. If you followed the instructions you receive full marks and if not you receive a 0. Your submission is satisfactory if you completed the main goal part of the activity

CriteriaPoints
Satisfactory?2

Tips, tricks, & troubleshooting

If you run into trouble, first look at our relevant tutorials which have links to various resources, tips, & tricks:


© 2022 Cody Dunne. Released under the CC BY-SA license