-
Notifications
You must be signed in to change notification settings - Fork 63
4: Make a visualization in the client
Up until now, we only show the data in the console. That's not very beneficial for users. In this stage, we will create an easy and straight-forward visualization of the data: Updating the client with realtime data received by the logger.
Navigate to the 'every-bit-matters' folder. Type:
$ git checkout -f stage-4
Nice. You have now checked out the code required to start. Let's begin.
We will now create a table which rerenders our results in realtime from the logger. Something like this:
To begin with, we need to extend our index.html with the boilerplate markup for a table.
Write a table, where the <th>headers</th>
represent the key-value pairs from the logger:
- date
- ping
- download
- upload
When you are done, it should look like:
client/index.html
<!DOCTYPE html>
<html>
<head>
<title>Every Bit Matters</title>
<link href="css/client.css" rel="stylesheet">
<script src="socket.io/socket.io.js"></script>
<script src="d3.js"></script>
</head>
<body>
<h1>Speed Test Logger</h1>
<table>
<thead>
<tr>
<th>Date</th>
<th>Ping</th>
<th>Upload</th>
<th>Download</th>
</tr>
</thead>
<tbody>
<!-- Render Area -->
</tbody>
</table>
<script src="client.js"></script>
</body>
</html>
Now that we have created our boilerplate table, lets dive into the client/client.js to dynamically update the table with results.
PS: We have moved the <script src="client.js"></script>
to before the closing </body>
tag. This is to ensure that the DOM is rendered in the browser before we load any code which tries to manipulate it.
To be able to dynamically render the table with results from the logger, we need to elaborate on the function run by the event socket.on('client:display', ...
.
We can start by updating this function, by selecting the DOM element where we want to render the results.
client/client.js
...
socket.on('client:display', function (results) {
var tbody = document.getElementsByTagName('tbody')[0];
console.log(tbody);
});
Now, run your server, and validate that the Node "tbody" is logged in the console.
JavaScript comes with a forEach function for arrays: Allowing you to run a function on every element in the array.
Lets implement a forEach function which allows us to console.log(the result objects)
.
client/client.js
...
socket.on('client:display', function (results) {
var tbody = document.getElementsByTagName('tbody')[0];
results.forEach(function (result) {
console.log(result);
});
});
You can validate that your results are coming in clearly by reloading the web app in the browser.
Now we have everything we need to build, populate, and insert our DOM elements. Let us extend our function by creating a single <tr>
and four <td>
elements for each result, and populate them with the result data:
...
socket.on('client:display', function (results) {
var tbody = document.getElementsByTagName('tbody')[0];
results.forEach(function (result) {
// create table row
var tr = document.createElement('tr');
// create columns
var date = document.createElement('td');
var ping = document.createElement('td');
var download = document.createElement('td');
var upload = document.createElement('td');
// populate columns
date.innerText = result.date;
ping.innerText = result.ping;
download.innerText = result.download;
upload.innerText = result.upload;
});
});
OK. We have all the elements we need, and now we can insert them into the DOM. But first, as the logger always sends his history along with the new data, we need to clear the tbody:
client/client.js
...
socket.on('client:display', function (results) {
var tbody = document.getElementsByTagName('tbody')[0];
tbody.innerHTML = "";
...
});
Now we can insert the new elements we have created into the <tbody>
:
socket.on('client:display', function (results) {
var tbody = document.getElementsByTagName('tbody')[0];
tbody.innerHTML = "";
results.forEach(function (result) {
// create table row
var tr = document.createElement('tr');
// create columns
var date = document.createElement('td');
var ping = document.createElement('td');
var download = document.createElement('td');
var upload = document.createElement('td');
// populate columns
date.innerText = result.date;
ping.innerText = result.ping;
download.innerText = result.download;
upload.innerText = result.upload;
// append columns to row
tr.appendChild(date);
tr.appendChild(ping);
tr.appendChild(download);
tr.appendChild(upload);
// append row to tbody
tbody.appendChild(tr);
});
});
Great job! You are now finished.
Next assignment: Deploying to Heroku