How to create a directive in Angular JS for a Morris JS graph

Andy Hadjigeorgiou picture Andy Hadjigeorgiou · Dec 2, 2013 · Viewed 8.8k times · Source

I am trying to create a graph using Morris JS by creating an Angular JS directive. My directive code is:

Reporting.directive('morrisLine', function(){
  return {
    restrict: 'EA',
    template: '<div id="call-chart">test2</div>',
    scope: {
        data: '=', //list of data object to use for graph
        xkey: '=',
        ykey: '='
    },
    link: function(scope,element,attrs){
      new Morris.Line({
          element: element,
          data: [
                { year: '2008', value: 20 },
                { year: '2009', value: 10 },
                { year: '2010', value: 5 },
                { year: '2011', value: 5 },
                { year: '2012', value: 20 }
              ],
          xkey: '{year}',
          ykey: ['value'],
      });
   }
  };
});

The Error code I am getting when I check the console on my browser is :

TypeError: Cannot call method 'match' of undefined
    at Object.t.parseDate (eval at <anonymous> (http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3:4904), <anonymous>:1:9523)
    at n.eval (eval at <anonymous> (http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3:4904), <anonymous>:1:3297)
    at n.t.Grid.r.setData (eval at <anonymous> (http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3:4904), <anonymous>:1:3888)
    at n.r (eval at <anonymous> (http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3:4904), <anonymous>:1:1680)
    at new n (eval at <anonymous> (http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js:3:4904), <anonymous>:1:11953)
    at link (http://127.0.0.1:8000/static/js/app/directives/directives.js:94:20)
    at j (http://127.0.0.1:8000/static/js/libs/angular/angular.min.js:43:157)
    at e (http://127.0.0.1:8000/static/js/libs/angular/angular.min.js:38:463)
    at e (http://127.0.0.1:8000/static/js/libs/angular/angular.min.js:38:480)
    at e (http://127.0.0.1:8000/static/js/libs/angular/angular.min.js:38:480) <div morris-line="" class="ng-isolate-scope ng-scope" style="position: relative;"> 

The part the error code is pointing at is the part that says

 element : element, 

I am new to Angular JS and directives and am hoping someone can point me in the right direction of how to deal with this problem. Thank you!

Answer

Darryldecode picture Darryldecode · Jan 1, 2014

this is how I did with morris chart. Example is barchart:

sampleApp.directive('barchart', function() {

    return {

        // required to make it work as an element
        restrict: 'E',
        template: '<div></div>',
        replace: true,
        // observe and manipulate the DOM
        link: function($scope, element, attrs) {

            var data = $scope[attrs.data],
                xkey = $scope[attrs.xkey],
                ykeys= $scope[attrs.ykeys],
                labels= $scope[attrs.labels];

            Morris.Bar({
                    element: element,
                    data: data,
                    xkey: xkey,
                    ykeys: ykeys,
                    labels: labels
                });
        }

    };

});

then you can use it with this element:

<barchart xkey="xkey" ykeys="ykeys" labels="labels" data="myModel"></barchart>

where myModel is the array of data to be pass in directive, it should have the proper format to be compatible with morris charts. take a close look on how this object is being pass in "link" function in the directive.

Here is a working and complete example: http://jsbin.com/ayUgOYuY/5/edit?html,js,output