是否可以在 Google Polymer 组件中使用 google.visualization.* 包中的核心 Google 图表对象(例如 DataTable 或事件)?
我有一个返回 JSON 数据的 Web 服务,我想将其转换为 DataTable。我收到的错误消息是“无法读取未定义的属性‘DataTable’”
来自这篇文章Google Visualization - TypeError: Cannot read property 'DataTable' of undefined [Chrome specific]我知道这可能是脚本加载问题,但如何控制 google-chart 脚本在 Polymer 中加载的方式?
下面是我的定制 polymer 事件
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../bower_components/google-chart/google-chart.html">
<dom-module id="dash-chart">
<template>
<style type="text/css">
.google-chart-style {
width: 100%;
height: 90%;
}
.google-chart-class {
width:100%;
height:90%;
}
</style>
<iron-ajax
auto
url={{url}}
handle-as="json"
on-response="handleResponse">
</iron-ajax>
<google-chart
class="google-chart-class"
id="myChart"
type={{type}}
options={{options}}>
</google-chart>
</template>
<script>
Polymer({
is: "dash-chart",
properties : {
url: String,
type: String,
options: Object,
data: Array,
xaxis: Array,
yaxis: Array,
fields: Array
},
convertResultsToDatatable: function(response) {
console.log(response);
//DataTable object
var objDataTable = new google.visualization.DataTable();
objDataTable.addColumn(this.xaxis[1], this.xaxis[2]);
objDataTable.addColumn(this.yaxis[1], this.yaxis[2]);
var afterConversionToDatatable = [[]];
for(var index in response) {
var objVal = response[index];
var arr = [];
for(var key in objVal) {
if(key === this.xaxis[0]) {
if(this.xaxis[1] === 'number') {
arr.push(parseInt(objVal[key]));
} else {
arr.push(objVal[key]);
}
} else if (key === this.yaxis[0]) {
if(this.yaxis[1] === 'number') {
arr.push(parseInt(objVal[key]));
} else {
arr.push(objVal[key]);
}
}
}
afterConversionToDatatable[index] = arr;
}
console.log(afterConversionToDatatable);
objDataTable.addRows(afterConversionToDatatable);
return objDataTable;
},
handleResponse: function(data) {
var rootKey;
var jsonResult = data.detail.response;
for(var prop in jsonResult) {
rootKey = prop;
}
//Done so that we do not need to hard code the root object (which changes based with every roxie query)
var resultNode = jsonResult[rootKey].Results.result_1.Row;
this.data = this.convertResultsToDatatable(resultNode);
}
});
</script>
</dom-module>
最佳答案
我让这个工作了。首先要了解的是,一旦库完全加载,您就可以使用 google.visualization.* 包中的任何类。就我而言,如果 <iron-ajax>
则库将正确加载。通话耗时超过 5 秒才完成。如果它小于我会收到错误:“无法读取未定义的属性'DataTable'”。
为了解决这个加载问题,我必须编写一个 Observer 方法,保证仅在设置属性后才调用该方法。关键是用 <iron-ajax>
调用观察者响应和 google-chart 的 type
属性集。
请注意,我尝试使用 polymer 生命周期方法(ready、attached、attributeChanged)并设置 <iron-ajax>
调用auto
,但没有成功。
在我的示例中,我设置 google-chart
来自另一种定制 polymer 成分的特性。
<dom-module id="poly-chart">
<template>
<style type="text/css">
:host {
--overlay-opacity
--overlay-zindex
--overlay-display
}
.google-chart-class {
width:100%;
height:90%;
opacity: var(--overlay-opacity, 1);
z-index: var(--overlay-zindex);
}
</style>
<iron-ajax
id={{id}}_ajx
url={{url}}
handle-as="json"
on-response="handleResponse">
</iron-ajax>
<google-chart
class="google-chart-class"
id={{id}}
type={{type}}
options={{options}}
on-google-chart-ready='chartLoaded'>
</google-chart>
</template>
<script>
Polymer({
is: "poly-chart",
properties : {
id: String,
url: String,
type: String,
options: Object,
fields: Array,
inputparams: String,
ajaxResponse: Object
},
observers: [
'ajaxCall(id, url, inputparams)',
'afterAjaxResponse(type, ajaxResponse, fields, id)'],
ajaxCall: function(id, url, inputparams){
var ajx = document.querySelector('iron-ajax#'+id+"_ajx");
ajx.generateRequest();
},
handleResponse: function(data) {
var rootKey;
var jsonResult = data.detail.response;
for(var prop in jsonResult) {
rootKey = prop;
}
var resultNode = jsonResult[rootKey].Results.result_1.Row;
if(resultNode.length === 0) {
this.loading = false;
}
this.ajaxResponse = resultNode;
},
afterAjaxResponse: function(chartType,ajaxResponse, fields, id) {
var loader = document.querySelector('#loader');
loader.dataTable(null)
.then(dt => {
return dt;
})
.then(function(dt){
fields.forEach(function(element) {
dt.addColumn(element.type, element.label);
});
var dtRows = convertTo2DArray(ajaxResponse, getFields(fields));
dt.addRows(dtRows);
var gc = document.querySelector('google-chart#'+id);
gc.data = dt;
})
.catch(function(error){
console.error(error);
});
}
});
</script>
调用 Polymer 元素如下所示:
<dom-module id="poly-widget">
<template>
<style>
.widgetHolderDiv {
width: 100%;
height: 100%;
}
</style>
<div class="widgetHolderDiv">
<poly-header title={{title}}></poly-header>
<poly-chart id={{id}}
type={{type}}
url={{url}}
options={{options}}
fields={{fields}}
inputparams={{inputparams}}>
</poly-chart>
</div>
</template>
<script type="text/javascript">
Polymer({
is: "poly-widget",
properties: {
id: String,
title: String,
url: String,
type: String,
options: Object,
fields: Array,
inputparams: String
}
});
</script>
仅供引用:这是我与 google-chart 开发团队在 github 上创建的问题的链接 https://github.com/GoogleWebComponents/google-chart/issues/182其中有一些见解。希望这会有所帮助。
关于polymer - 在 Polymer 的 <google-chart> Web 组件中使用 "google.visualization.*"对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42589358/