In this tutorial, we will build a realtime chart which will show the current active users, represented by a bar chart, without reloading the page. This is just a demo example to showcase the functionality of creating dynamic charts in realtime. You can extend this to create numerous reports in realtime for your application.
Today, we will create a realtime chart system using Laravel and Pusher. With the release of Echo, Laravel has provided an out of the box solution for implementing realtime data synchronisation using event broadcasting. It is simple and we can get started in a matter of minutes.
A basic understanding of Laravel and Vue is needed to follow this tutorial.
We need to sign up on Pusher and create a new app:
First, we will grab a fresh copy of Laravel:
laravel new realtime-chart-laravel-pusher
This will install the latest version of the Laravel framework and download the necessary dependencies. Next, we will install the Pusher PHP SDK using Composer:
composer require pusher/pusher-php-server
Next, we will install the JavaScript dependencies:
npm install
Now, we need to install the Javascript libraries necessary for realtime event broadcasting and displaying charts: Laravel Echo, chart.js and Pusher JS
npm install --save laravel-echo pusher-js chart.js
We will require some form of user authentication mechanism to demonstrate the functionality. Let us use the default authentication scaffolding provided by Laravel:
php artisan make:auth
First, we need to set the APP_ID
, APP_KEY
, APP_SECRET
and APP_CLUSTER
in the environment file. We can get these details in our Pusher app dashboard:
1## .env 2 3BROADCAST_DRIVER=pusher 4 5PUSHER_APP_ID=your-pusher-app-id 6PUSHER_APP_KEY=your-pusher-app-key 7PUSHER_APP_SECRET=your-pusher-app-secret 8PUSHER_APP_CLUSTER=your-pusher-app-cluster
Next, we need to create a fresh Echo instance in our applications's JavaScript. We can do so at the bottom of our resources/assets/js/bootstrap.js
file:
1import Echo from "laravel-echo" 2 3window.Echo = new Echo({ 4 broadcaster: 'pusher', 5 key: 'your-pusher-app-key', 6 cluster: 'ap2', 7 encrypted: true 8});
The core feature of our app is the number of active users shown as a realtime bar chart. Whenever a user joins or leaves this page, the graph for online users will be automatically updated.
We will create a bar chart with hard coded default values. Later, we will retrieve these values in realtime and update the chart accordingly.
To create a chart, we need to first instantiate the Chart
class. Let us first grab the element or context and then create a chart instance with the default datasets:
<canvas id="myChart" height="100"></canvas>
1let ctx = document.getElementById("myChart"); 2 3let myChart = new Chart(ctx, { 4 type: 'bar', 5 data: { 6 labels: ['Online'], 7 datasets: [{ 8 label: '# of Users', 9 data: [3], 10 borderWidth: 1 11 }] 12 } 13});
Below is the screenshot for how the graph would look like:
As you can see in the above code sample, we are populating the values through data
property in the datasets
array. For the sake of demonstration we have hard coded the values. Let us now map it to the realtime values.
First we will create a property in our component to reflect the count of registered and online users. Initially, we will set it to the default values:
1data() { 2 return { 3 count: 0 4 } 5},
Let us now create a method to draw our chart using the values specified above.
1drawChart() { 2 let ctx = document.getElementById("myChart"); 3 let myChart = new Chart(ctx, { 4 type: 'bar', 5 data: { 6 labels: ['Online'], 7 datasets: [{ 8 label: '# of Users', 9 data: [this.count], 10 borderWidth: 1 11 }] 12 }, 13 options: { 14 scales: { 15 yAxes: [{ 16 ticks: { 17 beginAtZero:true 18 } 19 }] 20 } 21 } 22 }); 23}
Next, we need to update the above count in realtime whenever a new user joins the page or some user leaves the page.
We'll implement that with Echo and it is super simple. Let us go and fill out our update
method in the Example
Vue component.
1update() { 2 Echo.join('chart') 3 .here((users) => { 4 this.count = users.length; 5 this.drawChart(); 6 }) 7 .joining((user) => { 8 this.count++; 9 this.drawChart(); 10 }) 11 .leaving((user) => { 12 this.count--; 13 this.drawChart(); 14 }); 15}
join
is used when we want to join a presence channel and that is used to tell us who else is on the page. Presence channels are automatically private channels. We do need to authenticate them.
here
gives us a list of users that are also present on the same page.
joining
will be executed whenever a new user joins the channel or page in the above scenario.
leaving
will be executed whenever a user leaves the channel.
Every presence channel is a private channel. Laravel Echo will automatically call the specified authentication route. However, we still need to write the authentication logic which will actually authorize the user to listen to a particular channel.
Authorization logic is written in the routes/channels.php
. The authorization logic for our chart
channel is:
1Broadcast::channel('chart', function ($user) { 2 return [ 3 'name' => $user->name 4 ]; 5});
We are not going to return true
or false
. If the user is authenticated to listen on this presence channel we are going to return an array of data that we want returned to that callback in the update
method.
You can write the authentication logic as required for your application in the above callback and return null if authorization fails.
That's it! Now, whenever a user joins or leaves the page, it will be updated in the chart in realtime.
Below is our Example component written using Vue.js
1<template> 2 <div class="container"> 3 <div class="row"> 4 <div class="col-md-8 col-md-offset-2"> 5 <div class="panel panel-default"> 6 <div class="panel-heading">Example Component</div> 7 8 <div class="panel-body"> 9 <canvas id="myChart" height="100"></canvas> 10 </div> 11 </div> 12 </div> 13 </div> 14 </div> 15</template> 16 17<script> 18 import Chart from 'chart.js' 19 20 export default { 21 data() { 22 return { 23 count: 0, 24 labels: ['Online'] 25 } 26 }, 27 mounted() { 28 this.update(); 29 this.drawChart(); 30 }, 31 methods: { 32 drawChart() { 33 let ctx = document.getElementById("myChart"); 34 let myChart = new Chart(ctx, { 35 type: 'bar', 36 data: { 37 labels: this.labels, 38 datasets: [{ 39 label: '# of Users', 40 data: [this.count], 41 borderWidth: 1 42 }] 43 }, 44 options: { 45 scales: { 46 yAxes: [{ 47 ticks: { 48 beginAtZero:true 49 } 50 }] 51 } 52 } 53 }); 54 }, 55 update() { 56 Echo.join('chart') 57 .here((users) => { 58 this.count = users.length; 59 this.drawChart(); 60 }) 61 .joining((user) => { 62 this.count++; 63 this.drawChart(); 64 }) 65 .leaving((user) => { 66 this.count--; 67 this.drawChart(); 68 }); 69 } 70 } 71 } 72</script>
Below is the quick demonstration of our application:
In this article, we have covered how to create a realtime chart using Laravel and Pusher. We have covered the configuration options necessary to get started, and the example above should help you fill in the gaps and give an overview of some of the other configuration options available to you.