Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Real-time data is data that is presented as it is acquired. It is often used in tracking or monitoring systems like traffic GPS system, auction/bidding applications and stock trading applications. Charts help with a graphical representation of this data and help the viewer make a decisionĀ easily.
In this post, Iāll show you how to make real-time chart in JavaScript. Weāll be building a basic voting web application with a page for voting, and another page with a real-time chart showing the voting result as it happens. Hereās a peek at what weāll beĀ building
Iāll be using Chart.js and Hamoni Sync to build it. Chart.js is a simple JavaScript charting library. Hamoni Sync is a real-time state synchronisation service which enables you to synchronise your application state in real-time. The vote result is the state we want show users in real-time. Hamoni Sync makes this easier by allowing you to define state for your application, while you avoid designing complex state logic around publish/subscribe systems.
Setup theĀ code
We will be using a project template which already has the HTML pages and node app to serve the static files. Follow the instruction below to set itĀ up
- Clone the repo from GitHub by running git clone https://github.com/pmbanugo/realtime-chartjs-hamoni-starter.git in the command line. If youāre not using git, you can download itĀ here.
- Switch to the project directory cd realtime-chartjs-hamoni-starter
- Install the dependencies by running npm install. This will install express and Hamoni Sync node modules. #Ā Backend
The server.js file contains code to server HTML pages in the public folder. Lines 9ā14 defines a default state for the voting application. It contains 4 candidates with their vote count asĀ 0.
let voteData = [ { candidate: "Peter Mbanugo", vote: 0 }, { candidate: "Angela Daniels", vote: 0 }, { candidate: "Rose Philly", vote: 0 }, { candidate: "James Crump", vote: 0 } ];
It also defines a REST endpoint for voting defined from lines 18 to 30. When a vote comes in, we may want to save that data to a database and then update the chart with an up-to-date result of the vote. The chart state will be communicated in real-time using Hamoni Sync. On line 40 I have declared a statement to initialise Hamoni but we need an account ID and appĀ ID.
Create Hamoni Account andĀ App
Login to the Hamoni dashboard (or Signup if you donāt already have an account). When logged in you can click the Show Account ID button to see your account ID. We need a Hamoni App ID, hence we need to create an app from the dashboard. An app is a container that can hold application state. Youād typically want to have a separate Hamoni app for each of your application.
Under the āCreate Applicationā header, enter an application name and click the create button. Within a few seconds, you should see it created and displayed in the application listĀ section.
Copy the app and account ID and replace them with the string value on line 40 in server.js
Create application state inĀ Hamoni
Now we need to create state in Hamoni Sync. To do that we need to use a sync primitive. Sync primitives are what you use to define and manipulate state. Theyāre basically a way to categorise or differentiate kinds of data to be stored. There are 3 sync primitives:
- Value Primitive: This kind of state holds simple information represented with datatypes like string, boolean or numbers. It is best suited for cases such as unread message count, toggles,Ā etc.
- Object Primitive: Object state represents states that can be modelled as a JavaScript object. An example usage could be storing the score of aĀ game.
- List Primitive: This holds a list of state objects. A state object is a JavaScript object. You can update an item based on its index in theĀ list.
Iāll be using an object primitive for thisĀ post.
Add the following function in server.js
function createState() { hamoni .createObject("election", voteData) .then(statePrimitive => { console.log("election state created"); state = statePrimitive; }) .catch(console.log); }
This creates a state with the name of *election* *and state value using the variable `*voteData*.* Then we need to connect to the Hamoni Sync server. We do this by calling hamoni.connect(). Add the following code below the function createState()`
hamoni.connect().then(() => createState()).catch(console.log);
If it connects successfully to the server, we call the createState() function to create the state for ourĀ chart.
Update application state
We want to update the state when a new vote comes in. The object primitive which holds our state has an update() method which can be used to update the state. We will update the election state when the user calls /voteendpoint of our API. Below lines 27, add the following code to update theĀ state
app.post("/vote", function(req, res) { .... state.update(voteData); .... });
This will update the state and broadcast the update to connected clients.
Frontend
Our backend is ready to accept votes and update the state. Now we need to build the frontend to send in votes and display realtimeĀ chart.
The starter template we cloned at the beginning has the files public/vote.html and public/js/vote.js. These files already contain code to display a form in the web page and javascript to post to the server. I skipped writing that code here because itās a basic HTML form and JavaScript to send form data to the server. Do leave a comment if anything there is confusing.
The chart will be displayed in index.html inside the public folder. index.html already contains script tags for Chart.js and Hamoni Sync (see lines 17 andĀ 18)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script> <script src="https://unpkg.com/hamoni-sync@0.2.0/hamoni.dev.js"></script>
Render theĀ chart
Open the file public/index.js. Add the function below to render a chart in the webĀ page.
function renderChart(state) { var ctx = document.getElementById("myChart").getContext("2d"); var chart = new Chart(ctx, { // The type of chart we want to create type: "bar", // The data for our dataset data: { labels: state.map(s => s.candidate), datasets: [ { label: "Elections 2018", backgroundColor: "rgb(255, 99, 132)", borderColor: "rgb(255, 99, 132)", data: state.map(s => s.vote) } ] }, // Configuration options go here options: { scales: { xAxes: [ { time: { unit: "Vote" }, gridLines: { display: false }, ticks: { maxTicksLimit: 6 } } ], yAxes: [ { ticks: { min: 0, max: 30, maxTicksLimit: 10 }, gridLines: { display: true } } ] }, legend: { display: true } } }); }
This function takes a parameter that represents our chart state. The type options specify the type of chart we want to render, in this case, a bar chart. The data option defines properties used to display data for the chart. There are two important properties that I want to bring to your attention. First is the label property on line 8, labels: state.map(*s*
*=>*` `s.candidate)`It gets its value from the state. The chart state is an array of each electoral candidate and their vote. With that code, weāre setting the candidateās name as labels for the chart. The second is `data: state.map(``*s*`
=>s.vote)` on line 14. It sets the data for theĀ chart.
Now we need to retrieve chart state and render theĀ chart.
Get state and stateĀ updates
To retrieve the chart state, we need to connect to Hamoni Sync. Add the following code to get state and state updates, then render the chart based onĀ that:
let hamoni = new Hamoni("Account_ID", "APP_ID");hamoni .connect() .then(response => { hamoni .get("election") .then(statePrimitive => { renderChart(statePrimitive.get());
statePrimitive.onUpdated(state => renderChart(state)); }) .catch(console.log); }) .catch(error => console.log(error));
If the client successfully connects to Hamoni Sync, we call hamoni.get("election") to get our election state. If it succeeds, we call renderCharts() with the value for theĀ state.
To be notified of state updates, we call onUpdated() on the state primitive with a callback that should be executed each time thereās anĀ update.
Now we can test our code to see it working. Open the command line and run npm start, then open your browser and navigate to localhost:5000.
Voila!! š
Real-time chart state made with less hassle. Chart.js is easy to use. Hamoni Sync reduces the development time and effort in designing complex state logic around publish/subscribe systems because it embraces the concept ofĀ state.
You can get the finished source code onĀ GitHub.
Links
Also shared onĀ Dev.to
Real-time Chart in JavaScript with ChartJS and Hamoni Sync was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.