Integrate Charts in your AngularJS Hybrid Apps with NVD3

There are many options out there if you want to display charts in hybrid apps. Since a hybrid app is basically a web application running HTML, JavaScript and CSS, you can use any JavaScript charting library or you can even generate charts in a backend and display them as static images.

In this article we will take a look at NVD3 which are reusable charts based on the D3 data visualization library. We will see how it can be used to create a chart using pure JavaScript and also how the chart can be wrapped in an AngularJS directive.

Some other popular JavaScript libraries are:

  • D3.js — D3 stands for Data-Driven Documents. It’s a very powerful library for data visualization that uses SVG. It’s quite low-level so even making a simple chart can be a quite complex task, but the end result is stunning.
  • Chart.js — Simpler to use than D3.js but still very customizable. Instead of SVG it’s using canvas, so it’s a very good option if you need to support older browsers or WebViews.
  • n3-charts — This library is built on top of AngularJS and D3.js. It makes displaying charts in an AngularJS a breeze.

We’ve recently been discussing if we should support a charting library in Onsen UI and if so which one we should choose. One of the best candidates is NVD3 since it provides a good combination of ease-of-use and the powerful data visualization of D3.js. It’s also very simple to integrate in AngularJS apps, as we will see in this article.

Some good things about NVD3:

  • Responsive — Charts created using NVD3 will be rendered differently depending on the size of the screen and the orientation.
  • Dynamic — Charts can be refreshed easily when the data changes.

Below is a simple app using NVD3 and Onsen UI that shows the population for all the countries on Earth.

The population data in the app is fetched from the World Population API.

Creating a chart with NVD3

First create a new HTML file and load the following resources:

  • d3.js
  • nv.d3.js
  • nv.d3.css

They are all available on CDN, so we can do:

Let’s first make a chart and render it on the screen. Create a file called chart.js and add the following code:

If you run this code in the browser it will display the text “No Data Available.”. Which makes sense since we haven’t added any data yet. The data should be defined with the following format:

So let’s go ahead and generate some simple data and plug it into the chart:

Saving and reloading the browser will show something like this:

Wrapping a NVD3 chart with an AngularJS directive

One of the strength of AngularJS is data-binding, so let’s make an AngularJS directive where we can bind the chart data to an HTML attribute. In this section we will create a <line-chart> component that can be used in the following way:

<line-chart data="data" height="200px" width="120px"></line-chart>

We also add some <input> tags so the user can change the data. The final markup will look like this:

Quite short but it’s all that’s needed! We’ll bootstrap the app and initialize the data array with some dummy data in the controller:

At this point we have not written any code for the directive so only the input elements will work. Implementing the directive is pretty straight forward and we’ll borrow some code from the previous pure JavaScript example. I’ve used two services (d3 and nv) that just return the respective objects.

In the $watch callback we check if the chart has been initialized before calling the update() function. Since nv.addGraph() is asynchronous the callback might fire before the chart has been created, in which case we get the following error:

TypeError: Cannot read property 'apply' of undefined

You can play around with the chart below. Because of the data-binding the chart will be re-rendered every time the data changes.

A directive similar to this one was used in the example at the start of the article. The code can be found on my GitHub page.

Conclusion

If you have any questions about the content of the article please write a comment below. In the case you found some mistakes or you would like to improve the content, feel free to make a pull request to the website repository. We appreciate all kinds of feedback!


Originally published at onsen.io on July 30, 2015.