Last month,  Mark Lacomber wrote a post describing how to use D3.js visualization library at Logentries. I am following up to show how to combine D3 with the AngularJS framework. As we all know, Angular and D3 frameworks are very popular, and once they work together they can be very powerful and helpful when creating dashboards. But, they can also be challenging and confusing especially when new to these frameworks. The right way to incorporate D3 with Angular is to use custom directives. Directives in Angular are essentially functions that are executed on a DOM element. Let’s go through a simple example together. 

  • Our first step is to create a factory which will enable us to inject the D3 module into our custom directive.

angular.module('d3', []) .factory('d3Service', [function(){ var d3; // insert d3 code here return d3; }];

  • After creating the factory, we can now inject the module into our main app.

angular.module('app', ['d3']);

  • For the purpose of this example, our directive will display a simple bar chart. We can call the directive from a HTML tag.

<divblog-bar-chartbar-height="20"bar-padding="5"></div>

  • We inject our d3 module into our custom directive.

angular.module('myApp.directives', ['d3']) .directive('blogBarChart', ['d3Service', function(d3Service) { return { restrict: 'EA', // directive code } }]);

  • In order to use the D3 library, we need to include our service. You can either copy and paste the entire D3 library or just reference a CDN.

scriptTag.src =‘http://d3js.org/d3.v3.min.js';

  • In the service, we will use the notion of a promise. We need to wait for the promise to resolve by using the “then” method of our d3Service. For simplicity, we will use a link function which registers listeners and sets up binding.

angular.module('myApp.directives', ['d3']) .directive('blogBarChart', ['d3Service', function(d3Service) { return { restrict: 'EA', scope: {}, link: function(scope, element, attrs) { d3Service.d3().then(function(d3) { // d3 is the raw d3 object }); }} }]);

  • We are now ready to write actual D3 code inside our AngularJS directive. The bar chart can also be made dynamic for the developer. We can pass attributes such as width of the bar chart to the directive and then use them with the D3 code. We will in our example set up an event listener to track changes in the size of the window.

window.onresize = function() { scope.$apply(); };

  • After doing that we can focus on the D3 code for the bar chart.

var svg = d3.select(ele[0]) .append('svg') .style('width',100%);

  •  
    • One important thing to remember before the previous statement is that if SVG already existed, it would need to be emptied. Here is how you would remove all the preexisting SVG elements.

svg.selectAll('*').remove();

This example only shows a very small subset of the D3 code that could go into our directive. As well, we only worked with hardcoded data whereas in a real world scenario we would use data from a backend service. Thanks to AngularJS, we are able to easily integrate that data into our custom D3 directive by using bi-directional binding.

All in all, combining D3 with AngularJS now looks straight forward and relatively easy.  Let us know how it goes for you!