Build

Streaming Updates to Real-time Progress Bars with JavaScript

Anmol Agrawal on Aug 17, 2017
Streaming Updates to Real-time Progress Bars with JavaScript

This tutorial is a quick and easy example of Real-time Updates using PubNub to stream status updates and display the progress in a real-time progress bar.

There are more than a fair share of tutorials out there that show you how to build a progress bar in JavaScript. But what good is a static progress bar?

In this tutorial, we'll show you how to connect your progress bar to the internet and stream updates to it in real time. This could be inventory from an IoT sensor, capacity in a chatroom, or uploading files – an infinite amount of other use cases.

You can find the source code for our real-time JavaScript progress bar here.

script.js

This Node.js script replicates the effect of the file upload. Ideally, we will get the percentage uploaded as bytes uploaded divided by total byte size of the file. Once we have the percentage, we are sending that data to ‘progress-bar’ channel every 5 sec to give an effect of file uploading taking time.

var pubnub = require("pubnub")({
   subscribe_key: 'demo', // always required
   publish_key: 'demo' // only required if publishing
});
var percentages = [0,20,40,60,80,100]
function send_percentage(percentage){
   pubnub.publish({
       channel: "progress-bar",
       message: {"value": percentage},
       callback: function(m){console.log(m)}
   });
}
var interval_id = setInterval(function(){
   send_percentage(percentages.shift());
}, 5000)

index.html

This is a simple HTML template with couple of CDNs (jQuery and PubNub) and placeholder for circular progress bar.

<!DOCTYPE html>
<html >
 <head>
   <meta charset="UTF-8">
   <title>Circular Progress Bar</title>
   <link rel="stylesheet" href="css/normalize.css">
     <link rel="stylesheet" href="css/style.css">
 </head>
 <body>
<div id="page">
 <div class="progress-bar">
     <canvas id="inactiveProgress" class="progress-inactive" height="275px" width="275px"></canvas>
   <canvas id="activeProgress" class="progress-active"  height="275px" width="275px"></canvas>
   <p>0%</p>
 </div>
</div>
   <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
   <script src="https://cdn.pubnub.com/pubnub-3.7.13.min.js"></script>
   <script src="js/index.js"></script>
 </body>
</html>

index.js

Most of this JavaScript is responsible for animation effect of circular progress bar. But apart from that, we are just subscribing to that particular PubNub channel, and passing the received percentage to drawProgress method.

$(document).ready(function(){
            var pubnub = PUBNUB({
                subscribe_key : 'demo'
            });
            var $pCaption = $('.progress-bar p');
            var iProgress = document.getElementById('inactiveProgress');
            var aProgress = document.getElementById('activeProgress');
            var iProgressCTX = iProgress.getContext('2d');
            
            drawInactive(iProgressCTX);
            pubnub.subscribe({
                channel: "progress-bar",
                message: function(message){
                    var percentage = message.value / 100;
                    console.log(percentage + '%');
                    drawProgress(aProgress, percentage, $pCaption);
                }
            })
            function drawInactive(iProgressCTX){
                iProgressCTX.lineCap = 'square';
                //outer ring
                iProgressCTX.beginPath();
                iProgressCTX.lineWidth = 15;
                iProgressCTX.strokeStyle = '#e1e1e1';
                iProgressCTX.arc(137.5,137.5,129,0,2*Math.PI);
                iProgressCTX.stroke();
                //progress bar
                iProgressCTX.beginPath();
                iProgressCTX.lineWidth = 0;
                iProgressCTX.fillStyle = '#e6e6e6';
                iProgressCTX.arc(137.5,137.5,121,0,2*Math.PI);
                iProgressCTX.fill();
                //progressbar caption
                iProgressCTX.beginPath();
                iProgressCTX.lineWidth = 0;
                iProgressCTX.fillStyle = '#fff';
                iProgressCTX.arc(137.5,137.5,100,0,2*Math.PI);
                iProgressCTX.fill();
            }
            function drawProgress(bar, percentage, $pCaption){
                var barCTX = bar.getContext("2d");
                var quarterTurn = Math.PI / 2;
                var endingAngle = ((2*percentage) * Math.PI) - quarterTurn;
                var startingAngle = 0 - quarterTurn;
                bar.width = bar.width;
                barCTX.lineCap = 'square';
                barCTX.beginPath();
                barCTX.lineWidth = 20;
                barCTX.strokeStyle = '#76e1e5';
                barCTX.arc(137.5,137.5,111,startingAngle, endingAngle);
                barCTX.stroke();
                $pCaption.text( (parseInt(percentage * 100, 10)) + '%');
            }
        });

And that's it! This is just scratching the surface of real-time updates using PubNub. Check out some of our other use cases, and as always, you can contact us with any questions you have.