Skip to content

Course Map

bri25yu edited this page Nov 29, 2022 · 1 revision

How the course chart works

The course chart uses the d3.js library, specifically its force chart, with many centers of gravity. The force chart is a physics simulation, with imaginary springs pulling connected nodes together and other springs spacing them apart until some steady-state equilibrium is found.

The course data is available as JSON at https://hkn.eecs.berkeley.edu/coursesurveys/chartinfo, which is pulled from our database. (You can paste the JSON into https://jsonlint.com/ for a nicer view.)

On the website source, there's a script tag that looks something like:

<script>coursechart-{hash}.js</script>
<link rel="stylesheet" media="all" href="/assets/coursechart-{hash}.css" />

These separate source files contain all the code and CSS rules for the chart. The CS and EE charts are drawn separately with a call to generateChart, which pulls the course data and applies d3.js force chart magic and CSS rules. For example:

  • The fading in/out is CSS opacity, coupled with d3.js transition animations
  • The colors are set as CSS background-color

The JavaScript code has a few important details:

  • force.on("tick") is a callback function, runs the force simulation until the graph reaches a steady state.
  • pref, in the types array, tries to cluster classes together (16x, 17x, 18x).
  • bias, in each class, fine-tunes classes, so 188 always appears above 189, and 170 appears above the other 17x.

/courseguides/chartinfo endpoint

This endpoint is routed to CourseguideController::get_courses_json, which renders the course Hash from CourseChartHelper::get_coursechart_json into a JSON string.

The format is roughly:

{
  "types": [
    { "id": 1, "chart_pref_x": 0.5, "chart_pref_y": 0, "color": "#ABCDEF", "name": "core" },
    // ...
  ],
  "cs_courses": [
    {
      "id": 74,
      "department_id":	2,
      "name": "61A",
      "link": "/coursesurveys/course/CS/61A",
      "prereqs": [],
      "type_id": 1,
      "bias_x": 0,
      "bias_y": 0,
      "depth": 1,
      "startX": 481,
      "startY": 179,
    }
    //...
  ],
  "ee_courses": [
    //...
  ]
}

Editing the course chart

Courses are represented by a CourseChart object. As of Spring 2016, the fields are as follows:

  • id - autogenerated by rails
  • course_id - the course ID that this node represents
  • bias_x - see bias above
  • bias_y - same
  • depth - see above
  • show - whether or not to show this node

In addition, the course object has a CourseType that tells it which category and stuff that it belongs in, which lets the nodes get its colors and locations. Look at the CourseType model for more information.

Links are represented by the CoursePrereq model that contains:

  • id - autogenerated by rails
  • course_id - course the arrow points to
  • prereq_id - course the arrow points from (actually i'm not sure if these are switched, you can just look up 61A in the database or whatever to find out)
  • is_recommended - whether or not this arrow should be solid or dashed (sometimes profs ask us to add a prereq as a recommendation)

To remove a node or link, set show to false or delete the link from the database. To add a node or link, use the rails console to create a new CourseChart object and a CoursePrereq object, if needed.

For more information, check lib/tasks/coursechart_update.rake.