Combining D3 and D3plus in an Angular web application: A complete guide

I'm currently integrating d3Plus sample code () into my angular-based webapp.

This is the initial setup code:

angular.module('UI', ['UI.controllers', 'UI.directives']);
angular.module('d3Plus', ['d3']);
angular.module('d3', []);
angular.module('UI.controllers', []);
angular.module('UI.directives', ['d3Plus']);

angular.module('d3').factory('d3',[function(){ 
    var d3;    
    d3=minimized/code/of/d3.js
    return d3;
}]) ;

angular.module('d3Plus').factory('d3Plus',['d3', function(){ 
    var d3Plus;    
    d3Plus=minimized/code/of/d3Plus.js
    return d3Plus;
}]) ;


angular.module('UI.directives').directive('d3Bars', ['d3', function(d3) {....}])
angular.module('UI.directives').directive('d3plusMap', ['d3Plus', function(d3) {....}])

The Issue: I encounter a ReferenceError when trying to use a custom tag (created with d3Plus). The error message in the console reads:

ReferenceError: d3 is not defined
on line 11496 of angular.js.

Any suggestions?

Update 1: The d3 based tag - d3-bars functions correctly.

Answer №1

Step-by-step instructions on integrating d3.js as a dependency in an angular.js application can be found in this ng-newsletter article:

angular.module('d3', [])
 .factory('d3Service', ['$document', '$q', '$rootScope',
   function($document, $q, $rootScope) {
    var d = $q.defer();
    function onScriptLoad() {
     // Load client in the browser
     $rootScope.$apply(function() { d.resolve(window.d3); });
    }
    // Create a script tag with d3 as the source
    // and call our onScriptLoad callback when it
    // has been loaded
    var scriptTag = $document[0].createElement('script');
    scriptTag.type = 'text/javascript'; 
    scriptTag.async = true;
    scriptTag.src = 'http://d3js.org/d3.v3.min.js';
    scriptTag.onreadystatechange = function () {
      if (this.readyState == 'complete') onScriptLoad();
    }
    scriptTag.onload = onScriptLoad;

    var s = $document[0].getElementsByTagName('body')[0];
    s.appendChild(scriptTag);

    return {
      d3: function() { return d.promise; }
    };
  }]);

A similar approach can be used for any other JS library. For d3plus, the module/factory setup looks like this:

angular.module('d3plus', [])
  .factory('d3plusService', ['$document', '$window', '$q', '$rootScope',
  function ($document, $window, $q, $rootScope) {
  var d = $q.defer(),
    d3plusService = {
      d3plus: function () {
        return d.promise;
      }
    };

  function onScriptLoad() {
    // Load client in the browser
    $rootScope.$apply(function () {
      d.resolve($window.d3plus);
    });
  }
  var scriptTag = $document[0].createElement('script');
  scriptTag.type = 'text/javascript';
  scriptTag.async = true;
  scriptTag.src = 'path/to/d3plus.min.js';
  scriptTag.onreadystatechange = function () {
    if (this.readyState == 'complete') onScriptLoad();
  };
  scriptTag.onload = onScriptLoad;

  var s = $document[0].getElementsByTagName('body')[0];
  s.appendChild(scriptTag);

  return d3plusService;
}]);

Remember to incorporate the promise functions in your d3/d3plus directives as shown below:

