I have this .ejs page which contains a table. In that table, there are 4 columns which contain numbers. I want to display an average of each of these columns on the same page.
I have managed to get the averages, but it is very inefficient and is taking up a lot of space in the .ejs file.
This is what the page looks like.
Here is my code for the .ejs file (including my poorly coded average "calculator"):
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<title>MTU Phone Usage Monitor</title>
<link rel="stylesheet" href="/stylesheets/styleTable.css"></link>
</head>
<body>
<div class="banner">
<div class="navbar">
<img src="\images\logo.png" class="logo">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/phone/create">New Entry</a></li>
<li><a href="/table">View Data</a></li>
<li><a href="/help">Help</a></li>
</ul>
</div>
<form action="/phone/find" method="post"></form>
<div class="table-wrapper">
<table class="tableData" id="table">
<caption>
<%= title %>
</caption>
<thead>
<tr>
<th>Name</th>
<th>Education Usage</th>
<th>Shopping Usage</th>
<th>Searching/Browsing usage</th>
<th>Social Media usage</th>
<th>Date and Time</th>
<th></th>
</tr>
</thead>
<tbody>
<% for(var i=0; i < phonelist.length; i++) { %>
<tr>
<td>
<%= phonelist[i].name %>
</td>
<td>
<%= phonelist[i].timeEducation %>
</td>
<td>
<%= phonelist[i].timeShopping %>
</td>
<td>
<%= phonelist[i].timeBrowsing %>
</td>
<td>
<%= phonelist[i].timeSocial %>
</td>
<td>
<%= phonelist[i].createdAt %>
</td>
<td>
<div class="secret">
<form action="/phone/delete" method="post"> <input type="String" value="<%= phonelist[i].id%>" name="id" readonly><button type="Submit">Delete</button></form>
<form action="/phone/update" method="post"> <input type="String" value="<%=phonelist[i].id%>" name="id" readonly><button type="Submit">Update</button></form>
</div>
</td>
</tr>
<% } %>
</div>
<span id="education"></span><br>
<span id="shopping"></span><br>
<span id="browsing"></span><br>
<span id="social"></span>
<script>
var table = document.getElementById("table"),
avgVal, sumVal = 0,
rowCount = table.rows.length - 1; // minus the header
//calculate average education usage
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[1].innerHTML);
}
document.getElementById("education").innerHTML = "Average Education = " + parseFloat(sumVal / rowCount);
avgVal, sumVal = 0;
//calculate average shopping usage
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[2].innerHTML);
}
document.getElementById("shopping").innerHTML = "Average Shopping = " + parseFloat(sumVal / rowCount);
avgVal, sumVal = 0;
//calculate average browsing usage
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[3].innerHTML);
}
document.getElementById("browsing").innerHTML = "Average Shopping = " + parseFloat(sumVal / rowCount);
avgVal, sumVal = 0;
//calculate average browsing usage
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[3].innerHTML);
}
document.getElementById("browsing").innerHTML = "Average Shopping = " + parseFloat(sumVal / rowCount);
avgVal, sumVal = 0;
//calculate average social usage
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[4].innerHTML);
}
document.getElementById("social").innerHTML = "Average Shopping = " + parseFloat(sumVal / rowCount);
</script>
</body>
</html>
Here is the code for where the data comes from:
phoneRouter.route('/find')
.post((req, res, next) => {
phones.find({ name: req.body.name })
.then((phonetaken) => {
phones.find(req.body)
.then((phonefound) => {
res.render('oneFound.ejs', { 'phonelist': phonefound, title: 'All data recieved from user: ' + req.body.name }); //can use datadisplay
}, (err) => next(err));
})
})
I believe it is the aggregate
method that would be used to calculate the averages here. How do I implement it?
How do I shorten that code, make it more presentable and more readable.
I think I could put a for loop inside of a for loop, but I'm not sure how to implement it and get all 4 averages displaying.
With this, I also want to generate a bar graph of the averages at the bottom of the page.
How would I shorten my code/make it more efficient? How would I generate a bar graph of the averages?
I have managed to embed 2 for
loops. Makes the script look much cleaner this way.
Check it out:
<script>
var table = document.getElementById("table"),
avgVal, sumVal = 0,
rowCount = table.rows.length - 1;
for (var x = 1; x < 5; x++) {
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[x].innerHTML);
}
if (x == 1) {
var text = "Average Education = ";
} else if (x == 2) {
var text = "Average Shopping = ";
} else if (x == 3) {
var text = "Average Browsing = ";
} else if (x == 4) {
var text = "Average Social = "
}
document.getElementById(String(x)).innerHTML = text + parseFloat(sumVal / rowCount);
avgVal, sumVal = 0;
}
</script>
Then span
tags looked like this:
<span id="education"></span><br>
<span id="shopping"></span><br>
<span id="browsing"></span><br>
<span id="social"></span>
Now they look like this:
<span id="1"></span><br>
<span id="2"></span><br>
<span id="3"></span><br>
<span id="4"></span>