polymer - 在 Polymer 的 <google-chart> Web 组件中使用 "google.visualization.*"对象

标签 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-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/

相关文章:

javascript - jQuery 每个只返回最后一个元素,Google 图表 API

media-queries - Polymer 1.0 dom-if 在之前为 true 时不会重新计算

javascript - Chrome 扩展程序内容脚本中的 polymer 元素

javascript - 带有图例和其他颜色的 Google Charts API 散点图

javascript - Google Charts 如何隐藏值 = 0

r - 通过 GoogleVis 更改工具提示

javascript - 获取模板 if 语句内的节点

dart - 自动将html字符串转换为元素

javascript - vaadin 网格隐藏列

javascript - 如何垂直显示 Google 柱形图 x 轴标签?