2016-09-18 4 views
2

Я ознакомился с несколькими пошаговыми инструкциями о том, как реализовать диаграммы d3 в угловом приложении. В принципе, я пытаюсь реализовать следующее d3 chart в моей настраиваемой угловой директиве («workHistory»). Для целей данного вопроса, я следую простой гистограмму example, где я его настроить, как так:Как настроить диаграмму d3 внутри пользовательской директивы в Angular?

index.html

<!doctype html> 
    <html lang="en" ng-app="webApp"> 
    <head> 
     <meta charset="utf-8"> 

     <title>My Portfolio</title> 

     <!--Stylesheets --> 
     <link rel="stylesheet" href="styles/main.css"/> 
     <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"/> 
     <!--Libraries --> 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script> 
     <script src="bower_components/jquery/dist/jquery.min.js"></script> 
     <script src="bower_components/angular-route/angular-route.min.js"></script> 
     <script src="bower_components/angular-loader/angular-loader.min.js"></script> 
     <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script> 
     <script src="bower_components/d3/d3.min.js"></script> 
     <!--Module --> 
     <script src="scripts/modules/module.js"></script> 
     <script src="scripts/modules/d3.module.js"></script> 
     <!--Controllers --> 
     <script src="scripts/controllers/mainHeroController.js"></script> 
     <script src="scripts/controllers/workHistoryController.js"></script> 
     <!--Directives--> 
     <script src="scripts/directives/mainHero.directive.js"></script> 
     <script src="scripts/directives/mainNavbar.directive.js"></script> 
     <script src="scripts/directives/workHistory.directive.js"></script> 
    </head> 

    <!--Main Landing Page-->  
    <body ng-app="webApp"> 
     <div id="container1"> 
      <work-history chart-data="myData"></work-history> 
     </div> 
     <div id="container2"> 
      Container 2 
     </div> 
    </body> 
    </html> 

workHistory.directive.js

(function() 
{ 
    'use strict'; 

    angular 
     .module('webApp') 
     .directive('workHistory', workHistory); 

    function workHistory() 
    { 
     var directive = 
      { 
       restrict: 'EA', 
       controller: 'WorkHistoryController', 
       //controllerAs: 'workhistory', 
       scope: {data: '=chartData'}, 
       template: "<svg width='850' height='200'></svg>", 
       link: workHistoryLink, 
      }; 

     return directive; 
    } 

    function workHistoryLink(scope, element/*, attrs, ctrl, tfn*/) 
    { 

     var chart = d3.select(element[0]); 
     chart.append("div").attr("class", "chart") 
     .selectAll('div') 
     .data(scope.data).enter().append("div") 
     .transition().ease("elastic") 
     .style("width", function(d) { return d + "%"; }) 
     .text(function(d) { return d + "%"; }); 
     } 
})(); 

main.css

.axis path, 
.axis line{ 
    fill: none; 
    stroke:black; 
    shape-rendering:crispEdge; 
} 

.axis text{ 
    font-family: sans-serif; 
    font-size: 10px; 
} 

h1{ 
    font-family: sans-serif; 
    font-weight: bold; 
    font-size: 16px; 
} 
.tick 
{ 
    stroke-dasharray: 1, 2; 
} 

Проблема: С помощью этого кода ничего не отображается. Я получаю следующую ошибку:

angular.js:13920TypeError: chart.append(...).attr(...).selectAll(...).data(...).enter is not a function

Может кто-нибудь помочь мне понять, как правильно настроить это? (Bonus, если кто-то может объяснить, как я могу получить складное дерево d3 графика, выполненный в пользовательской директиву

Благодаря

+0

должен проработавший не могли бы вы предоставить рабочую скрипку .. – Cyril

+0

создал plunker (HTTP: // plnkr.co/edit/kexnO1igGSkcMIhvX9Ao?p=preview) со сворачиваемым деревом в вашей директиве, возможно, это может помочь – Andriy

ответ

5

Есть несколько ошибок в коде:..

  1. вы шаблон Неправильно: вы создаете svg, но внутри вы вставляете стандартные html-теги. Он не может работать. В этом случае вы должны создать шаблон с тегом div в качестве корневого узла.
  2. , если вы хотите предоставить начальную как вы делаете, вы должны сделать это как корневой узел, установив свойство replace своей директивы t o true.
  3. Затем, если вы хотите, чтобы добавленные divs на d3 были видны, вы должны сделать их видимыми, установив фон или границу с помощью «.style ('background', 'blue')", например
  4. Я не понять, что вы можете сделать в контроллере «WorkHistoryController». По моему мнению, в такой директиве вам следует избегать предоставления связи и контроллера.
  5. Наконец, если вы хотите, чтобы все думало всегда работать, вы должны поместить код D3 в $ watch, чтобы вы были уверены, что генерация запускается после установки данных в области.
  6. В качестве дополнения, теперь вы всегда наблюдаете массив, он должен обрабатывать удаление элементов, которые не нужны, если массив меньше, чем раньше: «.exit().удалить();»

Этой директиву должна выглядеть следующим образом:

angular 
    .module('app', []) 
    .directive('workHistory', workHistory); 

function workHistory() 
{ 
    var directive = 
     { 
      restrict: 'EA', 
      scope: {data: '=chartData'}, 
      replace:true, 
      template: "<div style='width:100%'></div>", 
      link: workHistoryLink, 
     }; 

    return directive; 
} 

function workHistoryLink(scope, element) 
{ 
    scope.$watch('data', function(){ 
    var chart = d3.select(element[0]); 
    chart.append("div").attr("class", "chart") 
     .selectAll('div') 
     .data(scope.data).enter().append("div") 
     .style('background', 'blue') 
     .transition().ease("elastic") 
     .style("width", function(d) { return d + "%"; }) 
     .text(function(d) { return d + "%"; }) 
     .exit().remove(); 
    }, true); 
} 

здесь является jsbin, чтобы сделать мою точку: http://jsbin.com/vegesigevi/edit?html,js,output

Надеется, что это помогает

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