I tried using d3 into an angular project as mentioned in one of the primary examples on ng-newsletter. Which shows how to setup a D3 service within angular.
I'm wondering how including D3 as an Angular service works well with Angular yeoman and bower? Or is there a conflict as I suspect below?
It appears I needed the service to be able to inject the D3 service into my directive. Otherwise, my Angular directive could not reference the D3 object when attempting to include the d3 library via a script tag into the global space.
I'm concerned using D3 as an Angular service reduce performance in code that is gained from using some of the best practices from yeoman/grunt/bower. e.g. minified code, updating to future versions of D3 with bower.
I know what you mean. If you use bower, then D3 is initialised in the global scope. Following the method described on ng-newsletter will give you a D3 instance as a service but you'll have to manage it outside of bower.
The whole point of a service in AngularJS is that objects are initialised as they're needed. The technique I settled on is therefor a compromise. It works with the Yeoman Angular generator and bower and it puts D3 into an Angular service. However, the service is really just referencing the window.d3 object so AngularJS purists will probably think it's hacky.
First, install D3 with bower:
Your bower.json file will be updated to look like this:
Note that D3 is now in there - "d3": "~3.5.5".
When you do a "grunt serve" to view the site on http://localhost:9000, D3 will now be included in the global scope. Also when you do a "grunt build" it will be minified and uglified along with all the other javascript and copied to the /dist directory.
So far so good but it's in the global scope and not in an AngularJS service which is where it should be.
Writing a service is simple. In your app.js, add this:
Maybe that's not the absolute best way to return d3. Maybe it should be done using module.exports as suggested at the bottom of this post - http://lorenhoward.com/blog/simple-way-integrate-d3-angular/. I'm not super familiar with AngularJS so I may be missing a nuance.
Anyway, just add "D3Module" to the list of modules for your app:
The service "d3" can now be included in a directive:
Injecting D3 into a service is not a necessity, it shows how we can use DI to achieve the results. If you use jQuery in an angular project you can chose to go the same route or just add it to the list of included scripts in the index.html. Either way the same results are achieved - jQuery or $ becomes global just like D3.