Как внедрить D3 и D3plus вместе в веб-приложение Angular?

Я пытаюсь включить пример кода d3Plus (http://d3plus.org/examples/basic/32517cfde67270c99092/) в моем веб-приложении на основе angular.

Скелет кода:

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) {....}])

Ошибка: когда я пробую пользовательский тег (директива, созданная с помощью d3Plus), я получаю следующую ошибку в своей консоли: ReferenceError: d3 is not defined в строке angular.js: 11496

Любая помощь?

Редактировать 1: тег на основе d3 — d3-bars работает нормально.


person Mohitt    schedule 05.12.2014    source источник


Ответы (2)


Как вы можете внедрить d3.js в качестве зависимости в angular.js, описано в этот бюллетень ng:

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; }
    };
  }]);

То же самое можно применить к любой другой JS-библиотеке. Для d3plus мой рабочий модуль/фабрика выглядит так:

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;
}]);

Обязательно включите функции промисов в свои директивы d3/d3plus следующим образом:

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

           }
         }
      }
   }
}
]);
person helicon    schedule 11.09.2015

Я не думаю, что вы передаете d3 как зависимость. Вместо этого вы ссылаетесь на него непосредственно из вашего исходного кода js (т.е. <script src="http://d3js.org/d3.v2.js"></script>)

Вы можете найти рабочий пример здесь, на github.

Дополнительные примеры с исходным кодом можно найти здесь: Библиотека визуализации D3.js с AngularJS, Директивы Angular.js для диаграмм nvd3.js, d3.js.

Если вы предпочитаете видео на YouTube: AngularJS и D3: директивы для визуализации

-Гарольд

person haroldcampbell    schedule 05.12.2014