我一直在使用谷歌的图表API,并已达到死胡同。我使用API查询电子表格并返回一些数据。对于可视化,我使用Razorflow - 一个JS仪表板框架 - 而不是Google Charts。使用这样的代码获取数据非常简单(此代码应该可以使用 - 电子表格是公开的):
function initialize() {
// The URL of the spreadsheet to source data from.
var myKey = "12E2fE8GWuPvXJoiRZgCZUCFhRKlW69uJAm7fch71jhA"
var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/" + myKey + "/gviz/tq?sheet=Sheet1");
query.setQuery("SELECT A,B,C WHERE A>=1 LIMIT 1");
query.send(function processResponse(response) {
var KPIData = response.getDataTable();
var KPIName = [];
myNumberOfDataColumns = KPIData.getNumberOfColumns(0) - 1;
for (var h = 0; h <= myNumberOfDataColumns ; h++) {
KPIName[h] = KPIData.getColumnLabel(h);
};
});
};
google.charts.setOnLoadCallback(initialize);
上面将创建一个包含A,B和C列的列标签的数组。
获取数据后,我想将数据用于我的图表。问题是,我需要在创建图表之前准备好数据。我这样做的一种方法是在调用google.charts.setOnLoadCallback(initialize)
之前创建图表,然后使用回调内部的数据填充图表。像这样:
//create dashboard
StandaloneDashboard(function (db) {
//create chart - or in this case a KPI
var firstKPI = new KPIComponent();
//add the empty component
db.addComponent(firstKPI);
//lock the component and wait for data
firstKPI.lock();
function initializeAndPopulateChart() {
// The URL of the spreadsheet to source data from.
var myKey = "12E2fE8GWuPvXJoiRZgCZUCFhRKlW69uJAm7fch71jhA"
var query = new google.visualization.Query("https://docs.google.com/spreadsheets/d/" + myKey + "/gviz/tq?sheet=Sheet1");
query.setQuery("SELECT A,B,C WHERE A>=1 LIMIT 1");
query.send(function processResponse(response) {
var KPIData = response.getDataTable();
var KPIName = [];
myNumberOfDataColumns = KPIData.getNumberOfColumns(0) - 1;
for (var h = 0; h <= myNumberOfDataColumns ; h++) {
KPIName[h] = KPIData.getColumnLabel(h);
};
//use label for column A as header
firstKPI.setCaption(KPIName[0]);
//Set a value - this would be from the query too
firstKPI.setValue(12);
//unlock the chart
firstKPI.unlock();
});
};
google.charts.setOnLoadCallback(initializeAndPopulateChart);
});
它有效,但我想将图表功能与数据加载分开。我想最好的解决方案是创造一个承诺。这样我可以做这样的事情:
//create dashboard
StandaloneDashboard(function (db) {
function loadData() {
return new Promise (function (resolve,reject){
//get the data, eg. google.charts.setOnLoadCallback(initialize);
})
}
loadData().then(function () {
var firstKPI = new KPIComponent();
firstKPI.setCaption(KPIName[0]);
firstKPI.setValue(12);
db.addComponent(firstKPI);
})
});
应该很明显,我不完全了解如何使用promises。以上不起作用。我尝试了很多不同的方法但是,我似乎没有更接近解决方案。我是否正在使用承诺?如果是这样,我应该怎么做呢?
答案 0 :(得分:0)
在承诺内部,您需要在异步作业完成时调用resolve
或reject
函数。
function loadData() {
return new Promise (function (resolve,reject){
query.send(function() {
//...
err ? reject(err) : resolve(someData);
});
})
}
然后你可以做
loadData().then(function (someData) {
//here you can get async data
}).catch(function(err){
//here you can get an error
});
});
答案 1 :(得分:0)
new Promise(resolve => {
google.charts.setOnLoadCallback(resolve);
}).then(getValues);