显示空白图表,然后使用按钮更新(谷歌图表)
Showing Blank Chart then Updating It Using Button (Google Charts)
我正在尝试使用谷歌图表创建一些数据的散点图可视化。最初,我希望图表是呈现的,但在用户单击按钮之前是空的。我希望它被绘制为空的原因是,即使没有加载任何数据,图表也会占据页面上正确的区域。
按下html按钮将向远程服务器发送请求,获取一些数据,然后在数据加载后刷新显示,以显示可爱的更新图形。
问题是,即使在将数据添加到TableData变量并请求dashboard.draw()之后,图形显示也不会更新。我觉得这里一定遗漏了一些明显的东西,因为所有关于堆栈溢出的建议都表明,只需将数据添加到DataTable并调用draw()就可以更新表。表的控制器似乎确实更新以反映新数据,但图表本身没有。
如果我在调用drawChart()函数时立即加载数据,那么图形就会完美地显示出来。类似地,如果我不显示一个空图表,而是在数据加载回调函数中加载数据后才调用draw(),那么图表就会正确显示。然而,当一张图表突然出现在页面上时,这看起来并不好。
HTML:
<body>
<h1>A nice chart showing user data.</h1>
<p>Simply insert a username into the text box and click get user data.</p>
<div class="usernameInputDiv">
<form id="usernameForm1">
Username: <input id="usernameTextBox" type="text" name="username">
</form>
<div class="button">
<button class="btn">Get User Data</button>
</div>
</div>
<div id="dashboard_div" style="width: 600px; height: 350px;">
<div id="dashboardChart_div" style="width: 600px; height: 300px;">
</div>
<div id="rangeSlider_div" style="width: 600px; height: 50px;">
</div>
</div>
</body>
和javascript代码:
$(document).ready(function () {
google.load("visualization", "1", {packages:["corechart", "controls"], "callback" : drawChart});
});
//Draws a scatter chart
function drawChart() {
//Column names for adding data
var columnNames = ["time","bytesInAvg","bytesOutAvg","bytesInMax","bytesOutMax"];
//initialise a data structure to store the data
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Date');
data.addColumn('number', 'bytesInAvg');
data.addColumn('number', 'bytesOutAvg');
data.addColumn('number', 'bytesInMax');
data.addColumn('number', 'bytesOutMax');
//Create a dashboard
//Dashboards are used to group one (or more) graphs along with the controls for that graph
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div'));
var options = {
title: 'Data Sent/Received Per Minute (bytes)',
hAxis: {title: 'Time'},
vAxis: {title: 'Data Sent/Received (bytes)'},
legend: '' //sets the legend to be displayed, use None for no legend
};
//Create chart for dashboard
var dashboardChart = new google.visualization.ChartWrapper({
'chartType': 'ScatterChart',
'containerId': 'dashboardChart_div',
'options': options
});
//Create controller for chart
var dateRangeSlider = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'rangeSlider_div',
'options': {
'filterColumnLabel': 'Date'
}
});
//bind the chart and controller together in the dashboard
dashboard.bind(dateRangeSlider, dashboardChart);
//No data is loaded, so just show a blank chart for now so that it occupies the space
//and is obvious to the user.
updateDisplay(data,dashboard);
//This is used to get and load data from a remote service
$('.btn').click(function() {
console.log("Received button press event");
getTestData(data, dashboard, columnNames);
});
function updateDisplay(data, dashboard){
//get the range of the data (just use col 1 for now)
var yRange = data.getColumnRange(1);
var xRange = data.getColumnRange(0);
//Update chart axes. I would like this to be done automatically,
//but it isn't, so for now I do it by hand.
dashboardChart.setOption('vAxis.maxValue', yRange.max);
dashboardChart.setOption('vAxis.minValue', yRange.min);
dashboardChart.setOption('hAxis.maxValue', xRange.max);
dashboardChart.setOption('hAxis.minValue', xRange.min);
//update the display
dashboard.draw(data);
}
//Test function simulating querying a server (using setTimeout to simulate delay)
//and loading the data into a DataTable
function getTestData(data, dashboard, columnNames){
setTimeout(function() {
var jsonObject = [
{time:"2014-09-25T01:17:00.000Z", "bytesInAvg":713, "bytesOutAvg":1751, "bytesInMax":6916, "bytesOutMax":18947},
{time:"2014-09-25T01:18:00.000Z", "bytesInAvg":146, "bytesOutAvg":328, "bytesInMax":810, "bytesOutMax":2877},
{time:"2014-09-25T01:19:00.000Z", "bytesInAvg":44, "bytesOutAvg":73, "bytesInMax":122, "bytesOutMax":196},
{"time":"2014-09-25T01:20:00.000Z", "bytesInAvg":41, "bytesOutAvg":69, "bytesInMax":122, "bytesOutMax":196},
];
addResultToDataTable(data,jsonObject,columnNames);
updateDisplay(data, dashboard);
}, 2000);
}//getTestData
function addResultToDataTable(data, result, columnNames)
{
for ( var i = 0; i < result.length; i++)
{
data.addRow([ new Date(result[i]['time']), result[i][columnNames[1]], result[i][columnNames[2]], result[i][columnNames[3]], result[i][columnNames[4]] ]);
}
}//addResultsToDataTable
}//drawChart()
我在这里包含了一个jsfiddle的最低限度的工作示例。有人能弄清楚为什么图表没有正确更新吗?
谢谢。
不确定原因,但您的dateRangeControl出现了问题,因此即使数据在那里,它也会按范围过滤而不显示。您可以使用进行检查
dashboard.draw(data);
console.log(dateRangeSlider.getState()) // after update, shows same date for start and end(year 1969)
因此,一个快速的解决方案是为您的数据设置一个有效的范围:
dashboard.draw(data);
dateRangeSlider.setState({end:new Date(), start:new Date(new Date().setMonth(new Date().getMonth()-1))})
全小提琴:http://jsfiddle.net/uf5wocx9/17/
显然,一旦最初使用dashboard.draw(data)绘制了空图,就应该随后对图(ChartWrapper)本身进行更新。因此,与其调用dashboard.draw(data),不如直接调用dashbardChart.draw。这样做就不需要手动更改日期范围滑块。这种行为有点奇怪,在文档中并不明显。
来自此处文档的第8节:
- 绘制后的程序更改
如果您需要以编程方式更改仪表板状态,您可以因此,通过直接在ControlWrapper和ChartWrapper上操作实例。经验法则是执行直接在特定ControlWrapper上需要的更改(或ChartWrapper)实例:例如,更改控件选项或状态分别通过setOption()和setState(),并调用其draw()方法。然后,仪表板将更新以匹配请求的更改。
- 角度指令是't更新谷歌地图值
- 用sql数据库更新谷歌地图标记
- Firefox 14更新谷歌广告未加载页面
- 仅更新谷歌地图中的标记
- 在不加载页面的情况下更新谷歌地图上的标记位置
- 使用 AJAX 动态更新谷歌地图
- 动态更新谷歌地理图表的颜色
- 如何更新谷歌地图引擎表
- 页面加载时从邮政编码更新谷歌地图
- 如何在用户滚动时更新谷歌地图中心
- 显示空白图表,然后使用按钮更新(谷歌图表)
- 如何更新谷歌地图,如果它的地图画布改变了它的尺寸
- 如何更新谷歌地图大头针而不刷新整个地图
- 更新谷歌折线图
- 更新谷歌地图制作不透明度,无需重新加载页面
- 无论如何,限制更新谷歌地图时平移
- 定期更新谷歌排行榜
- 动态更新谷歌热图层
- 更新谷歌地图的缩放矩形
- 更新谷歌地图标记没有重新加载地图和眨眼