<!DOCTYPE html>
<html>
<head>
<script>document.write('<base href="' + document.location + '" />');</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- IE required polyfills, in this exact order -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
<script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<!-- Angular polyfill required everywhere -->
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2-polyfills.js"></script>
<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-beta.12/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2.dev.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.12/router.dev.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.12/http.dev.js"></script>
<!-- Chart.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
'api': {defaultExtension: 'ts'},
'app': {defaultExtension: 'ts'}
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
</head>
<body>
<app>Loading Demo ...</app>
</body>
</html>
import { bootstrap } from 'angular2/platform/browser';
import { AppComponent } from './component';
bootstrap(AppComponent)
.then(success => console.log(`Bootstrap success`))
.catch(error => console.log(error));
{
"ambientDependencies": {
"es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#6697d6f7dadbf5773cb40ecda35a76027e0783b2"
}
}
import {
Component, OnDestroy, OnInit, OnChanges,
EventEmitter, ElementRef, Input
} from 'angular2/core';
import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass} from 'angular2/common';
declare var Chart:any;
@Component({
selector: 'chart, canvas[chart]',
template: `<canvas></canvas>`,
directives: [CORE_DIRECTIVES, NgClass]
})
export class Charts {
constructor(element:ElementRef) {
}
}
@Component({
selector: 'base-chart',
properties: [
'data',
'labels',
'series',
'colours',
'chartType',
'legend',
'options'
],
events: ['chartClick', 'chartHover'],
template: `
<canvas style="width: 100%; height: 100%;" (click)="click($event)" (mousemove)="hover($event)"></canvas>
`,
directives: [CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass]
})
export class BaseChart implements OnInit, OnDestroy, OnChanges {
@Input() data:Array<any> = [];
@Input() labels:Array<any> = [];
@Input() options:any = {responsive: true};
@Input() chartType:string;
@Input() series:Array<any> = [];
@Input() colours:Array<any> = [];
@Input() legend:boolean;
private ctx:any;
private cvs:any;
private parent:any;
private chart:any;
private legendTemplate:any;
private initFlag:boolean = false;
private chartClick:EventEmitter<any> = new EventEmitter();
private chartHover:EventEmitter<any> = new EventEmitter();
private defaultsColours:Array<any> = [
{
fillColor: 'rgba(151,187,205,0.2)',
strokeColor: 'rgba(151,187,205,1)',
pointColor: 'rgba(151,187,205,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(151,187,205,0.8)',
color: 'rgba(151,187,205,1)',
highlight: 'rgba(151,187,205,0.8)'
}, {
fillColor: 'rgba(220,220,220,0.2)',
strokeColor: 'rgba(220,220,220,1)',
pointColor: 'rgba(220,220,220,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(220,220,220,0.8)',
color: 'rgba(220,220,220,1)',
highlight: 'rgba(220,220,220,0.8)'
}, {
fillColor: 'rgba(247,70,74,0.2)',
strokeColor: 'rgba(247,70,74,1)',
pointColor: 'rgba(247,70,74,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(247,70,74,0.8)',
color: 'rgba(247,70,74,1)',
highlight: 'rgba(247,70,74,0.8)'
}, {
fillColor: 'rgba(70,191,189,0.2)',
strokeColor: 'rgba(70,191,189,1)',
pointColor: 'rgba(70,191,189,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(70,191,189,0.8)',
color: 'rgba(70,191,189,1)',
highlight: 'rgba(70,191,189,0.8)'
}, {
fillColor: 'rgba(253,180,92,0.2)',
strokeColor: 'rgba(253,180,92,1)',
pointColor: 'rgba(253,180,92,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(253,180,92,0.8)',
color: 'rgba(253,180,92,1)',
highlight: 'rgba(253,180,92,0.8)'
}, {
fillColor: 'rgba(148,159,177,0.2)',
strokeColor: 'rgba(148,159,177,1)',
pointColor: 'rgba(148,159,177,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(148,159,177,0.8)',
color: 'rgba(148,159,177,1)',
highlight: 'rgba(148,159,177,0.8)'
}, {
fillColor: 'rgba(77,83,96,0.2)',
strokeColor: 'rgba(77,83,96,1)',
pointColor: 'rgba(77,83,96,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(77,83,96,0.8)',
color: 'rgba(77,83,96,1)',
highlight: 'rgba(77,83,96,0.8)'
}];
constructor(private element:ElementRef) {
}
ngOnInit() {
this.ctx = this.element.nativeElement.children[0].getContext('2d');
this.cvs = this.element.nativeElement.children[0];
this.parent = this.element.nativeElement;
this.refresh();
this.initFlag = true;
}
ngOnChanges(changes) {
if (this.initFlag) {
this.refresh();
}
}
ngOnDestroy() {
if (this.chart) {
this.chart.destroy();
this.chart = null;
}
if (this.legendTemplate) {
this.legendTemplate.destroy();
this.legendTemplate = null;
}
}
setLegend() {
let list = this.parent.getElementsByTagName('ul');
if (list.length) {
list[0].remove();
this.parent.insertAdjacentHTML('beforeend', this.chart.generateLegend());
} else {
this.parent.insertAdjacentHTML('beforeend', this.chart.generateLegend());
}
}
getColour(colour:Array<number>):any {
return {
fillColor: this.rgba(colour, 0.2),
strokeColor: this.rgba(colour, 1),
pointColor: this.rgba(colour, 1),
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: this.rgba(colour, 0.8),
color: this.rgba(colour, 1),
highlight: this.rgba(colour, 0.8)
};
}
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
rgba(colour, alpha) {
return 'rgba(' + colour.concat(alpha).join(',') + ')';
}
public click(evt) {
let atEvent = this.chart.getPointsAtEvent || this.chart.getBarsAtEvent || this.chart.getSegmentsAtEvent;
let activePoints = atEvent.call(this.chart, evt);
if (activePoints.length > 0) {
let activeLabel = activePoints[0].label;
this.chartClick.emit({activePoints: activePoints, activeLabel: activeLabel});
}
}
public hover(evt) {
let atEvent = this.chart.getPointsAtEvent || this.chart.getBarsAtEvent || this.chart.getSegmentsAtEvent;
let activePoints = atEvent.call(this.chart, evt);
if (activePoints.length > 0) {
let activeLabel = activePoints[0].label;
let activePoint = activePoints[0].value;
this.chartHover.emit({activePoints: activePoints, activePoint: activePoint, activeLabel: activeLabel});
}
}
getChartBuilder(ctx:any, data:Array<any>, options:any) {
return new Chart(ctx)[this.chartType](data, options);
}
getDataObject(label:string, value:any):any {
if (this.chartType === 'Line'
|| this.chartType === 'Bar'
|| this.chartType === 'Radar') {
return {
label: label,
data: value
};
}
if (this.chartType === 'Pie'
|| this.chartType === 'Doughnut'
|| this.chartType === 'PolarArea') {
return {
label: label,
value: value
};
}
return null;
}
getChartData(labels:any, dataObject:any) {
if (this.chartType === 'Line'
|| this.chartType === 'Bar'
|| this.chartType === 'Radar') {
return {
labels: labels,
datasets: dataObject
};
}
if (this.chartType === 'Pie'
|| this.chartType === 'Doughnut'
|| this.chartType === 'PolarArea') {
return dataObject;
}
}
private refresh() {
if (this.options.responsive && this.parent.clientHeight === 0) {
return setTimeout(() => this.refresh(), 50);
}
this.ngOnDestroy();
let dataset:Array<any> = [];
for (let i = 0; i < this.data.length; i++) {
let colourDesc:Array<number> = [this.getRandomInt(0, 255), this.getRandomInt(0, 255), this.getRandomInt(0, 255)];
let colour = i < this.colours.length ? this.colours[i] : this.defaultsColours[i] || this.getColour(colourDesc);
let data:any = (<any>Object).assign(colour,
this.getDataObject(this.series[i] || this.labels[i], this.data[i]));
dataset.push(data);
}
let data:any = this.getChartData(this.labels, dataset);
this.chart = this.getChartBuilder(this.ctx, data, this.options);
if (this.legend) {
this.setLegend();
}
}
}
export const CHART_DIRECTIVES:Array<any> = [Charts, BaseChart];
import {Component, EventEmitter} from 'angular2/core';
import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass} from 'angular2/common';
import {CHART_DIRECTIVES} from './../charts.ts';
// webpack html imports
//let template = require('./line-chart-demo.html');
@Component({
selector: 'line-chart-demo',
templateUrl: 'shared/demo/line-chart-demo.html',
directives: [CHART_DIRECTIVES, NgClass, CORE_DIRECTIVES, FORM_DIRECTIVES]
})
export class LineChartDemo {
constructor() {
console.log('line demo');
}
// lineChart
private lineChartData:Array<any> = [
[65, 59, 80, 81, 56, 55, 40],
[28, 48, 40, 19, 86, 27, 90],
[18, 48, 77, 9, 100, 27, 40]
];
private lineChartLabels:Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
private lineChartSeries:Array<any> = ['Series A', 'Series B', 'Series C'];
private lineChartOptions:any = {
animation: false,
responsive: true,
multiTooltipTemplate: '<%if (datasetLabel){%><%=datasetLabel %>: <%}%><%= value %>'
};
private lineChartColours:Array<any> = [
{ // grey
fillColor: 'rgba(148,159,177,0.2)',
strokeColor: 'rgba(148,159,177,1)',
pointColor: 'rgba(148,159,177,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(148,159,177,0.8)'
},
{ // dark grey
fillColor: 'rgba(77,83,96,0.2)',
strokeColor: 'rgba(77,83,96,1)',
pointColor: 'rgba(77,83,96,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(77,83,96,1)'
},
{ // grey
fillColor: 'rgba(148,159,177,0.2)',
strokeColor: 'rgba(148,159,177,1)',
pointColor: 'rgba(148,159,177,1)',
pointStrokeColor: '#fff',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(148,159,177,0.8)'
}
];
private lineChartLegend:boolean = true;
private lineChartType:string = 'Line';
private randomize() {
let _lineChartData = [];
for (let i = 0; i < this.lineChartData.length; i++) {
_lineChartData[i] = [];
for (let j = 0; j < this.lineChartData[i].length; j++) {
_lineChartData[i].push(Math.floor((Math.random() * 100) + 1));
}
}
this.lineChartData = _lineChartData;
}
// events
chartClicked(e:any) {
console.log(e);
}
chartHovered(e:any) {
console.log(e);
}
}
<div>
<div>
<base-chart class="chart"
[data]="lineChartData"
[labels]="lineChartLabels"
[options]="lineChartOptions"
[series]="lineChartSeries"
[colours]="lineChartColours"
[legend]="lineChartLegend"
[chartType]="lineChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></base-chart>
</div>
<div style="margin-bottom: 10px;">
<table class="table table-responsive table-condensed">
<tr>
<th *ngFor="#label of lineChartLabels">{{label}}</th>
</tr>
<tr *ngFor="#d of lineChartData">
<td *ngFor="#label of lineChartLabels; #j=index">{{d && j && d[j]}}</td>
</tr>
</table>
<button (click)="randomize()">CLICK</button>
</div>
</div>
import { Component } from 'angular2/core';
import { LineChartDemo } from './../shared/demo/line-chart-demo.ts';
@Component({
selector: 'app',
directives: [LineChartDemo]
template: `<line-chart-demo></line-chart-demo>`,
styles: [`
line-chart-demo {position: absolute;}
`]
})
export class AppComponent {
}