2014-12-19 6 views
5

Ich bin mit diesem Fehler fest, habe eine benutzerdefinierte Direktive zum Erstellen eines Balkendiagramms, das aus einer JSON-Datei generiert wird.TypeError: Kann die Eigenschaft 'childNodes' von undefiniertem Winkel nicht lesen

Hier ist mein Code, ich eine index.html-Seite haben, wo ein Blick nach innen auf die Navigation basiert geroutet hier ist die

INDEX.HTML

<head> 
    <title>DiginRt</title> 

    <body ng-app="DiginRt" class=" pace-done" cz-shortcut-listen="true"> 
     <div id="header-topbar-option-demo" class="page-header-topbar"> 
      <div id="page-wrapper"> 
       <div id="title-breadcrumb-option-demo" class="page-title-breadcrumb"> 
        <div class="page-header pull-left"> 
         <div class="page-title"> Dashboard</div> 
        </div> 
        <div class="clearfix"> </div> 
       </div> 
       <div class="page-content" ui-view> // Here i load the view for the dashboards </div> 
      </div> 
     </div> 
     </div> 
     <script src="script/jquery-1.10.2.min.js"></script> 
     <script src="script/jquery-ui.js"></script> 
     <script type="text/javascript"> 
      var $j = jQuery.noConflict(); 
     </script> 
     <script type="text/javascript" src="script/prototype.js"></script> 
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js"></script> 
     <script type="text/javascript" src="script/d3.js"></script> 
     <script src="script/angular-ui-router.min.js"></script> 
     <script type="text/javascript" src="script/jquery.jsPlumb-1.4.1-all-min.js"></script> 
     <script type="text/javascript" src="script/plumb.js"></script> 
     <script type="text/javascript" src="script/app.js"></script> 
    </body> 

</html> 

Dashboard.HTML:

<body ng-controller="DashboardCtrl"> 
    <div id="main_wrapper"> 
     <div id="toolboxControl"> 
      <div id="containerChart"> 
       <ul> 
        <li> <a ng-click="addWidget()" href="#controlflow">Charts</a> 
         <div id="controlflow" class="containerChart"> 
          <input ng-model="searchCommonValue" class="form-control" type="search" placeholder="Search controls..."> 
          <div plumb-menu-item ng-repeat="widget in dashboard.widgets | filter : searchCommonValue" class="menu-item" data-identifier="{{widget.id}}" data-title="{{widget.name}}" draggable> <img class="toolheader" src="{{widget.Icon}}"> 
           <div class="toolcontent">{{widget.name}}</div> 
          </div> 
         </div> 
        </li> 
       </ul> 
      </div> 
     </div> 
     <div ng-controller="CustomWidgetCtrl" id="container" class="drop-container" ng-click="addEvent($event)" droppable> 
      <div plumb-item class="item" style="margin: 20px; top: 60px; left: 200px; height: 300px; width: 500px;" ng-repeat="widget in dashboard.widgets" ng-style="{ 'left':widget.sizeX, 'top':widget.sizeY }" data-identifier="{{widget.id}}"> 
       <div class="box"> 
        <div class="box-header"> 
         <h3>{{ widget.name }}</h3> 
         <div class="box-header-btns pull-right"> <a title="settings" ng-click="openSettings(widget)"><i class="glyphicon glyphicon-cog"></i></a> <a title="Remove widget" ng-click="remove(widget)"><i class="glyphicon glyphicon-trash"></i></a> </div> 
        </div> 
        <div class="box-content"> 
         <!-- <bars data="40,4,55,15,16,33,52,20"></bars> --> 
         <bargraph id="d3bar" datajson="sample.json" xaxis-name="Year" xaxis-pos="905" yaxis-name="Frequency" yaxis-pos="12" d3-format=".0%"> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
    </div> 
    </div> 
    </span> 
    </div> 

App.Js:

