First, we will set up an angularjs template that serves as a boilerplate for the examples and the application. We will see a typical directory structure for an angularjs project and initialize a controller. Similar to the previous example, the controller will generate random data that we want to display in an autoupdating chart.

Next, we will wrap D3.js in a factory and create a directive for the visualization. You will learn how to isolate the components from each other. We will create a simple angularjs directive and write a custom compile function to create and update the chart.

In the end, you will learn about unit tests, integration tests, set them up, and implement them for the visualization components. This will make the component maintainable and keep it bug free.

In this Tutorial, you will learn how to:

  • Set up a simple angularjs application
  • Integrate D3.js into angularjs
  • Create a visualization directive
  • Write unit tests in the visualization component
  • Write integration tests for the application


Setting up an angularjs application

To get started with this tutorial, I assume that you feel comfortable with the main concepts of angularjs: the application structure, controllers, directives, services, dependency injection, and scopes. I will use these concepts without introducing them in great detail, so if you do not know about one of these topics, first try an intermediate angularjs tutorial or read the recommended literature in tutorial 1, The Magic of SVG, D3.js, and angularjs.

Organizing the directory

To begin with, we will create a simple angularjs boilerplate for the examples and the visualization application. We will use this boilerplate during the development of the sample application throughout the tutorial. Let’s create a project root directory that contains the following files and folders:

  • bower_components/: This directory contains all third-party components
  • src/: This directory contains all source files
  • src/app.js: This file contains source of the application
  • src/app.css: CSS layout of the application
  • test/: This directory contains all test files (test/config/ contains all test configurations, test/spec/ contains all unit tests, and test/e2e/ contains all integration tests)
  • index.html: This is the starting point of the application


Installing angularjs

In this tutorial, we use the angularjs version 1.3.14, but different patch versions (~1.3.0) should also work fine with the examples. Let’s first install angularjs with the Bower package manager. Therefore, we execute the following command in the root directory of the project:

bower install angular#1.3.14

Now, angularjs is downloaded and installed to the bower_components/ directory. If you don’t want to use Bower, you can also simply download the source files from the angularjs website and put them in a libs/ directory.


Note that—if you develop large angularjs applications—you most likely want to create a separate bower.json file and keep track of all your third-party dependencies.

Bootstrapping the index file

We can move on to the next step and code the index.html file that serves as a starting point for the application and all examples of this section. We need to include the JavaScript application files and the corresponding CSS layouts, the same for the chart component. Then, we need to initialize angularjs by placing an ng-app attribute to the html tag; this will create the root scope of the application. In this tutorial, we will call the angularjs application myApp, as shown in the following code:

<html ng-app="myApp"> 
    <!-- Include 3rd party libraries -->
    <script src="bower_components/d3/d3.js" charset="UTF-8"></script>
    <script src="bower_components/angular/angular.js" charset="UTF-8"></script>

    <!-- Include the application files -->
    <script src="src/app.js"></script>
    <link href="src/app.css" rel="stylesheet">

    <!-- Include the files of the chart component -->
    <script src="src/chart.js"></script>
    <link href="src/chart.css" rel="stylesheet">

    <!-- angularjs example go here  -->

For all the examples in this section, I will use the exact same setup as the preceding code. I will only change the body of the HTML page or the JavaScript or CSS sources of the application. I will indicate to which file the code belongs to with a comment for each code snippet.


Adding a module and a controller

Next, we initialize the angularjs module in the app.js file and create a main controller for the application. The controller should create random data (that represent some simple logs) in a fixed interval. Let’s generate some random number of visitors every second and store all data points on the scope as follows:

/* src/app.js */
// Application Module 
angular.module('myApp', [])

// Main application controller
.controller('MainCtrl', ['$scope', '$interval',
  function ($scope, $interval) {

    var time = new Date('2014-01-01 00:00:00 +0100');

    // Random data point generator
    var randPoint = function() {
      var rand = Math.random;
      return { time: time.toString(), visitors: rand()*100 };

    // We store a list of logs
    $scope.logs = [ randPoint() ];

    $interval(function() {
      time.setSeconds(time.getSeconds() + 1);
    }, 1000);

In the preceding example, we define an array of logs on the scope that we initialize with a random point. Every second, we will push a new random point to the logs. The points contain a number of visitors and a timestamp—starting with the date 2014-01-01 00:00:00 (timezone GMT+01) and counting up a second on each iteration. I want to keep it simple for now; therefore, we will use just a very basic example of random access log entries. Later in this tutorial, we will use the library to push a list of real logs from our server applications directly to the angularjs application in real time.


Consider to use the cleaner controller as syntax for larger angularjs applications because it makes the scopes in HTML templates explicit! However, for compatibility reasons, I will use the standard controller and $scope notation.

Integrating D3.js into angularjs

We bootstrapped a simple angularjs application in the previous section. Now, the goal is to integrate a D3.js component seamlessly into an angularjs application—in an Angular way. This means that we have to design the angularjs application and the visualization component such that the modules are fully encapsulated and reusable. In order to do so, we will use a separation on different levels:

  • Code of different components goes into different files
  • Code of the visualization library goes into a separate module
  • Inside a module, we divide logics into controllers, services, and directives

Using this clear separation allows you to keep files and modules organized and clean. If at anytime we want to replace the D3.js backend with a canvas pixel graphic, we can just implement it without interfering with the main application. This means that we want to use a new module of the visualization component and dependency injection.

These modules enable us to have full control of the separate visualization component without touching the main application and they will make the component maintainable, reusable, and testable.

Organizing the directory

First, we add the new files for the visualization component to the project:

  • src/: This is the default directory to store all the file components for the project
  • src/chart.js: This is the JS source of the chart component
  • src/chart.css: This is the CSS layout for the chart component
  • test/test/config/: This directory contains all test configurations
  • test/spec/test/spec/chart.spec.js: This file contains the unit tests of the chart component
  • test/e2e/chart.e2e.js: This file contains the integration tests of the chart component


If you develop large angularjs applications, this is probably not the folder structure that you are aiming for. Especially in bigger applications, you will most likely want to have components in separate folders and directives and services in separate files.

Then, we will encapsulate the visualization from the main application and create the new myChart module for it. This will make it possible to inject the visualization component or parts of it—for example just the chart directive—to the main application.

IN NEXT chapter you will learn about wrapping d3js