2017-06-14 85 views
0

我已经使用 nicholas bering, API Promise创建了我的图表示例。我在下面的演示中伪造了$ http数据回调。ng-google-chart如何曝光draw()方法

我的问题是如何正确访问图表的draw()方法后,它已经显示在浏览器中?

在我的演示下面,我创建了一个google.visualization.DataView(),以便我可以访问hideRows()方法。一旦发生这种情况,文档说我需要调用draw()方法来重新绘制新修改的行信息。

在这种情况下,我试图让用户隐藏显示数量为零的项目行(我的数据中的第2行“Olives”)。一旦我得到这个工作,我会让用户切换其他的东西,但现在我试图让我的问题简单。

但是,这是我迷失的地方...... draw()方法据我了解,它应该已经存在于我创建的原始图表上。如何在不用用document.getElementById('myBarChart')戳DOM的情况下公开原始图表的draw()方法。这似乎与Angular不同。

这里是我的代码:

<div ng-controller="ChartsController as ChartsController" 
ng-init="ChartsController.init()"> 

    <button ng-click="ChartsController.ToggleZeroDistributionOff()">No Zeros</button><br> 

    <div google-chart chart="chartMe" id="myBarChart" /> 

</div> 

现在我的控制器:

'use strict'; 

app.controller('ChartsController', ['$scope', '$http', '$q', 'googleChartApiPromise', function ($scope, $http, $q, googleChartApiPromise) { 

    this.name = "ChartsController"; 
    this.$inject = ['$scope', '$q', '$http', 'googleChartApiPromise']; 

    $scope.chartMe = {}; 

    this.init = function() { 
     // simulated $http callback data returned in promise 
     var dataPromise = { 
      "data": [ 
       {"itemname": "Mushrooms", "qty": 13 }, 
       {"itemname":"Onions", "qty": 11}, 
       {"itemname":"Olives", "qty": 0}, 
       {"itemname":"Zucchini", "qty": 1}, 
       {"itemname": "Pepperoni", "qty": 27 } 
      ] 
     } 
     // bind data and chart loading before building the my chart 
     $q.all({ data: dataPromise, api: googleChartApiPromise }) 
      .then(apiLoadSuccess); 
    }; 


    function apiLoadSuccess(result) { 
     $scope.chartMe.type = 'BarChart'; 
     //create a new DataTable loaded with data from the HTTP response 
     $scope.chartMe.data = new google.visualization.DataTable(); 
     $scope.chartMe.data.addColumn('string', 'Item Name/Units'); 
     $scope.chartMe.data.addColumn('number', 'Qty'); 
     // create an array to hold index of items 
     var aNoQty = []; 
     var aQty = []; 
     var aRows = []; 
     for (var i = 0; i < result.data.data.length; i++) { 
      var oData = []; 
      aRows.push(i); 
      oData[0] = result.data.data[i].itemname; 
      oData[1] = result.data.data[i].qty; 
      // which items quanity exist 
      if (result.data.data[i].qty > 0) { 
       aQty.push(i); 
      } else { 
       aNoQty.push(i); 
      }; 
      // now add the row 
      $scope.chartMe.data.addRow(oData); 
     }; 

     $scope.aNoQty = aNoQty; 
     $scope.aQty = aQty; 

     $scope.chartMe.options = { 
      title: "Item(s) Distributed", 
      isStacked: false, 
      displayExactValues: true, 
     }; 
    }; 

    this.ToggleZeroDistributionOff = function() { 
     $scope.chartMe.view = new google.visualization.DataView($scope.chartMe.data); 
     $scope.chartMe.view.hideRows($scope.aNoQty) 

     // this seems like the wrong way to attach to existing chart... 
     // i'm referring to using document.getElementById() - not very Angular ! 
     // but how else to expose the draw() method ?? 
     var myChart = new google.visualization.BarChart(document.getElementById('myBarChart')); 
     // now draw() method is expoised 
     myChart.draw($scope.chartMe.view.toDataTable(), $scope.chartMe.options) 
    } 
}]); 

在此先感谢您的任何建议。

+0

我的理解使用google.visualization.BarChart(DOM_Reference_Required),我从先前读数理解,对DOM元素的直接访问是藻体后和在角不推荐。也许我错了,但没有引用DOM元素,我想我想知道ng-google-chart有一个像ng-model一样的解决方案。 –

