Google visualization data.join创建的dataTable的dataView的chartWrapper在值更改时不更新
首先,请原谅下面的小说,但这很难描述 我有一个相当复杂的应用程序,我目前正在通过一个GAS应用程序的HtmlService使用gviz 不过,这更像是一个客户端gviz API问题 我正在通过query方法加载两个数据表,并通过data.join将它们组合起来。该结果数据表是数据视图的源 然后使用该视图生成具有多个类别过滤器和单个tableChart的仪表板。我有一个按钮,可以在显示的视图行和列的两个过滤器集之间切换。其概念是加载所有记录,并在挂起和完成之间切换,向用户显示相关列 这部分实际上工作得非常好。我遇到的问题是数据更新问题。每次可视化绘制时,我都会遍历生成的表,并将操作附加到各个列 一个这样的操作打开一个带有行值的jQueryUI对话框,允许用户进行修改并提交到服务器。当它提交时,而不是重新查询我的数据,我的方法是在ajaxsuccess上更新dataTable,这要快得多 在实现连接之前,这是基于单个dataTable的,当我更新dataTable时,基于它的dataView也会更新,在chartWrapper上调用draw()会按照预期更新UI 问题是,这在联接的数据表上不起作用。我已经在客户端的开发者工具中确认,dataTable实际上正在像dataView一样更新值,但这不会传播到tableChart 这是真正奇怪的部分。如果在开发工具中使用chartWrapper的.getDataTable方法,我可以确认有问题的记录已更新尽管生成的可视化中的值不是 我尝试在AJAX成功中重新绘制图表包装器,但没有成功。当滚动级别更改时,它会重新绘制(chartWrapper),但数据不会更改。我尝试在开发工具中手动重画chartWrapper和dashboard,甚至将视图作为dataTable传递。事实上,两者都会重新绘制,但都不会更新数据 我曾尝试在chartWrapper上重新绘制getDataTable表,但这基本上与我的仪表板和样式分离,并绘制了整个数据集,这不是我所需要的 更改类别筛选器不会在回筛选后更新tableChart。即使将不同的过滤器应用到dataView,然后再返回,也不会更新它。我发现唯一有效的方法是重新查询整个内容,这需要5-10秒的时间。每一次变更都是不可接受的延误。在第一次加载时,这很好,但理想情况下,每个用户会话只发生一次 我花了数小时调试和整理(糟糕的)文档,我看到的一切似乎都表明它应该可以工作 我开始怀疑这可能是某种缓存问题,还是我遗漏了一些文档中没有解释的技巧 这个特定页面的客户端代码是1100行,所以很难完整发布。下面是一个非常简单的版本,我正在做的关键部分包括。如有任何意见或建议,将不胜感激 注意,我省略了许多与生成操作的对话框或按钮相关的部分,但它们大多是不相关的Google visualization data.join创建的dataTable的dataView的chartWrapper在值更改时不更新,google-visualization,Google Visualization,首先,请原谅下面的小说,但这很难描述 我有一个相当复杂的应用程序,我目前正在通过一个GAS应用程序的HtmlService使用gviz 不过,这更像是一个客户端gviz API问题 我正在通过query方法加载两个数据表,并通过data.join将它们组合起来。该结果数据表是数据视图的源 然后使用该视图生成具有多个类别过滤器和单个tableChart的仪表板。我有一个按钮,可以在显示的视图行和列的两个过滤器集之间切换。其概念是加载所有记录,并在挂起和完成之间切换,向用户显示相关列 这部分实际上工
var loaded = false;
var ready = {pro: false, sec: false};
var data = {};
// Ajax load gviz api
$.ajax({
url: 'https://www.google.com/jsapi?callback',
cache: true,
dataType: 'script',
success: function(){
google.load('visualization', '1', {packages:['controls'], 'callback' : sendQuery
});
return true;
}
});
function sendQuery() {
console.log('query setting');
var opts = {sendMethod: 'auto'};
var urlPro = 'Google Spreadsheet source 1';
queryPro = new google.visualization.Query(urlPro, opts);
queryPro.setQuery('select A,B,C,D,E where(G = \'No\')');//...15k+ rows 30+ cols in reality
var urlSec = 'Google Spreadsheet source 2';
querySec = new google.visualization.Query(urlSec, opts);
querySec.setQuery('select A,B,C,D');//...~200+ rows 30+ cols in reality, rows created with app
queryPro.send(function(response){
console.log('query Pro returned');
if (response.isError()) {
alert('Error in query Pro: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
ready.pro = true;
data.pro = response.getDataTable();
if (ready.pro && ready.sec) {
drawDashboard(false);
}
});
querySec.send(function(response){
if (response.isError()) {
alert('Error in query Sec: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
console.log('query Sec returned');
ready.sec = true;
data.sec = response.getDataTable();
if (ready.pro && ready.sec) {
drawDashboard(false);
}
});
}
function drawDashboard(complete) {
var pendingCols = [0,2,3,4];
var completeCols = [1,2,3,4,5,7,8];
if (!loaded) {
console.log('first load of data');
var joinProCols=[1,2,3,4];
var joinSecCols=[1,2,3];
joined = new google.visualization.data.join(data.pro, data.sec, 'left', [[0, 0]], joinProCols, joinSecCols);
viewActive = new google.visualization.DataView(joined);
var numCols = joined.getNumberOfColumns();
for (var i=0; i<numCols; i++){
ogColName = joined.getColumnLabel(i).replace(/\W/g, '');
if (empTable.hasOwnProperty(ogColName)){ //passed from server; ommitted def in this example
joined.setColumnLabel(i, empTable[ogColName][lang]);
}
joined.setColumnProperty(i, 'ident', ogColName);
}
}
var pendingRows = joined.getFilteredRows([{column: 4, value: null}]);
var completeRows = joined.getFilteredRows([{column: 4, minValue: ''}]);
if (complete) {
viewActive.setColumns(completeCols);
viewActive.setRows(completeRows);
} else {
viewActive.setColumns(pendingCols);
viewActive.setRows(pendingRows);
}
dashboard = new google.visualization.Dashboard(document.getElementById('dashboard-div'));
// options for displayed table
var tableOpts = {
width: '1500px',
height: '100%',
page: 'enable',
pageSize: 40,
cssClassNames: {
headerCell: 'gviz header',
headerRow: 'gviz header',
oddTableRow: 'gviz odd',
tableRow: 'gviz even',
selectedTableRow: 'gviz selected',
hoverTableRow: 'gviz hover',
rowNumberCell: 'gviz rowNum'
}
};
tableChart = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'table-div',
'options': tableOpts
});
var picker1 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'sel-pick1',
'options': {
'filterColumnLabel': 'Picker1',
'ui': {
'labelStacking': 'vertical',
'selectedValuesLayout': 'belowWrapping',
'caption': 'Picker1'
}
}
});
var picker2 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'sel-pick2',
'options': {
'filterColumnLabel': 'Picker2',
'ui': {
'labelStacking': 'vertical',
'selectedValuesLayout': 'belowWrapping',
'caption': 'Picker2'
}
}
});
//...quite a few more pickers in real code
if (complete) {
var picker3 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'sel-pick3',
'options': {
'filterColumnLabel': 'picker3',
'ui': {
'labelStacking': 'vertical',
'selectedValuesLayout': 'belowWrapping',
'caption': 'picker3'
}
}
});
//...A couple more pickers in real app here too
}
// Set up dependencies between controls and charts
dashboard.bind(picker1, picker2);
//...bindings for other pickers
if (complete) {
dashboard.bind(picker2, picker3);
dashboard.bind([picker1, picker2, picker3], tableChart);
} else {
dashboard.bind([picker1, picker2], tableChart);
}
// Draw all visualization components of the dashboard and add listeners
google.visualization.events.addListener(tableChart, 'ready', function(){
google.visualization.events.addListener(tableChart.getChart(), 'page', addFields);
google.visualization.events.addListener(tableChart.getChart(), 'sort', addFields);
google.visualization.events.addListener(tableChart.getChart(), 'select', function(e){
//cancel selection here as it won't be useful
tableChart.getChart().setSelection('');
});
//grab the table and inject our custom actions into it
if (complete) {
addFields(true);
} else {
addFields();
}
// show containers
$('.processing.page').hide();
$('#dashboard-div').show();
loaded = true;
});
dashboard.draw(viewActive);
}
//........................................
$('#dataForm').submit(function( event ) {
if ($('#dataForm').valid()){
$('#dataForm').hide();
$('.processing.data.form').show();
google.script.run.withSuccessHandler(onSuccessUpdate).recordData(this);
}
event.preventDefault();
});
//...................................................
function onSuccessUpdate(response){
var numCols = joined.getNumberOfColumns();
for (var i=0; i<numCols; i++){
for (var key in response.form){
if (!response.form.hasOwnProperty(key)) continue;
if (joined.getColumnProperty(i, 'ident') == key){
joined.setValue(response.row, i, response.form[key]);
}
}
}
tableChart.draw();//This should be updating the values!
$('.message.success').html(response.message).show();
$('#dataForm').show();
$('.processing.data.form').hide();
$('#userProfileDialog').dialog('close');
}
var-load=false;
var ready={pro:false,sec:false};
变量数据={};
//Ajax加载gviz-api
$.ajax({
网址:'https://www.google.com/jsapi?callback',
是的,
数据类型:“脚本”,
成功:函数(){
load('visualization','1',{packages:['controls'],'callback':sendQuery
});
返回true;
}
});
函数sendQuery(){
log(“查询设置”);
var opts={sendMethod:'auto'};
var urlPro='谷歌电子表格源1';
queryPro=newgoogle.visualization.Query(urlPro,opts);
setQuery('selecta,B,C,D,E其中(G=\'No\');/…15k+行30+列
var urlSec='谷歌电子表格源2';
querySec=newgoogle.visualization.Query(urlSec,opts);
setQuery('select A,B,C,D');/…~200+行30+列实际上是用app创建的行
queryPro.send(函数(响应){
log('query Pro returned');
if(response.isError()){
警报('query Pro中的错误:'+response.getMessage()+'+response.getDetailedMessage());
返回;
}
ready.pro=true;
data.pro=response.getDataTable();
if(ready.pro&&ready.sec){
drawDashboard(假);
}
});
querySec.send(函数(响应){
if(response.isError()){
警报('query Sec中的错误:'+response.getMessage()+'+response.getDetailedMessage());
返回;
}
log('query Sec returned');
ready.sec=true;
data.sec=response.getDataTable();
if(ready.pro&&ready.sec){
drawDashboard(假);
}
});
}
功能面板(完整){
var pendingCols=[0,2,3,4];
var completeCols=[1,2,3,4,5,7,8];
如果(!已加载){
log(“第一次加载数据”);
var joinProCols=[1,2,3,4];
var joinSecCols=[1,2,3];
join=new google.visualization.data.join(data.pro,data.sec,'left',[[0,0]],joinProCols,joinSecCols);
viewActive=新的google.visualization.DataView(已加入);
var numCols=joined.getNumberOfColumns();
法罗群岛
function onSuccessUpdate(response){
var numCols = joined.getNumberOfColumns();
for (var i=0; i<numCols; i++){
for (var key in response.form){
if (!response.form.hasOwnProperty(key)) continue;
if (joined.getColumnProperty(i, 'ident') == key){
joined.setValue(response.row, i, response.form[key]);
//Need to also set formatted value
joined.setFormattedValue(response.row, i, response.form[key]);
}
}
}
tableChart.draw();//This should be updating the values!
$('.message.success').html(response.message).show();
$('#dataForm').show();
$('.processing.data.form').hide();
$('#userProfileDialog').dialog('close');