Build a live bitcoin pricing chart

Realtime experiences are governing the tech world today. There is an increasing need for realtime data – an event trigger telling everyone around the world within milliseconds of it happening. While moving this realtime data around poses to be a huge technical challenge, displaying this realtime data visually so a human can infer it usefully is another challenge. So, the DevRel teams at Ably and Kendo UI came together to work on a small application to demonstrate how such challenges can be overcome by using the right SaaS products.

In this tutorial, we’ll show you how you can build an Angular app to get a realtime data stream of changing bitcoin prices in USD using the Ably Hub, (a marketplace for open streaming data sources) and display it conveniently in a chart using Kendo UI’s Angular components. There are many other free-to-use open streaming data sources on the Ably Hub to choose from and so many other components offered by Kendo UI that you can use to plot the realtime data easily visually. So, while this article is a good primer on how to get started, feel free to explore other open data sources and UI components. As a side node, you can also publish your own realtime data using Ably and share it with others and even host it publicly on the Ably Hub.

The application we’ll build would look as follows:


Live bitcoin price chart demo

The complete source code for this app is also hosted on GitHub

Step 1 – Setting up

a. Getting an Ably API key

Before we get started, you will need an Ably API key to authenticate with Ably. If you are not already signed up, you should sign up now for a free Ably account. Once you have an Ably account:

  1. Log into your app dashboard
  2. Under “Your apps”, click on the app you wish to use for this tutorial, or create a new one with the “Create New App” button
  3. Click on the “API Keys” tab
  4. Copy the secret “API Key” value from your Root key and store it so that you can use it later in this tutorial

    Copy API Key screenshot

b. Installing all the pre-requisite libraries

Before jumping into the project, let’s make sure we have the required libraries installed. We’ll need:

  • Angular CLI: You can use NPM installed in the previous step to install the Angular Command Line Interface. The Angular CLI helps you with creating and managing your Angular apps with simple commands. You can run npm install -g @angular/cli in your terminal or command line to install the Angular CLI globally on your system.
  • Kendo UI’s Angular chart component: Only needing the chart component for now, you can run the ng add @progress/kendo-angular-charts command to install just the chart goodies.

c. Creating a new app using the Angular CLI

When you are in the directory of your choice, simply run ng new live-bitcoin-chart, where live-bitcoin-chart is the name of our application. Feel free to replace it with a name of your choice.

d. Serving the app locally to see the changes as you make them

The Angular CLI offers a very handy command ng serve, which will serve up your code locally in your browser and refresh the page automatically when you make any changes to your code.

Step 2 – Creating a chart using Kendo UI’s Angular chart component

First, we’ll need to import the ChartModule into our app! In your app.module.ts, add the following code:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ChartsModule } from '@progress/kendo-angular-charts';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import 'hammerjs';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ChartsModule,
    BrowserAnimationsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now we are ready for the component that we’ll use to house our chart, so let’s go create it!

The CLI comes in handy again here with ng generate component ChartUiPanel. Once you run this in your terminal, you’ll see it generate these files and update our app.module.ts.

$ ng generate component ChartUiPanel
CREATE src/app/chart-ui-panel/chart-ui-panel.component.css (0 bytes)
CREATE src/app/chart-ui-panel/chart-ui-panel.component.html (29 bytes)
CREATE src/app/chart-ui-panel/chart-ui-panel.component.spec.ts (672 bytes)
CREATE src/app/chart-ui-panel/chart-ui-panel.component.ts (299 bytes)
UPDATE src/app/app.module.ts (503 bytes)

Let’s add the chart to our chart-ui-panel.component.ts file and get ready to plug in that realtime data!

<kendo-chart>
    <kendo-chart-title text="Bitcoin live pricing chart"></kendo-chart-title>
    <kendo-chart-legend position="bottom" orientation="horizontal"></kendo-chart-legend>
    <kendo-chart-tooltip format="{0}"></kendo-chart-tooltip>
    <kendo-chart-value-axis>
        <kendo-chart-value-axis-item [title]="{ text: 'Price in USD' }" [min]="10000" [max]="11000">
        </kendo-chart-value-axis-item>
    </kendo-chart-value-axis>
    <kendo-chart-category-axis>
        <kendo-chart-category-axis-item [title]="{ text: 'Time stamps' }" [categories]="timestamps[0].timedata">
        </kendo-chart-category-axis-item>
    </kendo-chart-category-axis>
    <kendo-chart-series>
        <kendo-chart-series-item *ngFor="let item of series" type="line" style="smooth" [data]="item.data"
            [name]="item.name">
        </kendo-chart-series-item>
    </kendo-chart-series>
</kendo-chart>

Here we are using the kendo-chart, chart-title, chart-legend and more to create our Kendo UI Chart! The chart and the legend are the next two things we set up and pretty straight forward.

