Angularjs - Charts.js: Same chart element doesn't redraw on other view
Asked Answered
D

2

14

I am new to angularjs, trying to create my first directive. I am creating a directive to load Charts.js2.0(beta) into my application.

I have 2 views managed by angular-route, both html view has ng-included a html page that contains only charts-element.

The problem is the first page properly draws the chart, when i go to other view the charts div is loaded but charts is not re-drawn. And now if i go back to first view its blank.

Link to Plunker

What i am doing wrong? Is there any issue with my directive?

Thanks in advance.

Divebomb answered 14/11, 2015 at 14:7 Comment(2)
Where are you handling the create event emitted in the watch?Salable
Sorry, create event is not used, I was doing trial and error to resolve this but was unsuccessful. I forgot to remove it from PlunkerDivebomb
L
6

There appears to be an issue with the Charts library modifying the existing object on the root scope, and thereby ignoring it forever afterward. I can't really trace down what is doing it, but here's a fix for you: http://plnkr.co/edit/jDQFV62FSeXAQJ6o7jE8

Here is what you had

  scope.$watch('config', function(newVal) {
    if(angular.isDefined(newVal)) {
      if(charts) {
        charts.destroy();
      }
      var ctx = element[0].getContext("2d");
      charts = new Chart(ctx, scope.config);
      //scope.$emit('create', charts);
    }
  });

Above, you can see that you're passing scope.config directly into the charts method. That appears to be modifying the data somehow, and since that's passed by reference, you're actually modifying $rootScope.sales.charts. If you copy that object and use it locally like below, you don't have that problem.

Here's how I fixed it.

  scope.$watch('config', function(newVal) {
    var config = angular.copy(scope.config);
    if(angular.isDefined(newVal)) {
      if(charts) {
        charts.destroy();
      }
      var ctx = element[0].getContext("2d");
      charts = new Chart(ctx, config);
      //scope.$emit('create', charts);
    }
  });

You can see that instead of passing that object directly in, we use angular to make a copy (angular.copy()), and that's the object we pass in.

Lyophilize answered 23/11, 2015 at 18:14 Comment(1)
can you please see my question #37256987Thierry
L
2

I think it has relation with the id of the canvas where you are drawing. I've had this problem too amd it was because i was using the same id for the canvas of two graphs in different views. Be sure that those ids are different and that the javasrcipt of each graph is in the controller of each view or in each view itself.

Taking a look at your pluker I see that you are using the same html for the graph and I guess that when angular moves from one of your views to the other thinks that the graph is already drawn. Differentiating two graphs will solve the problem. I don't know of there is any other approach that allows using the same html for the canvas of the graph.

Hope it helps you solve it

Lippe answered 14/11, 2015 at 16:15 Comment(1)
Instead of ng-include, i directly added directive and assigned them different ids- Still getting same issue.Divebomb

© 2022 - 2024 — McMap. All rights reserved.