Looker Visualization API 是一种 JavaScript API,可在 沙盒化 iframe 中运行,并托管在 Looker 应用中。
您可以使用相同的可视化图表代码在 Looker 中的任何位置提供可视化图表:探索、Look、信息中心、嵌入或 PDF 或渲染的图片。
每个可视化图表都代表单个 Looker 查询的视图。 Looker 会执行查询并将结果传递给您的可视化图表代码。Looker 还会传递一个 DOM 元素,您的可视化图表代码可以在其中绘制。
要求
在开始之前,请确保满足以下要求:
- 您需要具备一定的 JavaScript 和 Web 开发知识。
- 您需要拥有 Looker 管理员访问权限才能创建和更新 LookML 项目清单文件。
创建 Hello World 可视化图表
本部分介绍了如何创建自定义可视化图表脚本,以显示给定查询的第一个维度。
最终结果应类似于下图:

设置
如需在 Looker 中开发和测试可视化图表,您有两种选择:
配置其中一个选项后,您可以按照本部分中的示例创建 hello_world.js。
基本代码结构
如需查看此示例的最终源代码,请参阅 GitHub 代码库。
在您托管的文件夹中,创建一个新的空白 JavaScript 文件,并将其命名为 hello_world.js。
如需向 Looker 注册新的自定义可视化图表,请调用 looker.plugins.visualizations.add 函数,并向其传递可视化图表对象。
此对象包含可视化图表的定义及其配置界面。
以下示例展示了可视化图表的框架,其中填充了所有必需的属性。它包含一个 create 函数和一个 updateAsync 函数,您可以在其中编写可视化图表代码:
looker.plugins.visualizations.add({
create: function(element, config) {
},
updateAsync: function(data, element, config, queryResponse, details, done) {
}
})
此代码是有效的 Looker 可视化图表,但尚未可视化,并且显示为空白框。
介绍背景
请考虑 create 函数,该函数有两个实参:element 和 config。
Looker 提供了一个 element,即
Looker 要求您将可视化图表放入其中的
DOM 元素。
Looker 会构建此元素并将其设置为适当的大小;您必须将内容放入其中。
create 函数提供了对元素执行初始设置的机会。对于此示例,您需要创建一个类似于以下 HTML 结构的图表:
<style>
/* custom styles for your chart */
</style>
<div class="hello-world-vis">
<div>Data Goes Here</div>
</div>
使用 JavaScript,您可以将元素插入 DOM 元素中以匹配此结构。
以下示例展示了此函数,并添加了更多详细信息:
create: function(element, config) {
// Insert a <style> tag with some styles to use later.
var css = element.innerHTML = `
<style>
.hello-world-vis {
/* Vertical centering */
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
</style>
`;
// Create a container element to center the text.
var container = element.appendChild(document.createElement("div"));
container.className = "hello-world-vis";
// Create an element to contain the text.
this._textElement = container.appendChild(document.createElement("div"));
},
此代码会添加 CSS,创建 hello-world-vis 容器,并在其中添加 div。
该代码还会将 this._textElement 分配给您要渲染到的容器。这样做很方便,这样您就不必在图表开始渲染时再次查找它。
create 函数是执行只需执行一次的设置任务的便捷位置。
渲染
本部分介绍了如何展开 updateAsync 方法以可视化数据。每当图表必须可视化更改或发生任何其他可能会影响图表渲染方式的事件(例如,图表大小调整或配置选项更改)时,都会调用此方法。
对于此示例,您只需在第一个单元格中找到第一个维度。
您可以使用 data(它是数据集每一行的数组)和 queryResponse(其中包含有关查询的元数据,例如字段名称和类型)来执行此操作。
您还可以使用名为 LookerCharts.Utils.htmlForCell 的辅助方法,以提供该单元格中数据点的正确 HTML 表示形式。此方法会自动处理钻取链接、格式设置和数据操作等元素:
updateAsync: function(data, element, config, queryResponse, details, done) {
// Grab the first cell of the data.
var firstRow = data[0];
var firstCell = firstRow[queryResponse.fields.dimensions[0].name];
// Insert the data into the page.
this._textElement.innerHTML = LookerCharts.Utils.htmlForCell(firstCell);
// Always call done to indicate a visualization has finished rendering.
done()
}
这样就完成了使自定义可视化图表正常运行所需的步骤。不过,请务必添加一种处理错误的方法。
处理错误
updateAsync 代码会获取第一行数据,但如果查询未返回任何结果或不包含任何维度,则可能会发生错误。
如果没有错误处理,浏览器控制台中会显示 JavaScript 错误,这可能会在图表未渲染时让用户感到困惑。
图表在尝试渲染时如果遇到问题,可以显示自定义出错提示。Looker 会向可视化图表对象添加两个函数:addError 和 clearErrors。您可以使用这些函数来显示对所有用户都有意义的出错提示。
由于这些函数已添加到可视化图表对象,因此可以通过 this 对象从 updateAsync 函数的上下文中获取这些函数。
您可以修改 updateAsync 方法的开头,以检测错误情况、向用户通知问题并退出,而不是尝试渲染:
updateAsync: function(data, element, config, queryResponse, details, done) {
// Clear any errors from previous updates.
this.clearErrors();
// Throw some errors and exit if the shape of the data isn't what this chart needs.
if (queryResponse.fields.dimensions.length == 0) {
this.addError({title: "No Dimensions", message: "This chart requires dimensions."});
// Always call done() before exiting early to avoid dashboard exports hanging
done();
return;
}
if (!data || data.length === 0) {
this.addError({title: "No Data", message: "The query returned no results."});
done();
return;
}
// ... the rest of the update code here ...
如果用户创建的查询仅包含度量,则会看到类似于以下内容的出错提示:

异步渲染和 PDF 导出
在前面的“Hello World”示例中,系统会在更新 DOM 后立即调用 done() 函数。这种方法是合适的,因为设置 innerHTML 是同步的。
不过,如果您使用 D3.js、Chart.js 或 React 等图表库,渲染很可能是异步的。如果您在脚本底部调用 done(),Looker 可能会在图表完成绘制之前捕获 PDF 或 PNG 导出的屏幕截图,这可能会导致图块空白。
当 Looker 导出信息中心时,它会使用无头浏览器,并依赖于 done() 回调来了解何时可以安全地截取屏幕截图。
为确保图表正确导出,您必须将 done() 回调与库的完成事件相关联,并在导出期间使用 details.print 标志停用动画。
以下示例展示了如何使用 D3.js 处理异步渲染:
updateAsync: function(data, element, config, queryResponse, details, done) {
this.clearErrors();
// Check if Looker is exporting the chart to a PDF/PNG
const isExport = details && details.print === true;
// Clear previous elements
this.svg.selectAll("*").remove();
const circle = this.svg.append("circle")
.attr("cx", 50)
.attr("cy", 50);
if (isExport) {
// Instant render for exports. Draw the final state immediately with no transitions
circle.attr("r", 40);
// Tell Looker to take the screenshot right now
done();
} else {
// If it's for the browser, start small and animate
circle.attr("r", 0)
.transition()
.duration(1000)
.attr("r", 40)
.on("end", () => {
// Tell Looker the animation is fully complete
done();
});
}
}
如果您使用 React,请确保将 done 回调作为第三个实参传递给渲染函数,以便 Looker 等待 React 装载组件:
this.chart = ReactDOM.render(
<MyCustomChart data={data} />,
element,
done // Looker waits for React to finish
);
配置
您可以允许用户自定义可视化图表的各个方面。
除了可视化图表对象的其他属性之外,还有一个名为 options 的属性。
您可以使用此属性来指定图表需要哪种选项:
looker.plugins.visualizations.add({
options: {
font_size: {
type: "string",
label: "Font Size",
values: [
{"Large": "large"},
{"Small": "small"}
],
display: "radio",
default: "large"
}
},
// ... rest of visualization object ...
此示例创建了一个 font_size 选项,该选项以单选按钮的形式显示,允许用户在“小”和“大”字号之间进行选择。
如需将该选项添加到可视化图表选择器,您必须指定 options 属性。
如需在代码中使用此选项,请注意,在 updateAsync 方法中有一个 config 形参。此形参包含以下所选选项:
updateAsync: function(data, element, config, queryResponse, details, done) {
config 对象类似于以下内容:
{font_size: "large"}
更新图表时,您可以检查此对象并做出相应响应。 在更新方法的末尾添加以下检查,以实现字号更改:
if (config.font_size == "small") {
this._textElement.className = "hello-world-text-small";
} else {
this._textElement.className = "hello-world-text-large";
}
您还应更新在 create 方法中添加的 <style> 标记,以定义
hello-world-text-small 和 hello-world-text-large CSS 类:
.hello-world-text-large {
font-size: 72px;
}
.hello-world-text-small {
font-size: 18px;
}
由于每当配置更改时都会调用 updateAsync 函数,并且 Looker 会自动保存配置,因此您只需执行此操作即可响应配置设置。
后续步骤
您可以在 Looker 开源 GitHub 代码库中查看此 "Hello World" 可视化图表的完整源代码。
如需详细了解其他功能,请参阅 Visualization API 参考文档。