The tooltip is established and formatted with <kendo-chart-tooltip format="{0}"></kendo-chart-tooltip>. This isn’t the only thing you can do with tooltips; however, checkout the Kendo UI Chart docs for all the cool ways to customize tooltips on your chart!

For our vertical and horizontal axes, we are using kendo-chart-value-axis and kendo-chart-category-axis, and setting the items inside of them to Price and Time Stamps, respectively.

The last bit inside our chart is arguably the most important — kendo-chart-series. This is what will create the line in our chart. For this item we will loop over the points in our series that we will set in just a moment with the data from the Ably Hub!

Step 3 – Subscribing to a live bitcoin price data stream from the Ably Hub

The Ably Hub is a marketplace for open realtime data streams. It is powered by Ably’s API Streamer that lets you easily publish and subscribe to realtime data streams to and from various organizations or developer groups. For this article, we’ll be using the Bitcoin Pricing product from the Ably Hub. Each product hosted on the Ably Hub comes with some documentation on how you can subscribe to the data stream and start receiving updates. Some of the products are self-subscribe while others require the data producer to approve or decline your request to subscribe to the data source.

The produce we’ll be using is self-subscribe, so go ahead and subscribe to the product on the Ably Hub after logging into your Ably account. This will give your apps (that are authenticated using API keys you earlier copied) access to the bitcoin USD data stream. After this, you are all set to use this data stream in your app.

Let’s get back to our Angular project.

We’ll begin by adding the Ably library as a CDN link in the index.html file. Paste the following line of code:

<script lang="text/javascript" src="https://cdn.ably.com/lib/ably.min-1.js"></script>

Next, in our chart component, i.e. chart-ui-panel.component.ts, let’s declare Ably with the type any, as follows:

declare var Ably: any;

Inside the main class in the chart component, i.e. ChartUiPanelComponent, let’s declare the types of some more variables that we’ll use later:

ably: any
usdPriceChannel: any
dataInDecimalcopy: any = 0;

Next, replace the contents of the ngOnInit() method with the following:

this.ably = new Ably.Realtime('<YOUR-ABLY-API-KEY>');
// make sure you have access to this product by self-subscribing to it via the Ably Hub
this.usdPriceChannel = this.ably.channels.get('[product:ably-coindesk/bitcoin]bitcoin:usd');

this.usdPriceChannel.subscribe((msg) => {
  var timestamp = new Date(msg.timestamp)
  const dataInDecimal = msg.data.replace(/\,/g, '');

  // plot the data only when it has changed
  if (dataInDecimal != this.dataInDecimalcopy) {
    const dataCopy = this.series[0].data.slice(0);
    const timeCopy = this.timestamps[0].timedata.slice(0);
    dataCopy.push(parseFloat(dataInDecimal))
    timeCopy.push(timestamp.getHours() + ":" + timestamp.getMinutes() + ":" + timestamp.getSeconds())
    this.dataInDecimalcopy = dataInDecimal;

    // *optional: limit amount of data points shown
    if (dataCopy.length > 20) { dataCopy.shift(); }
    if (timeCopy.length > 20) { timeCopy.shift(); }
    // set the OG data equal to the copy
    this.series[0].data = dataCopy;
    this.timestamps[0].timedata = timeCopy;
  }
})

So, let’s understand what the above code snippet does.

We started with initializing the Ably realtime client library using the API key. This is the basic authentication method to authenticate clients with Ably. While this is simple and easy to use for this demo, in reality, we always recommend that you use Token authentication in production level apps. Tokens expire at regular intervals and expect the clients to request new ones, thus ensuring better security as the API key is never directly exposed in the client-side code.

Make sure to replace <YOUR-ABLY-API-KEY> in the above code snippet with your real API key that you copied and saved in Step 1.

After initializing the Ably realtime client library, we’ll need to attach it to the channel on which the required data is being published and then subscribe to it to receive updates as they happen continuously. All the data sharing in Ably happens over fundamental units called channels. The ably.channels.get() lets you implicitly attach to a channel. We know the name of the channel from the product documentation on the Ably Hub. In this case, the channel name to be used is [product:ably-coindesk/bitcoin]bitcoin:usd.

The subscribe() method lets you subscribe to the channel to receive realtime updates. After you’ve done that, Ably will automatically push updates over a duplex connection that will remain open while the application is running. You can learn more about how WebSockets work from our in-depth explanatory article.

Whenever some data comes through as a callback of the subscribe() method, we simply push the new data in the arrays we set up earlier – which serve as the data source for the Chart UI. We also get the timestamp to be displayed on the horizontal axis, so the data points make more sense.

That’s it! You have a neat chart that updates with live data based on real events.

The complete source code for this app is also hosted on GitHub

Further reading