+1

您可以使用['ChartWrapper类'](https://developers.google.com/chart/interactive/docs/reference#chartwrapper-class),它只需要元素的id,加上数据表和选项被嵌入,这样调用'draw()'不需要参数... – WhiteHat

+0

我最终使用了您之前关于将myChart添加到$ scope.chartMe中的完美工作的评论。 (即$ scope.chartMe.myChart = ...)谢谢! –

回答

0

谢谢WhiteHat的建议。它有效地解决了这个问题,但在我的案例中发现你的第一个答案更容易处理。

我贴下面的完整解决方案:

'use strict'; 

app.controller('ChartsController', ['$scope', '$http', '$q', 
'googleChartApiPromise', function ($scope, $http, $q, googleChartApiPromise) { 

this.name = "ChartsController"; 
this.$inject = ['$scope', '$q', '$http', 'googleChartApiPromise']; 

$scope.chartMe = {}; 

this.init = function() { 
    // simulated $http callback data returned in promise 
    var dataPromise = { 
     "data": [ 
      {"itemname": "Mushrooms", "qty": 13 }, 
      {"itemname":"Onions", "qty": 11}, 
      {"itemname":"Olives", "qty": 0}, 
      {"itemname":"Zucchini", "qty": 1}, 
      {"itemname": "Pepperoni", "qty": 27 } 
     ] 
    } 
    // bind data and chart loading before building the my chart 
    $q.all({ data: dataPromise, api: googleChartApiPromise }) 
     .then(apiLoadSuccess); 
}; 


function apiLoadSuccess(result) { 
    $scope.chartMe.type = 'BarChart'; 
    //create a new DataTable loaded with data from the HTTP response 
    $scope.chartMe.data = new google.visualization.DataTable(); 
    $scope.chartMe.data.addColumn('string', 'Item Name/Units'); 
    $scope.chartMe.data.addColumn('number', 'Qty'); 
    // create an array to hold index of items 
    var aNoQty = []; 
    var aQty = []; 
    var aRows = []; 
    for (var i = 0; i < result.data.data.length; i++) { 
     var oData = []; 
     aRows.push(i); 
     oData[0] = result.data.data[i].itemname; 
     oData[1] = result.data.data[i].qty; 
     // which items quanity exist 
     if (result.data.data[i].qty > 0) { 
      aQty.push(i); 
     } else { 
      aNoQty.push(i); 
     }; 
     // now add the row 
     $scope.chartMe.data.addRow(oData); 
    }; 

    $scope.aNoQty = aNoQty; 
    $scope.aQty = aQty; 

    $scope.chartMe.options = { 
     title: "Item(s) Distributed", 
     isStacked: false, 
     displayExactValues: true, 
    }; 

    // chart view used later 
    $scope.chartMe.view = new google.visualization.DataView($scope.chartMe.data); 
    // grab a reference to the chart 
    $scope.chartMe.myChart = new google.visualization.BarChart(document.getElementById('myBarChart')); 

}; 

this.ToggleZeroDistributionOff = function() { 
    // $scope.chartMe.view = new google.visualization.DataView($scope.chartMe.data); 
    $scope.chartMe.view.hideRows($scope.aNoQty) 

    // draw() method exists so refresh with new view 
    $scope.chartMe.myChart.draw($scope.chartMe.view.toDataTable(), $scope.chartMe.options) 
} 

}]);

这为我工作,并打开了很多新的选择。

0

谢谢!假设您没有那么多数据,另一种将行隐藏为视图中输入的响应的方法是,使用ng-change并设置 行(s)/列中单元格的值(s)= null。您必须找到所有要设置为空的单元格,因为您不能简单地将整行或列设置为空。逐个。优点是你可以坚持使用ng-google-charts的简单方法。再次,这可能使事情更容易,只有小图表。你也可以编写一个函数对表格进行push()操作,以便在输入中进行更改,以便从视图中插入数据。如果ng-change直接影响DataTable,请创建一个存储原始值的变量,这样您可以隐藏并恢复列或行。

https://www.w3schools.com/angular/ng_ng-change.asp