app.directive('myD3Directive', ['d3Service', 'd3plusService',
function(d3service, d3plusService) {
    return {
      restrict: 'E',
      link: function(scope, elem, attrs) {

         d3service.d3().then(function (d3) {

           d3plusService.d3plus().then(function (d3plus) {

           // Your code goes here

           }
         }
      }
   }
}
]);

Answer №2

It is not necessary to pass in the d3 as a dependency. Instead, you can directly reference it from your js source include (e.g.

<script src="http://d3js.org/d3.v2.js"></script>
)

For a demonstration, check out this functional example on github.

More examples with source code are available here: D3.js Visualization Library with AngularJS, Angular.js Directives for nvd3.js, d3.js charts.

If you prefer watching youtube videos, you can view AngularJS & D3: Directives for Visualizations

-harold

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing a command efficiently in Javascript with the get method

The command that needs to be sent to the embedded device is in the form of a GET method. However, the value continuouspantiltmove: String(pt) is not being properly transmitted to the CGI script through Google Chrome, causing it to fail. Since I do not hav ...

Instructions for manipulating and displaying a source array from a child component using Vue

I have a parent component with an array that I display in the template. My goal is to click on a link that uses vue-router with a dynamic id attribute, and then open a new component displaying only the element of the array that corresponds to that id. Howe ...

angular state transitions automatically following successful ng-file-upload with no apparent cause for error

After successfully uploading a file to the server, my AngularJS application redirects me back to the initial state without any errors. The success callback is triggered and there are no errors reported. Using ng-fileupload version 3.2.5. This is the fun ...

Guide on sending `form data` including id's using the save method in Angular's resource feature

Can someone help me with saving data using the Angular save method ('post')? How can I send the necessary ID with form data? Currently, I am encountering an error message stating 'Invalid HTTP status code 405`. Here is a snippet from my co ...

invoking a function in javascript from react

Currently, I am grappling with the task of invoking a JavaScript function from within React while adapting a "React" based "Menu" onto some existing jQuery functions. Below you can find my code for the menu: class Menus extends React.Component{ co ...

Encountering issues while running the AngularJS Seed E2E tests on multiple devices

After cloning the AngularJS Seed application and following all the instructions, I launched the application and ran the E2E tests on two different machines. However, both machines are encountering the same error: > [email protected] protractor C: ...

The execution of setRequestHeader in ng-file-upload has encountered an error

Having encountered an issue with ng-file-upload, I have implemented a code similar to the GitHub example. However, upon attempting to upload a file, I am confronted with the following error: Error: Failed to execute 'setRequestHeader' on 'X ...

"JSON.parse encounters issues when attempting to parse correctly formatted JSON data

During the development of my application, I encountered an issue when trying to send a large JSON file consisting of about 7 million characters (6.6 MB of data). Although the JSON is correctly received as a string, I faced an error when attempting to parse ...

Remove a row from a table using the hyperlink reference

I am facing an issue where I want to delete a row in the table along with the corresponding database entry by clicking on a href link, but it doesn't work as expected: <table cellpadding="0" cellspacing="0" border="0" class="display" id="example"& ...

Extract data from an array in MongoDB by organizing it into sections based on dates

As a beginner in the world of MongoDB, I'm trying to figure out how to extract data from an array in separate sections. { "name":"User name", "messages":[ { "message":"Message 1", ...

Modify the appearance of a specific <td> element using JavaScript to change its color

I am working on creating a quiz using HTML, displayed in a table format. Upon verification, I want to highlight the correct choice (which is represented by a <td> tag) in green, and the incorrect choice in red using the background property. Is there ...

Why isn't the npm table populating the command line interface table?

I attempted to create a command line table using npm table, but encountered issues with it. Here is my code and an explanation. const {table} = require('table'); let data; let output; data = [['id','product','name&apos ...

Leveraging Angular recommendations within HTML connected to a controller in PhpStorm

I am currently using phpStorm and I'm wondering if it is possible to bind an HTML template to a controller in order to receive proper suggestions. Within my router, I have set up a template HTML and controller: $stateProvider .state('ap ...

Changing the absolute layout to utilize floats

I am seeking guidance on a project I am currently working on and would greatly appreciate any help. Main Goal: The objective is to create a drag and drop CMS that allows users to draw elements on a grid and rearrange them as needed. The system will recor ...

Submit image on Laravel platform from canvas

My webpage has a canvas image that is generated using JavaScript, and I am attempting to upload it to my server using Laravel. Below is the code in my controller: public function handleImageUpload(Request $request) { $imageName = time().' ...

I am unable to utilize sweetalert for creating a confirmation message in ASP with a linkbutton

I'm currently working on a school project and facing issues with implementing the delete confirmation using sweetalert. Below is the script I am struggling with: <script type="text/javascript> function myDelete { ...

"Although disabled, input elements can still be focused on in Firefox browser

Illustrative example let userInput = document.createElement("input"); userInput.id = "user-input"; userInput.type = "number"; userInput.className = "user-number-input"; userInput.disabled = true; document.body.appendChild(userInput); .number-inp ...

Retrieve an array containing various values of a single element with the help of Protractor

Currently, I am in the process of testing an application that showcases graphs using rickshaw and d3. The tests are being run with protractor and jasmine. It's worth noting that this question is not specific to this particular scenario but rather more ...

Discover the ins and outs of crafting a tooltip in a spreadsheet with Java-Jsp

Seeking assistance on how to incorporate a tooltip or comment feature in a spreadsheet similar to the one found in Google Spreadsheets (right-click and insert comment). For example: ![tooltip] https://sites.google.com/a/wongsk.twbbs.org/wongsk/image2/pop ...

Limit the vertical movement in Vue drag and drop operations

Currently, I am working on a project that involves implementing drag-and-drop functionality using vue-draggable. You can find more information about it here: https://github.com/SortableJS/Vue.Draggable. I am facing an issue where the height of the element ...