您可以在 Google Apps 脚本 HTML 服务中显示由 Google Visualization API 提供的任何 25+ chart types。
以下是Bubble Chart example 的修改版本。我们将从电子表格中提取数据,而不是固定数据。该图表将显示在模式对话框中,作为该电子表格中的附加组件。
源数据:
A B C D E
ID Life Expectancy Fertility Rate Region Population
CAN 80.66 1.67 North America 33739900
DEU 79.84 1.36 Europe 81902307
DNK 78.6 1.84 Europe 5523095
EGY 72.73 2.78 Middle East 79716203
GBR 80.05 2 Europe 61801570
IRN 72.49 1.7 Middle East 73137148
IRQ 68.09 4.77 Middle East 31090763
ISR 81.55 2.96 Middle East 7485600
RUS 68.6 1.54 Europe 141850000
USA 78.09 2.05 North America 307007000
客户端
设计的其余部分非常简单,但是对于不习惯在 HTML 服务中使用 javascript 的 Apps 脚本程序员,尤其是异步函数调用和回调的行为,这就是客户端中发生的事情最有趣的辅助代码。这是基本流程。
显示带有占位符的 html 页面,用于可视化。
加载外部 JavaScript 库。我们将使用 jQuery(用于轻松操作 DOM),当然还有 Google 的 JavaScript API,也就是 jsapi,用于可视化对象。
当页面加载时,请求回调。我们称之为sendQuery(),因为它将检索我们的电子表格数据。 这与仅显示图表的原始示例不同,因为我们不只是使用硬编码数据。
当jsapi完成加载时,sendQuery()被调用。它请求我们的数据,并将异步响应传递给另一个回调,drawSeriesChart()。
drawSeriesChart() 收到数据后,绘制图表。
从电子表格中检索数据的选项
由于我们的可视化将在浏览器(也称为客户端)中运行,因此我们需要从电子表格(也称为服务器端)中获取信息。根据您的具体需求,有几种方法可以检索该数据。
-
通过可视化 API 查询。
对于published spreadsheet,这是一种非常灵活的数据检索方式。您的客户端 js 可以指定您感兴趣的数据范围,您可以利用Query Language 来操作您将显示的数据,而无需修改源电子表格。
function sendQuery() {
var opts = {sendMethod: 'auto'};
var sheetId = "--- your sheet ID ---";
var dataSourceUrl = 'https://spreadsheets.google.com/tq?key=%KEY%&pub=1'
.replace("%KEY%",sheetId);
var query = new google.visualization.Query(dataSourceUrl, opts);
// Specify query string, if desired.
// Send the query with a callback function.
query.send(drawSeriesChart);
}
适用于您不拥有源数据的情况,例如
创建将提供电子表格数据的 Web 服务。这种方法使电子表格本身保持私密。
-
使用服务器和客户端脚本之间的直接通信,通过google.script.run。这样,电子表格仍然是私密的。此示例非常简单,因为它收集了整个电子表格,但您可以扩展它以通过过滤、排序或添加更多元数据进行格式化来操作您的数据。
function sendQuery() {
// Send the query with a callback function.
google.script.run
.withSuccessHandler(drawSeriesChart)
.getSpreadsheetData();
}
这需要在服务器端实现函数getSpreadsheetData() 以返回所需的数据。这在后面的实际代码中显示。
代码.gs
除了通常用于创建菜单的 yada-yada 之外,此文件还实现了 getSpreadsheetData() 函数,我们将使用该函数从工作表中检索所有数据。
/**
* Adds a custom menu with items to show the sidebar and dialog.
*
* @param {Object} e The event parameter for a simple onOpen trigger.
*/
function onOpen(e) {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem('Bubble Chart Example', 'showBubbleEx')
.addToUi();
}
/**
* Runs when the add-on is installed; calls onOpen() to ensure menu creation and
* any other initializion work is done immediately.
*
* @param {Object} e The event parameter for a simple onInstall trigger.
*/
function onInstall(e) {
onOpen(e);
}
/**
* Opens a dialog for a visualization.
*/
function showBubbleEx() {
var ui = HtmlService.createTemplateFromFile('BubbleEx')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(450)
.setHeight(350);
SpreadsheetApp.getUi().showModalDialog(ui, "Bubble Chart Example");
}
/**
* Return all data from first spreadsheet as an array. Can be used
* via google.script.run to get data without requiring publication
* of spreadsheet.
*
* Returns null if spreadsheet does not contain more than one row.
*/
function getSpreadsheetData() {
var data = SpreadsheetApp.getActive().getSheets()[0].getDataRange().getValues();
return (data.length > 1) ? data : null;
}
BubbleEx.html
这是改编自“Sheets 插件”模板,并引用其中包含的 Stylesheet.html 文件。
<!-- Use a templated HTML printing scriptlet to import common stylesheet. -->
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
<!-- Below is the HTML code that defines the dialog element structure. -->
<div>
<div id="series_chart_div" style="width: 400px; height: 300px;"></div>
<div class="block" id="dialog-button-bar">
<button id="dialog-cancel-button" onclick="google.script.host.close()">Cancel</button>
</div>
</div>
<!-- Use a templated HTML printing scriptlet to import JavaScript. -->
<?!= HtmlService.createHtmlOutputFromFile('BubbleExJavaScript').getContent(); ?>
BubbleExJavaScript.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
// Load the Visualization API and desired package(s).
google.load('visualization', '1.0', {'packages':['corechart']});
/**
* Run initializations on dialog load.
*/
$(function() {
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(sendQuery);
// Assign handler functions to dialog elements here, if needed.
// Call the server here to retrieve any information needed to build
// the dialog, if necessary.
});
/**
* Issue asynchronous request for spreadsheet data.
*/
function sendQuery() {
google.script.run
.withSuccessHandler(drawSeriesChart)
.getSpreadsheetData();
}
/**
* Callback function to generate visualization using data in response parameter.
*/
function drawSeriesChart(response) {
if (response == null) {
alert('Error: Invalid source data.')
return;
}
else {
var data = google.visualization.arrayToDataTable(response,false);
var options = {
title: 'Correlation between life expectancy, fertility rate and population of some world countries (2010)',
hAxis: {title: data.getColumnLabel(1)}, // 'Life Expectancy'
vAxis: {title: data.getColumnLabel(2)}, // 'Fertility Rate'
bubble: {textStyle: {fontSize: 11}}
};
var chart = new google.visualization.BubbleChart(document.getElementById('series_chart_div'));
chart.draw(data, options);
}
}
</script>