如何清除角度图表的数据

时间:2015-05-20 12:08:15

标签: javascript angularjs chart.js angular-chart

我有一个很好的应用程序,它根据几个标准显示折线图。当主要标准改变时,我想清除当前的折线图。但是,我无法找到如何做到这一点。我使用的是AngulerJS v1.4.0-rc2,Chart.js v1.0.2和angular-chart v0.7.1。

加载页面时,我调用函数updateSelection()。当任何其他标准发生变化时,也会调用此函数。该功能实现为:

$scope.updateSelection = function() {
    $scope.chartLabels = maandData;
    if ($scope.isPostcodeArea()) {
        $scope.chartSeries = getPostcodeSeries();
        $scope.chartData = getPostcodeData($scope.dataArea.index, $scope.dataMetric.index);
    } else {
        $scope.chartSeries = getSelectionSeries();
        $scope.chartData = getSelectionData($scope.dataArea.index, $scope.dataMetric.index);
    }
};

这将调用适当的函数来根据主要标准初始化折线图的数据。在网页中显示数据条目会显示正确的值。

在主要条件的选择框中,我调用函数updateArea()

$scope.updateArea = function() {
    $scope.form.$setPristine();
    if ($scope.isPostcodeArea()) {
        $scope.postcodeSelection = null;
        $scope.postcodeCompare1 = null;
        $scope.postcodeCompare2 = null;
        $scope.postcodeCompare3 = null;
    } else {
        $scope.selectionData = null;
        $scope.selectionCompare1 = null;
        $scope.selectionCompare2 = null;
        $scope.selectionCompare3 = null;
    }
    $scope.selections = getSelections($scope.dataArea.index);
    $scope.selectionLabel = $scope.areas[$scope.dataArea.index].label;
    $scope.chartLabels = [];
    $scope.chartSeries = [];
    $scope.chartData = [];
};

此函数将重置输入表单和表单数据。它还将确定另一个标准(selections)的数据,这是一个适合标准的标签(selectionLabel),它应该重置图表数据。

但是,图表未更新以反映新数据。那么,有没有办法正确地重置数据?

使用以下HTML显示图表本身:

<canvas id="line" class="chart chart-line"
    data="chartData" labels="chartLabels" series="chartSeries"
    legend="true" options="{'scaleBeginAtZero': true, 'datasetFill': false}">
</canvas> 

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,并找到了解决问题的两种方法

第一种方法是获取画布的上下文并使用clearRect函数:

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

这样您就可以清除画布,无论您的数据是否仍然设置。像这样做我有悬停事件的问题,当我将鼠标移到它上面时,画布再次与数据一起设置。所以我寻找另一种方法来做到这一点。

您可以尝试的第二种方法是使用ChartJsProvider:

1.-在angular-chart.js文件的createChart函数中,在变量图表初始化之后添加此行:

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

2.-将ChartJs注入控制器

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

MyController.$inject = ['ChartJs'];

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

3.-在你的控制器中使用createdChart destroy函数清除/销毁图表

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

这种方式在chrome,opera和safari中正确地为我工作。

编辑:

我发现了一种比修改库更好的方法(我知道这不是一个好习惯,所以我试图找到这种新方法)

您仍然需要将ChartJs注入控制器

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

MyController.$inject = ['ChartJs'];

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

我使用参数elementId创建了一个名为clearChart的函数,因此如果页面中有多个图表,则可以直接访问要清除/删除的图表:

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(); 
            }
        }
    }
}

这种新的第二种方式对我来说非常适合。

我希望对我的英语有帮助和抱歉

答案 1 :(得分:1)

我认为我找到了另一种方法,对我来说效果更好,而且代码更少。

Chart.js正在其中发出onCreate事件,您正在获取创建的图表对象。

然后我将对象存储在一个变量中,这样我就可以在我的点击处理程序中使用它。 (如果您在页面上有多个图表,则可能会收到多个lineChart.destroy()事件,并且您可以将每个图表对象存储在数组或对象中以供日后使用。)

在点击处理程序中,您可以调用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'];,这会破坏您的图表对象。别忘了清理你的数据。如果你再次需要,图表将由angular-chartjs重新创建。

这样做的好处是所有东西都被重置了。之前我遇到过这个问题,x轴刻度没有用其他方法清除。

请查看下面的演示或此jsfiddle

我需要在我的演示中检查的一个问题是图表在每个新数据时都会完全重新生成。也许这是正常行为,但我不确定。

&#13;
&#13;
<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>
&#13;
!
&#13;
&#13;
&#13;