[Chartjs]-How to clear the data for a angular-chart

2👍

I’ve had the same problem and found two ways to solve it

The first way is getting the context for the canvas and using clearRect function:

var canvas = document.getElementById('line');
if (canvas){
    var ctx = canvas.getContext('2d');
    ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);
}

This way you can clear the canvas, no matter if your data is still set. Doing it like this I had a problem with hover event, when I moved my mouse over it, the canvas was seted with the data again. So I looked for another way to do it.

The second way you can try is using ChartJsProvider:

1.- In the createChart function in your angular-chart.js file, add this line just after the variable chart initialization:

var chart = new ChartJs.Chart(ctx)[type](data, options);
ChartJs.createdChart = chart; // add this line so you can access chart variable from ChartJsProvider

2.- Inject ChartJs to the Controller

angular.module('myModule')
    .controller('MyController', MyController);

MyController.$inject = ['ChartJs'];

function MyController(ChartJs){
    // your controller code
}

3.- In your controller use the createdChart destroy function to clear/destroy the chart

var canvas = document.getElementById('line');
if (canvas) { 
    ChartJs.createdChart.destroy();
}

This way is working for me correctly in chrome, opera, and safari.

Edited:

I found a new way to do this better than modifying the library (I know it’s not a good practice so that’s why I tried to find this new way)

You still need to inject ChartJs to the Controller

angular.module('myModule')
    .controller('MyController', MyController);

MyController.$inject = ['ChartJs'];

function MyController(ChartJs){
    // your controller code
}

I created a function called clearChart with a parameter elementId so if you have more than one chart in your page you can access directly to the one you want to clear/remove:

function clearChart(elementId) {
    if (document.getElementById(elementId)) {
        var charts = ChartJs.Chart.instances; // Get all chart instances
        for (var key in charts){ // loop looking for the chart you want to remove
            if (!charts.hasOwnProperty(key)){
                continue;
            }
            var chartAux = ChartJs.Chart.instances[key]; 
            if (chartAux.chart.ctx.canvas.id === elementId){ 
                // Remove chart-legend before destroying the chart
                var parent = chartAux.chart.ctx.canvas.parentElement;
                var legend = chartAux.chart.ctx.canvas.nextElementSibling;
                parent.removeChild(legend);
                // Compare id with elementId passed by and if it is the one            
                // you want to remove just call the destroy function
                ChartJs.Chart.instances[key].destroy(); 
            }
        }
    }
}

This new second way works perfectly for me.

I hope it helps and sorry about my english

1👍

I think I’ve found another method that’s working better for me and it is done with less code.

Chart.js is emitting an onCreate event in it you’re getting the created chart object.

Then I’m storing the object in a variable so I can use it in my click handler.
(If you’re having multiple charts on your page you probably get multiple onCreate events and you could store each chart object in an array or object for later usage.)

In the click handler you can call lineChart.destroy() and that will destroy your chart object. Don’t forget to clear your data too. The chart will be re-created by angular-chartjs if you need it again.

The benefit of this is that everything is resetted. I had the issue before that the x-axis scale wasn’t cleared with other methods.

Please have a look at the demo below or in this jsfiddle.

One issue that I need to check in my demo is that the chart is completely regenerate at every new data. Maybe this is normal behaviour but I’m not sure.

angular.module('chartDemo', ['chart.js'])
	.config(['ChartJsProvider', function (ChartJsProvider) {
    // Configure all charts
    ChartJsProvider.setOptions({
      animation: false,
      colours: ['#FF5252', '#FF8A80'],
      //responsive: false
    });
    // Configure all line charts
    ChartJsProvider.setOptions('Line', {
      //datasetFill: false
      //legendTemplate: /*'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><button ng-click="mainCtrl.toggle()">test</button><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'*/
    });
  }])
	.controller('MainController', MainController);

function MainController($scope, $timeout) {
  var vm = this;
  var defaultData = [
      [65, 59, 80, 81, 56, 55, 40]
  	],
    lineChart; //created in onCreate
  
  angular.extend(vm, {
  	series: ['Series A'], 
  	data: defaultData,
    labels: Object.keys(defaultData[0]),
  	onClick: function (points, evt) {
    	console.log(points, evt);
  	},
    enable: true,
    onChange: function() {
      if ( vm.enable )
      	startTimer();
    },
    clear: function() {
      console.log('clear chart');
      vm.data = [[]];
      lineChart.destroy();
    },
    startTimer: startTimer,
    toggle: function() {
      consoel.log('Test')
    }
  });
	
  $scope.toggle = function() {
    // not working yet
    console.log('test');
  };
  
  $scope.$on('toggle', function(e, data) {
    console.log(data);
  });
  
  //console.log(Object.keys(defaultData[0]));
  
  function startTimer() {
    if (	vm.enable	) {
    	$timeout(function() {
          vm.data[0].push(Math.random()*50);
          startTimer();
          vm.labels = Object.keys(vm.data[0])
      	}, 500);
    }
  }
  
  if (vm.enable) startTimer();
  
  $scope.$on('create', function (event, chart) {
  	console.log(chart);
    lineChart = chart;
	});
}

MainController.$inject = ['$scope', '$timeout'];
<link href="https://cdn.rawgit.com/jtblin/angular-chart.js/master/dist/angular-chart.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/alanszp/Chart.js/master/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdn.rawgit.com/jtblin/angular-chart.js/master/dist/angular-chart.min.js"></script>


<div ng-app="chartDemo" ng-controller="MainController as mainCtrl">
  enable<input type="checkbox" ng-model="mainCtrl.enable" ng-change="mainCtrl.startTimer();"/><button ng-click="mainCtrl.clear()">Clear</button>
    <canvas id="line" 
      class="chart chart-line" chart-data="mainCtrl.data" 
      chart-labels="mainCtrl.labels" 
      chart-legend="true" chart-series="mainCtrl.series" chart-legend="true"
      chart-click="mainCtrl.onClick"></canvas> 
  <pre>{{mainCtrl.debug}}</pre>
</div>

Leave a comment