ng-google-chart如何公开draw()方法

时间:2017-06-14 16:24:28

标签: angularjs charts google-visualization

我在下面使用了我的图表样本 nicholas bering, API Promise。我在下面的演示中伪造了$ http数据回调。

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

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

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

但这是我迷路的地方......我理解的draw()方法应该已经存在于我创建的原始图表中。如何公开原始图表的draw()方法,而不必使用document.getElementById('myBarChart')戳DOM。这似乎与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)
    }
}]);

提前感谢任何建议。

2 个答案:

答案 0 :(得分: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)
}

}]);

这对我有用,并开辟了许多新的选择。

答案 1 :(得分:0)

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

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