在Polymer中的<google-chart> Web组件中使用“google.visualization。*”对象

时间:2017-03-03 22:14:33

标签: polymer google-visualization

是否可以在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>

1 个答案:

答案 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上使用谷歌图表开发团队创建的问题的链接,其中包含一些见解。希望这会有所帮助。