是否可以在Google Polymer组件中使用 google.visualization。* 包中的核心Google图表对象(如DataTable或事件)?
我有一个返回JSON数据的web服务,我想将其转换为DataTable。我得到的错误消息是“无法读取未定义的属性'DataTable'”
从这篇文章Google Visualization - TypeError: Cannot read property 'DataTable' of undefined [Chrome specific]我了解到它可能是一个脚本加载问题,但我如何控制在Google聚合物中加载谷歌图表脚本的方式?
我的自定义聚合物事件在
之下
<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>
答案 0 :(得分:1)
我让这个工作。首先要理解的是,一旦完全加载库,您就可以使用 google.visualization。* 包中的任何类。在我的情况下,如果<iron-ajax>
调用完成时间超过5秒,则库将正确加载。如果它小于我会得到错误:“无法读取属性'DataTable'未定义”。
为了解决这个加载问题,我不得不编写一个Observer方法,保证只有在设置了属性后才能调用它。关键是通过<iron-ajax>
响应和谷歌图表的type
属性集来调用观察者。
请注意,我尝试使用聚合物生命周期方法(ready,attach,attributeChanged)并将<iron-ajax>
调用设置为auto
,但它无效。
在我的示例中,我从另一个自定义聚合物组件设置google-chart
属性。
<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>
仅供参考:以下是我在github https://github.com/GoogleWebComponents/google-chart/issues/182上使用谷歌图表开发团队创建的问题的链接,其中包含一些见解。希望这会有所帮助。