Week #4 – Production Assignment ( Data Visualization)

Introduction:

I have always found bar graphs to be quite fascinating. The ability to stack and compare data visually allows it to be easily perceived. In my case, I wanted to make sure, that I can log my study hours, as an extrinsic motivation. Something which will give me visual overview of my efforts in the form of time put into studying.

Concept:

In theory, I wanted the data visualization and bar graph to be based on weekly basis. A snapshot of just one week as opposed to a complete log since the dawn of time.  Each day in the week will have a bar , extending from top to bottom axis, and will vary in height, to signify which day was the most productive (I know this isn’t exactly considered productivity, but we might just pretend). Each bar will have designated study hours listed on top of it, and will give a quantitive and qualitative visual of study pattern.

The user will be greeted by start page, then taken to a page to log in study hours, and then again upon a button click, will see the graphs appear.

Code Highlight:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function setup() {
}
function startProgram() {
}
}
function submitData() {
// check and store if
for (let i = 0; i < studyInputs.length; i++) {
//cycle through the inputs to verify the nature of data.
let val = parseFloat(studyInputs[i].value());
// parseFloat is a javascript function, which parses
// a value as string and then converts it to number
studyHours.push(isNaN(val) ? 0 : val);
/*
isNaN is 'Not a number' function which returns true if the value is passed is not a number. in our case if the value passed is a
number, then its true, and pushes 'val' into study hours. and for
the one where if there is no number entered for instance a letter /
character instead, this will push the value '0' for the hours.
*/
studyInputs[i].hide(); // hide the input field after submission
}
submitButton.hide();
state = "graph"; // change state so that draw() will call drawGraph()
}
function drawGraph() {
}
//atlas draw function which keeps on cycling, and only draws graph when the state has been changed to draw graph.
function draw() {
// if state is "graph" continuously draw the graph.
if (state === "graph") {
drawGraph(); // custom function
}
}
function setup() { } function startProgram() { } } function submitData() { // check and store if for (let i = 0; i < studyInputs.length; i++) { //cycle through the inputs to verify the nature of data. let val = parseFloat(studyInputs[i].value()); // parseFloat is a javascript function, which parses // a value as string and then converts it to number studyHours.push(isNaN(val) ? 0 : val); /* isNaN is 'Not a number' function which returns true if the value is passed is not a number. in our case if the value passed is a number, then its true, and pushes 'val' into study hours. and for the one where if there is no number entered for instance a letter / character instead, this will push the value '0' for the hours. */ studyInputs[i].hide(); // hide the input field after submission } submitButton.hide(); state = "graph"; // change state so that draw() will call drawGraph() } function drawGraph() { } //atlas draw function which keeps on cycling, and only draws graph when the state has been changed to draw graph. function draw() { // if state is "graph" continuously draw the graph. if (state === "graph") { drawGraph(); // custom function } }
function setup() {

}

function startProgram() {

  }
 
}

function submitData() {
  // check and store if 
  for (let i = 0; i < studyInputs.length; i++) {
    //cycle through the inputs to verify the nature of data.
    let val = parseFloat(studyInputs[i].value());
    // parseFloat is a javascript function, which parses
    // a value as string and then converts it to number
    studyHours.push(isNaN(val) ? 0 : val);
    /*
    isNaN is 'Not a number' function which returns true if the value is     passed is not a number. in our case if the value passed is a 
    number, then its true, and pushes 'val' into study hours. and for
    the one where if there is no number entered for instance a letter /
    character instead, this will push the value '0' for the hours.
    */
    studyInputs[i].hide(); // hide the input field after submission
  }
  submitButton.hide();
  state = "graph";  // change state so that draw() will call drawGraph()
}

function drawGraph() {
  
}

//atlas draw function which keeps on cycling, and only draws graph when the state has been changed to draw graph.
function draw() {
  // if state is "graph" continuously draw the graph. 
  if (state === "graph") {
    drawGraph(); // custom function
  }
}

