我在下面使用了我的图表样本 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)
}
}]);
提前感谢任何建议。
答案 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,请创建一个存储原始值的变量,这样您就可以隐藏然后恢复列或行。