2

Я ищу, как отображать информацию о пузыре D3.js в AngularJS. Я могу показать предупреждение с желаемой информацией, но я не могу отображать информацию на странице с помощью AngularJS, потому что у меня нет доступа к области $ scope, потому что мой граф имеет директиву ... Как передать информацию без изменения структура веб-приложения? Я не могу разместить формирование пузырьковой диаграммы вне этой директивы. Это мой HTML:Показать информацию о пузырьковой диаграмме D3.js в AngularJS

<body ng-app="d3DemoApp"> 
    <div id="graph1" ng-controller="controllerBubble"> 
     The package name should appear here : {{packageName}} 
     <bubble-chart chart-data="chartData"></bubble-chart> 
    </div> 
    </body> 

Услуга:

d3DemoApp.service('dataService', function AppCtrl($http, $q) { 
    this.getCommitData = function(param) { 
    var deferred = $q.defer(); 
    $http({ 
     method: 'GET', 
     url: param 
    }). 
    success(function(data) { 
     deferred.resolve({ 
     chartData: data, 
     error: '' 
     }); 
    }). 
    error(function(data, status) { 
     deferred.resolve({ 
     error: status 
     }); 
    }); 
    return deferred.promise; 
    }; 
}); 

Контроллер:

var d3DemoApp = angular.module('d3DemoApp', []); 

// controller business logic 
d3DemoApp.controller('controllerBubble', function AppCtrl($rootScope, $scope, dataService) { 

    $scope.choice = 'data.json'; 

    loadData($scope.choice); 

    function loadData(param) { 
    dataService.getCommitData(param).then(function(res) { 
     if (res.error) { 
     $scope.error = res.error; 
     return false; 
     } 
     $scope.chartData = res.chartData; 
    }); 
    } 

}); 


d3DemoApp.directive('bubbleChart', function() { 
    return { 
    restrict: 'EA', 
    transclude: true, 
    scope: { 
     chartData: '=' 
    }, 
    link: function(scope, elem, attrs) { 

     scope.$watch('chartData', function(newValue, oldValue) { 
     console.info('new data comes to directive'); 
     console.info(newValue); 
     if (newValue) { 
      scope.drawChart(newValue); 
     } 
     }); 

     scope.drawChart = function(rootData) { 

     var diameter = 900, 
      format = d3.format(",d"), 
      color = d3.scale.category20c(); 

     var bubble = d3.layout.pack() 
      .sort(null) 
      .size([diameter, diameter]) 
      .value(function(d) { 
      return (d.numberOfLink + 1); 
      }) 
      .padding(1.5); 

     var svg = d3.select("body").append("svg") 
      .attr("width", diameter) 
      .attr("height", diameter) 
      .attr("class", "bubble"); 

     var filt = svg.append("defs") 
      .append("filter") 
      .attr({ 
      id: "f1", 
      x: 0, 
      y: 0, 
      width: "200%", 
      height: "200%" 
      }); 
     filt.append("feOffset").attr({ 
      result: "offOut", 
      "in": "sourceAlpha", 
      dx: 10, 
      dy: 10 
     }); 
     filt.append("feGaussianBlur").attr({ 
      result: "blurOut", 
      "in": "offOut", 
      stdDeviation: 10 
     }); 
     var feMerge = filt.append("feMerge"); 
     feMerge.append("feMergeNode").attr("in", "offsetBlur") 
     feMerge.append("feMergeNode").attr("in", "SourceGraphic"); 

     var node = svg.selectAll(".node") 
      .data(bubble.nodes(classes(rootData)) 
      .filter(function(d) { 
       return !d.children; 
      })) 
      .enter().append("g") 
      .attr("class", "node") 
      .attr("transform", function(d) { 
      return "translate(" + d.x + "," + d.y + ")"; 
      }); 

     node.append("title") 
      .text(function(d) { 
      return d.className + ": " + format(d.value); 
      }); 

     node.append("circle") 
      .attr("r", function(d) { 
      return d.r; 
      }) 
      .style("fill", function(d) { 
      return "red"; 
      }); 
     node.append("text") 
      .attr("dy", ".3em") 
      .style("text-anchor", "middle") 
      .text(function(d) { 
      return d.className.substring(0, d.r/3); 
      }) 

     node.on("click", click); 
     function click(d) { 
      alert(d.packageName); 
      $scope.packageName = d.packageName; // How to access to the scope ? 
      } 

     // Returns a flattened hierarchy containing all leaf nodes under the root. 
     function classes(root) { 
      var classes = []; 

      function recurse(name, node) { 
      if (node.children) node.children.forEach(function(child) { 
       recurse(node.name, child); 
      }); 
      else classes.push({ 
       packageName: name, 
       className: node.name, 
       value: node.numberOfLink, 
       idProjet: node.projectId, 
       numberOfLink: node.numberOfLink, 
       priority: node.priority 
      }); 
      } 

      recurse(null, root); 
      return { 
      children: classes 
      }; 
     } 
     d3.select(self.frameElement).style("height", diameter + "px"); 
     } 


     if (typeof scope.chartData != "undefined") { 
     scope.drawChart(scope.chartData); 
     } 
    } 
    }; 
}); 

Это онлайн пример проблемы с Plunker: https://plnkr.co/edit/LUa7RHxjSaVe1KTzy33c?p=preview

Надежда кто-то сможет сделать работы Plunker! Благодарю.

+0

Я не совсем понял вопрос. Вам нужен promt вместо предупреждения? просто замените alert с подсказкой (https://plnkr.co/edit/Yj6XgLeSdvw7YwVKURbL?p=preview). Что вы хотите сделать с подсказкой? – echonax

+0

Здравствуйте, я хочу, чтобы информация появилась на моей веб-странице, например, в абзаце или div ... – Anonyme

+0

Нет, на моей веб-странице с этим кодом: 'Имя пакета должно появиться здесь: {{packageName}}' – Anonyme

ответ

1

Вот результат: https://plnkr.co/edit/CnoTA0kyW7hWWjI6DspS?p=preview

Вы должны создать общую службу/фабрику между контроллерами для того, чтобы сделать это. Есть много примеров.

angular.module('d3DemoApp').factory('NotifyingService', function($rootScope) { 
    return { 
     subscribe: function(scope, callback) { 
      var handler = $rootScope.$on('notifying-service-event', callback); 
      scope.$on('$destroy', handler); 
     }, 

     notify: function(msg) { 
      $rootScope.$emit('notifying-service-event', msg.packageName); 
     } 
    }; 
}); 
+0

Я уже прочитайте это, но я не понимаю в моем случае, как я должен это делать. – Anonyme

+0

Привет, спасибо, что это работает, я хотел бы добавить другую информацию, но она удалит первый: https://plnkr.co/edit/f0D34h4LqXdlkENLZrDd?p=preview. Вы можете проверить его? Благодарю. – Anonyme

+0

@ afeffifari-1957 Я не знаю, что вы изменили, но вот рабочий. Https://plnkr.co/edit/CnoTA0kyW7hWWjI6DspS?p=preview – echonax

0

Я реализовал по-другому, передавая переменную из родительской области с директивой, которая находится в режиме изолированной области видимости был хорошим и чистым решением для меня, большинство проектов с открытым исходным кодом я видел реализованы таким же образом. В этом случае вы можете даже вызывать функции внутри директивы, если это связано с рабочим процессом компонент здесь есть ссылка на проект и дайте мне знать, что вы думаете https://github.com/amgadfahmi/angular-bubbletree

Смежные вопросы