The code in submit data is what I am proud of. At first, I encountered the possibility where the user might not enter a numerical value, but rather a string or character. Hence I made use of ‘parseFloat’ and ‘isNaN’ javascript functions paired with a inline if-else logic statement to check for the nature of input. If the input happened to be other than a number, then push a ‘zero’ value into the ‘studyHours’ array.

 

Things I struggled with:

I struggled the most with the placement and sizing of the bar graphs. There coordinates were inconsistent, and the spacing was off. Hence, I decided to use mathematical formulation to calculate the division of space on the spot , and keep its coordinates and their margin  consistent.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let margin = 60;
let gap = 20; //gap between days
let availableWidth = width - 2 * margin;
let barWidth = (availableWidth - (days.length - 1) * gap) / days.length;
let maxHours = max(studyHours); // maxiumum value in the array
if (maxHours === 0) {
maxHours = 1; // to avoid division by zeor
}
let graphHeight = height - 100;
stroke(0);
//horizontal bar
line(margin, height - 50, width - margin, height - 50);
// For each day, draw the corresponding bar and label its study hours and name
for (let i = 0; i < days.length; i++) {
let x = margin + i * (barWidth + gap);
let barHeight = map(studyHours[i], 0, maxHours, 0, graphHeight);
// Draw a blue bar representing the study hours
fill(50, 150, 200);
rect(x, height - 50 - barHeight, barWidth, barHeight);
let margin = 60; let gap = 20; //gap between days let availableWidth = width - 2 * margin; let barWidth = (availableWidth - (days.length - 1) * gap) / days.length; let maxHours = max(studyHours); // maxiumum value in the array if (maxHours === 0) { maxHours = 1; // to avoid division by zeor } let graphHeight = height - 100; stroke(0); //horizontal bar line(margin, height - 50, width - margin, height - 50); // For each day, draw the corresponding bar and label its study hours and name for (let i = 0; i < days.length; i++) { let x = margin + i * (barWidth + gap); let barHeight = map(studyHours[i], 0, maxHours, 0, graphHeight); // Draw a blue bar representing the study hours fill(50, 150, 200); rect(x, height - 50 - barHeight, barWidth, barHeight);
let margin = 60;
 let gap = 20; //gap between days
 let availableWidth = width - 2 * margin;
 let barWidth = (availableWidth - (days.length - 1) * gap) / days.length; 
 let maxHours = max(studyHours); // maxiumum value in the array
 if (maxHours === 0) {
   maxHours = 1;  // to avoid division by zeor
 }
 let graphHeight = height - 100;
 stroke(0);
 //horizontal bar
 line(margin, height - 50, width - margin, height - 50);
 
 // For each day, draw the corresponding bar and label its study hours and name
 for (let i = 0; i < days.length; i++) {
   let x = margin + i * (barWidth + gap);
   let barHeight = map(studyHours[i], 0, maxHours, 0, graphHeight);
   
   // Draw a blue bar representing the study hours
   fill(50, 150, 200);
   rect(x, height - 50 - barHeight, barWidth, barHeight);

 

 

Instruction on How to Use:

Click on ‘start’ to proceed to data logging stage.

Then, enter numerical values for the hours studied each day.

 

Once pressed on ‘submit’, the user will see visualized pattern of data entered.

Since ‘ali’ is not a numerical value, it shows zero, and for the rest, it visualizes the trend and numbers entered.

Embedded Sketch:

 

Future Improvements:

In the future, I want to make it even more dynamic. For instance 7 is not far away from hitting the title. Even though the current program is able to resize depending on the maximum and the minimum relative to other bars, and the graph, yet still, better margins and specific coloration to each bar can make it more sybmolic. For instance hot red can refer to the most hours studied, and simple greenish can refer to the least.

Complete code:

The complete code is extremely lengthy, not really but can be accessed via clicking on the sketch.

 

Leave a Reply