Skip to content

Instantly share code, notes, and snippets.

@RyanMarcus
Created August 31, 2018 19:37
Show Gist options
  • Save RyanMarcus/ac23203a3038a1d78b10a858e3e0a6cc to your computer and use it in GitHub Desktop.
Save RyanMarcus/ac23203a3038a1d78b10a858e3e0a6cc to your computer and use it in GitHub Desktop.
Code review #1 for Shuai on D3 JS stuff

Separate scripts into their own files

Scripts should moved into their own files instead of embedding them directly inside of the HTML. For example, if you move your JavaScript into a file called fragmentViz.js, then you can include it in an html page like this:

<script src="fragmentViz.js"></script>

Use const and let

In modern JavaScript, var has been replaced with const and let. For example, instead of writing:

var someConstant = 5;
let someVariableIWillModify = 7;

We now write:

const someConstant = 5;
let someVariableIWillMody = 7;

Using const and let make it clear to the reader what references will change and which won't. Fundamentally, let variables can be redefined and cosnt variables cannot be. for example, this code is invalid:

const a = 5;
a = 6; // error!

... but this code is valid:

let a = 5;
a = 6;

Note that const should be used whenever you are not going to reassign a variable. Just because you modify the value does not mean you are reassigning. For example, this is valid:

const myList = [];
myList.push(5); // modifying the *value* but not reassigning the *reference*

Use string templating instead of string concat

In JavaScript, if I have a variable called userName and I want to make a string containing the phrase "Hello " + username, I should use JavaScript string templating (called template literals:

const userName = "Ryan";
const greeting = `Hello ${userName}`;

Doing this avoids strange errors when you try to add a boolean/float and a string together.

Separate markup elements from D3 code

For example, you have:

// Create SVG element
svg = d3.select("body")
          .append("svg")
          .attr("width", w)
          .attr("height", h);

This will append a new svg element to the current body, always at the end. This was fine for the prototype, but now, since we might not always want the svg element added to the end of the body, we should create it in the HTML markup and then select it with D3. For example, in the body tag:

<svg id="tupleValueGraph" width="500px" height="400px"></svg>

Then, to get it with D3:

svg = d3.select("#tupleValueGraph")
        .attr(..);

Separate style from semantics

For example, you have:

.attr("stroke-width", 2)
.attr("stroke", "blue");

Instead, it is better to give this particular type of element a class (which you are already doing via .attr("class", "dataline"), but should probably do with the explicit .classed("dataline", true)) and then use CSS to style the element. For example, after removing the two lines above, you could create a styles.css with this:

.dataline {
  stroke-width: 2px;
  stroke: blue;
}

... and then include this style sheet in the HTML document by adding a link element to the head:

<link rel="stylesheet" type="text/css" href="styles.css">

This lets us re-use the dataline class and styles across the whole application. It also helps centralize where all the style information is located.

Build reusable modules instead of hard-coded D3 code

The code you have in graphData.html isn't very modular. We could make it a lot better by creating a JavaScript class:

class TupleValueGraph {
  constructor(svgID) {
    this.svgID = svgID;
    this.svg = d3.select(`#${svgID}`);
  }
  
  loadAndDisplayJSON(jsonFileName) {
    // code to load the json file and update the
    // visualization, using this.svg
  }
  
  // other methods...
}

This will let you write much cleaner code when things get more complicated, and will make your D3 visualization much more modular, allowing us to use it in multiple places!

@RyanMarcus
Copy link
Author

One extra note -- once you split things up into HTML / CSS / JS files, you might find that opening the HTML file with file:// in your browser doesn't work anymore. If this is the case, you can start a simple webserver in the same folder as your files:

python3 -m http.server

... and then you should be able to access things via http://localhost:8000/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment