Google 图表 (jsapi) 到 angular2 组件
Google charts (jsapi) into angular2 component
我正在努力创建一个 angular2 组件,它会调用 google 图表 api 并显示 google-图表 (https://developers.google.com/chart/interactive/docs/quick_start)。这通常会导致无法解释的错误或浏览器永远加载。
编辑:在下面添加了完整的更新测试文件
另见 plnkr here。
更具体地说,这些是我用来确定事情开始出错的点的测试文件:
index.html
<html>
<head>
<title>Angular 2 QuickStart</title>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.46/angular2.dev.js"> </script>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true }
});
System.import('./app.ts');
</script>
</head>
<body>
<my-app>loading...</my-app>
</body>
</html>
然后,app.ts
import {bootstrap, Component} from 'angular2/angular2';
@Component({
selector: 'my-app',
template:`
<h1>Demo component my-app</h1>
<div id="cc" (click)="test($event)">Click me</div>
`
})
class AppComponent {
constructor() {
console.log("Constructor was called");
}
test(event) {
console.log("Event :",event);
console.log("Test :", google);
console.log("Document object by id",document.getElementById("cc"));
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
console.log("Callback is entered ");
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('cc'));
chart.draw(data, options);
}
console.log("Google object : ", google);
console.log("Now, loading visualization api");
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
console.log("Now, setting callback");
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
console.log("Callback was set");
}
}
bootstrap(AppComponent);
这是控制台显示的内容,当我单击时:
Constructor was called
app.ts:18 Event : MouseEvent {isTrusted: true}
app.ts:19 Test : Object {loader: Object}
app.ts:20 Document object by id <div id="cc">Click me</div>
app.ts:53 Google object : Object {loader: Object}
app.ts:54 Now, loading visualization api
app.ts:57 Now, setting callback
app.ts:60 Callback was set
显然,回调永远不会进入 ?!
谁能帮我解决这个问题?非常感谢!
我在尝试将 google 图表实施到 ionic2 中时遇到了同样的问题。我不确定到底是什么问题,但似乎
google.load('visualization', '1.0', {'packages':['corechart']});
加载时间过长
google.setOnLoadCallback(drawChart);
永远不会执行。您可以通过将回调直接添加到 google.load() 来绕过此问题,如下所示:
google.load('visualization', '1.0', {'packages':['corechart'], callback: drawChart});
对我有用!并且图表正在根据需要加载。此解决方案的所有功劳归功于@davidkonrad:
希望有用!
最后,通过使用图表组件调用图表指令解决了这个问题。该指令的 setter 触发绘图。不再需要直接 capture/manage 绘图事件。
从顶部 index.html 文件加载 google 脚本
<script type="text/javascript" src="https://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load('visualization', '1.0', {
'packages': ['corechart']
});
</script>
创建一个 "chart" 指令来绘制 google 图表 (chart.directive.ts)
/**
* This directive will draw a chart from the array of records provided
*
* Note : the relevant jsapi scripts should be already available
* globally in the window.google object (see index.html)
**/
import {Directive, ElementRef, Input} from "angular2/core";
import {CORE_DIRECTIVES } from "angular2/common";
@Directive({
selector: "chart",
})
export class ChartDirective {
el: HTMLElement;
w: any; // To store the window, without generating errors in typescript on window.google
private _content: any[] = [];
// Setter for content will trigger drawing (or refreshing)
@Input()
set content(c: any[]) {
console.log("Setting content ...");
this._content = c;
this.draw();
}
get content() { return this._content; }
// Constructor inject a ref to the element
constructor(elementRef: ElementRef) {
console.log("Constructing chart directive");
this.w = window;
this.el = elementRef.nativeElement; // You cannot use elementRef directly !
// console.log("Native HTML :", this.el);
if (!this.w.google) { console.error("Hey ! It seems the needed google script was not loaded ?"); };
}
// Do the actual drawing
draw() {
// Create the data table.
let data = new this.w.google.visualization.DataTable();
data.addColumn("date", "Quand");
data.addColumn("number", "KG");
let rows = [];
for (let c in this._content) {
let d: Date = new Date(this._content[c].quand);
let k: number = +(this._content[c].kg); // Plus sign to force conversion sting -> number
// Only take into account records after the 'notBefore date'
if (d >= this._nbd) rows.push([d, k]);
}
data.addRows(rows);
// Create options
let options: any = {
// "width": 600,
"height": 300,
"curveType": "function"
};
// Instantiate and draw our chart, passing in some options.
(new this.w.google.visualization.LineChart(this.el))
.draw(data, options);
}
}
在图表组件中使用指令 (chart.component) ...
import {Component } from "angular2/core";
import {CORE_DIRECTIVES } from "angular2/common";
import {MyModel} from "./mymodel.service.ts";
import {ChartDirective} from "./chart.directive.ts";
@Component({
selector: "chartPage",
templateUrl: "/components/chart.template.html",
directives: [CORE_DIRECTIVES, ChartDirective]
})
export class ChartComponent {
}
// Injecting my data model into chart component ...
constructor(private model: MyModel) {
console.log("Constructing chart component");
};
}
...使用以下图表模板
<chart [content]="model.content" ></chart>
我正在努力创建一个 angular2 组件,它会调用 google 图表 api 并显示 google-图表 (https://developers.google.com/chart/interactive/docs/quick_start)。这通常会导致无法解释的错误或浏览器永远加载。
编辑:在下面添加了完整的更新测试文件
另见 plnkr here。
更具体地说,这些是我用来确定事情开始出错的点的测试文件:
index.html
<html>
<head>
<title>Angular 2 QuickStart</title>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.46/angular2.dev.js"> </script>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true }
});
System.import('./app.ts');
</script>
</head>
<body>
<my-app>loading...</my-app>
</body>
</html>
然后,app.ts
import {bootstrap, Component} from 'angular2/angular2';
@Component({
selector: 'my-app',
template:`
<h1>Demo component my-app</h1>
<div id="cc" (click)="test($event)">Click me</div>
`
})
class AppComponent {
constructor() {
console.log("Constructor was called");
}
test(event) {
console.log("Event :",event);
console.log("Test :", google);
console.log("Document object by id",document.getElementById("cc"));
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
console.log("Callback is entered ");
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('cc'));
chart.draw(data, options);
}
console.log("Google object : ", google);
console.log("Now, loading visualization api");
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
console.log("Now, setting callback");
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
console.log("Callback was set");
}
}
bootstrap(AppComponent);
这是控制台显示的内容,当我单击时:
Constructor was called
app.ts:18 Event : MouseEvent {isTrusted: true}
app.ts:19 Test : Object {loader: Object}
app.ts:20 Document object by id <div id="cc">Click me</div>
app.ts:53 Google object : Object {loader: Object}
app.ts:54 Now, loading visualization api
app.ts:57 Now, setting callback
app.ts:60 Callback was set
显然,回调永远不会进入 ?!
谁能帮我解决这个问题?非常感谢!
我在尝试将 google 图表实施到 ionic2 中时遇到了同样的问题。我不确定到底是什么问题,但似乎
google.load('visualization', '1.0', {'packages':['corechart']});
加载时间过长
google.setOnLoadCallback(drawChart);
永远不会执行。您可以通过将回调直接添加到 google.load() 来绕过此问题,如下所示:
google.load('visualization', '1.0', {'packages':['corechart'], callback: drawChart});
对我有用!并且图表正在根据需要加载。此解决方案的所有功劳归功于@davidkonrad:
希望有用!
最后,通过使用图表组件调用图表指令解决了这个问题。该指令的 setter 触发绘图。不再需要直接 capture/manage 绘图事件。
从顶部 index.html 文件加载 google 脚本
<script type="text/javascript" src="https://www.google.com/jsapi"> </script> <script type="text/javascript"> google.load('visualization', '1.0', { 'packages': ['corechart'] }); </script>
创建一个 "chart" 指令来绘制 google 图表 (chart.directive.ts)
/** * This directive will draw a chart from the array of records provided * * Note : the relevant jsapi scripts should be already available * globally in the window.google object (see index.html) **/ import {Directive, ElementRef, Input} from "angular2/core"; import {CORE_DIRECTIVES } from "angular2/common"; @Directive({ selector: "chart", }) export class ChartDirective { el: HTMLElement; w: any; // To store the window, without generating errors in typescript on window.google private _content: any[] = []; // Setter for content will trigger drawing (or refreshing) @Input() set content(c: any[]) { console.log("Setting content ..."); this._content = c; this.draw(); } get content() { return this._content; } // Constructor inject a ref to the element constructor(elementRef: ElementRef) { console.log("Constructing chart directive"); this.w = window; this.el = elementRef.nativeElement; // You cannot use elementRef directly ! // console.log("Native HTML :", this.el); if (!this.w.google) { console.error("Hey ! It seems the needed google script was not loaded ?"); }; } // Do the actual drawing draw() { // Create the data table. let data = new this.w.google.visualization.DataTable(); data.addColumn("date", "Quand"); data.addColumn("number", "KG"); let rows = []; for (let c in this._content) { let d: Date = new Date(this._content[c].quand); let k: number = +(this._content[c].kg); // Plus sign to force conversion sting -> number // Only take into account records after the 'notBefore date' if (d >= this._nbd) rows.push([d, k]); } data.addRows(rows); // Create options let options: any = { // "width": 600, "height": 300, "curveType": "function" }; // Instantiate and draw our chart, passing in some options. (new this.w.google.visualization.LineChart(this.el)) .draw(data, options); }
}
在图表组件中使用指令 (chart.component) ...
import {Component } from "angular2/core"; import {CORE_DIRECTIVES } from "angular2/common"; import {MyModel} from "./mymodel.service.ts"; import {ChartDirective} from "./chart.directive.ts"; @Component({ selector: "chartPage", templateUrl: "/components/chart.template.html", directives: [CORE_DIRECTIVES, ChartDirective] }) export class ChartComponent { } // Injecting my data model into chart component ... constructor(private model: MyModel) { console.log("Constructing chart component"); };
}
...使用以下图表模板
<chart [content]="model.content" ></chart>