var routerApp = angular.module('DiginRt', ['ui.bootstrap', 'ui.router']); 
routerApp.config(function($stateProvider, $urlRouterProvider) { 
    $urlRouterProvider.otherwise('/dashboard'); 
    $stateProvider.state('dashboard', { 
     url: '/dashboard', 
     templateUrl: 'Charts.html', 
     controller: 'DashboardCtrl' 
    }) 
}); 
routerApp.controller('DashboardCtrl', ['$scope', '$timeout', 
    function($scope, $timeout) { 
     $scope.gridsterOptions = { 
      margins: [20, 20], 
      columns: 4, 
      draggable: { 
       handle: 'h3' 
      } 
     }; 
     $scope.dashboards = { 
      '1': { 
       id: '1', 
       icon: 'images/icons/chart_line.png', 
       name: 'Home', 
       widgets: [{ 
        col: 0, 
        row: 0, 
        sizeY: 1, 
        sizeX: 1, 
        icon: 'images/icons/chart_line.png', 
        name: "Stocks per store" 
       }] 
      } 
     }; 
    } 
]) 
routerApp.controller('CustomWidgetCtrl', ['$scope', '$modal', 
    function($scope, $modal) { 
     $scope.remove = function(widget) { 
      $scope.dashboard.widgets.splice($scope.dashboard.widgets.indexOf(widget), 1); 
     }; 
     $scope.openSettings = function(widget) { 
      $modal.open({ 
       scope: $scope, 
       templateUrl: 'chart_settings.html', 
       controller: 'chartSettingsCtrl', 
       resolve: { 
        widget: function() { 
         return widget; 
        } 
       } 
      }); 
     }; 
    } 
]) 
var BarGraph = Class.create({ 
    initialize: function(datajson, xaxisName, xaxisPos, yaxisName, yaxisPos, d3Format) { 
     this.datajson = datajson; 
     this.xaxisName = xaxisName; 
     this.xaxisPos = xaxisPos; 
     this.yaxisName = yaxisName; 
     this.yaxisPos = yaxisPos; 
     this.d3Format = d3Format; 
    }, 
    workOnElement: function(element) { 
     this.element = element; 
    }, 
    generateGraph: function() { 
     //d3 specific coding 
     var margin = { 
       top: 20, 
       right: 20, 
       bottom: 30, 
       left: 40 
      }, 
      width = 960 - margin.left - margin.right, 
      height = 500 - margin.top - margin.bottom; 
     var formatPercent = d3.format(this.d3Format); 
     var x = d3.scale.ordinal().rangeRoundBands([0, width], .1); 
     var y = d3.scale.linear().range([height, 0]); 
     var xAxis = d3.svg.axis().scale(x).orient("bottom"); 
     var yAxis = d3.svg.axis().scale(y).orient("left").tickFormat(formatPercent); 
     var svg = d3.select(this.element).append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
     d3.tsv(this.datajson, function(error, data) { 
      if (error) return console.warn(error); 
      //console.log(this.xaxisName); 
      x.domain(data.map(function(d) { 
       return d.letter; 
      })); 
      y.domain([0, d3.max(data, function(d) { 
       return +d.frequency; 
      })]); 
      svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).append("text").attr("x", this.xaxisPos).attr("dx", ".71em").style("text-anchor", "end").text(this.xaxisName); 
      svg.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(-90)").attr("y", this.yaxisPos).attr("dy", ".71em").style("text-anchor", "end").text(this.yaxisName); 
      svg.selectAll(".bar").data(data).enter().append("rect").attr("class", "bar").attr("x", function(d) { 
       return x(d.letter); 
      }).attr("width", x.rangeBand()).attr("y", function(d) { 
       return y(d.frequency); 
      }).attr("height", function(d) { 
       return height - y(d.frequency); 
      }); 
     }.bind(this)); 
    } 
}); 
routerApp.directive('bargraph', function() { // Angular Directive 
    return { 
     restrict: 'EA', // Directive Scope is Element 
     replace: true, // replace original markup with template 
     transclude: false, // not to copy original HTML DOM 
     compile: function(elem, attrs) { // the compilation of DOM is done here. 
      // It is responsible for produce HTML DOM or it returns a combined link function 
      // Further Docuumentation on this - http://docs.angularjs.org/guide/directive 
      console.log(attrs.id); 
      console.log(attrs.datajson); 
      var html = "<div id='" + attrs.id + "' ></div>"; // the HTML to be produced 
      var newElem = $(html); 
      elem.replaceWith(newElem); // Replacement of the element. 
      var ourGraph = new BarGraph(attrs.datajson, attrs.xaxisName, attrs.xaxisPos, attrs.yaxisName, attrs.yaxisPos, attrs.d3Format); 
      ourGraph.workOnElement('#' + attrs.id); 
      // Work on particular element 
      ourGraph.generateGraph(); // here is the error! 
     } 
    } 
}); 

Antwort

6

gab es einige Winkel Code von Ihrem HTML und Script fehlt. Ein paar Dinge, die ich tat:

  • <html ng-app="routerApp"> auf der HTML-Seite
  • hinzugefügt

ich Datei var routerApp = angular.module('routerApp', []); den js hat einen PLUNK mit den Ergebnissen erstellt. Der einzige andere Unterschied zu Ihrem Code besteht darin, dass es für mich einfacher war, eine TSV-Beispieldatei als die JSON-Datei zu finden, auf die Sie in Ihrem Code verwiesen haben. Also habe ich von d3.json zu d3.tsv gewechselt, aber das ist hier wirklich nicht wichtig. Ich hoffe das hilft.

+0

Ich habe bereits die ng-App hinzugefügt, mein HTML-Code ist etwas anders. Ist es deswegen? – Sajeetharan

+0

ich bin seit sehr langer Zeit mit dieser – Sajeetharan

+0

Dies waren die einzigen 2 Codeänderungen, die ich (neben dem TSV) gemacht habe. Die einzige andere Sache, die ich tat, war, die notwendigen Bibliotheken im HTML anzugeben (Prototyp, D3 und eckig). Wenn Sie die eckige Bibliothek nicht verwenden, kann dies dazu führen, dass der Winkel nicht definiert wird. Überprüfen Sie das Plunk, das ich erstellt habe. – FernOfTheAndes

3

Es gibt irrelevante, nicht geschlossene und fehlerhafte Tags im gesamten HTML-Code, die Angular mit dem Parsen zu kämpfen scheint. Ich würde empfehlen, Ihren HTML-Code auf Gültigkeit zu überprüfen, da dies das Problem beheben wird, das Sie haben.

Wenn Sie Beispiele möchten, kann ich einige liefern, lassen Sie mich einfach in den Kommentaren wissen.

1

Ich hatte diese Probleme zuvor und es hatte mit einer Direktive zu tun, bei der die Option replace auf true gesetzt ist. Es könnte also eine Idee sein, zu überprüfen, ob Sie in Ihrem speziellen Fall wirklich die Option zum Ersetzen benötigen.

Verwandte Themen