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>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*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.
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(..);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.
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!
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:... and then you should be able to access things via
http://localhost:8000/.