├── .gitignore ├── src ├── index.ts ├── chart.module.ts └── chart.component.ts ├── .npmignore ├── dev ├── index.html ├── app.ts ├── app.module.ts └── app.component.ts ├── webpack.config.js ├── tsconfig.json ├── CHANGELOG.md ├── LICENSE.txt ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | typings/ 3 | dist/ 4 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chart.component'; 2 | export * from './chart.module'; 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | typings/ 3 | dev/ 4 | src/ 5 | tsconfig.json 6 | webpack.config.js 7 | .npmignore 8 | -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dev/app.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | require('zone.js/dist/zone'); 3 | 4 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 5 | import { AppModule } from './app.module'; 6 | 7 | platformBrowserDynamic().bootstrapModule(AppModule); 8 | -------------------------------------------------------------------------------- /src/chart.module.ts: -------------------------------------------------------------------------------- 1 | if (typeof window === 'object') { 2 | require('chart.js'); 3 | } 4 | import { NgModule } from '@angular/core'; 5 | import { ChartComponent } from './chart.component'; 6 | 7 | @NgModule({ 8 | declarations: [ ChartComponent ], 9 | exports: [ ChartComponent ] 10 | }) 11 | export class ChartModule { 12 | constructor() { } 13 | } 14 | -------------------------------------------------------------------------------- /dev/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | import { ChartModule } from '../src'; 5 | import { AppComponent } from './app.component'; 6 | 7 | @NgModule({ 8 | imports: [ BrowserModule, ChartModule ], 9 | declarations: [ AppComponent ], 10 | bootstrap: [ AppComponent ] 11 | }) 12 | export class AppModule { 13 | constructor() { } 14 | } 15 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require("webpack"); 2 | 3 | var config = { 4 | devtool: 'source-map', 5 | entry: { 6 | main: './dev/app.ts' 7 | }, 8 | resolve: { 9 | extensions: ['', '.ts', '.js'] 10 | }, 11 | output: { 12 | filename: 'bundle.js' 13 | }, 14 | module: { 15 | loaders: [ 16 | { 17 | test: /\.ts$/, 18 | loaders: ['ts'] 19 | } 20 | ] 21 | }, 22 | devServer: { 23 | host: '0.0.0.0', 24 | port: 4200 25 | } 26 | }; 27 | 28 | module.exports = config; 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "es5", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "sourceMap": true, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "removeComments": true, 11 | "noImplicitAny": false, 12 | "declaration": true, 13 | "types": [ 14 | "node" 15 | ], 16 | "lib": [ 17 | "es2017", 18 | "dom" 19 | ] 20 | }, 21 | "files": [ 22 | "src/index.ts" 23 | ], 24 | "exclude": [ 25 | "node_modules", 26 | "dist" 27 | ], 28 | "compileOnSave": false, 29 | "buildOnSave": false, 30 | "angularCompilerOptions": { 31 | "genDir": "dist", 32 | "skipTemplateCodegen": true 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## v0.5.1 / 2018-05-18 4 | ### Improve 5 | - performance 6 | 7 | ## v0.5.0 / 2018-03-17 8 | ### Added 9 | - events `clickCanvas`, `clickDataset`, `clickElements` and `clickElement`. 10 | 11 | ## v0.4.1 / 2017-11-19 12 | ### Fixed 13 | - angular 5 aot build. 14 | 15 | ## v0.4.0 / 2017-11-15 16 | ### Fixed 17 | - `Responsive` seems to be broken when used with chart.js >= 2.7.0 #26 18 | - angular 5 warning. 19 | 20 | ## v0.3.0 / 2017-08-16 21 | ### Changed 22 | - change type and options will re-create chart. 23 | 24 | ## v0.2.0 / 2017-04-07 25 | ### Added 26 | - angular 4 peer dependencies. 27 | 28 | ## v0.1.6 / 2016-11-16 29 | ### Fixed 30 | - issuse #1 for Ionic2. 31 | 32 | ## v0.1.5 / 2016-10-24 33 | ### Added 34 | - exposed chart instance. 35 | 36 | ## v0.1.4 / 2016-10-13 37 | ### Fixed 38 | - dependencies problem in some cases. 39 | 40 | ## v0.1.3 / 2016-10-05 41 | ### Fixed 42 | - typings path in package.json. 43 | 44 | ## v0.1.2 / 2016-10-04 45 | ### Added 46 | - Data change detection. 47 | 48 | ## v0.1.1 / 2016-10-03 49 | ### Added 50 | - First version implementation. 51 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2018 Chen, Yi-Cyuan 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-chartjs", 3 | "version": "0.5.1", 4 | "description": "Chart.js component for Angular2", 5 | "main": "dist/index.js", 6 | "typings": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "rm -rf dist/*;ngc", 9 | "build:demo": "cd dev && ngc", 10 | "prepublish": "npm run build", 11 | "start": "webpack-dev-server --progress --profile --colors --watch --display-error-details --display-cached --content-base dev/" 12 | }, 13 | "peerDependencies": { 14 | "@angular/common": ">=4.0.0 || ^2.0.0", 15 | "@angular/compiler": ">=4.0.0 || ^2.0.0", 16 | "@angular/core": ">=4.0.0 || ^2.0.0" 17 | }, 18 | "dependencies": { 19 | "chart.js": "^2.3.0" 20 | }, 21 | "author": "Chen, Yi-Cyuan ", 22 | "license": "MIT", 23 | "devDependencies": { 24 | "@angular/common": "2.4.10", 25 | "@angular/compiler": "2.4.10", 26 | "@angular/compiler-cli": "2.4.10", 27 | "@angular/core": "2.4.10", 28 | "@angular/platform-browser": "2.4.10", 29 | "@angular/platform-browser-dynamic": "2.4.10", 30 | "@types/chart.js": "^2.6.13", 31 | "@types/core-js": "^0.9.43", 32 | "@types/node": "^8.0.52", 33 | "core-js": "^2.4.1", 34 | "reflect-metadata": "^0.1.8", 35 | "rxjs": "5.4.3", 36 | "ts-loader": "^0.8.2", 37 | "typescript": "^2.0.3", 38 | "webpack": "^1.13.2", 39 | "webpack-dev-server": "^1.16.1", 40 | "zone.js": "0.7.2" 41 | }, 42 | "repository": { 43 | "type": "git", 44 | "url": "https://github.com/emn178/angular2-chartjs.git" 45 | }, 46 | "keywords": [ 47 | "chart", 48 | "angular2" 49 | ], 50 | "homepage": "https://github.com/emn178/angular2-chartjs", 51 | "bugs": { 52 | "url": "https://github.com/emn178/angular2-chartjs/issues" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dev/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | import { ChartComponent } from '../src'; 3 | 4 | @Component({ 5 | selector: 'app', 6 | template: '' 7 | }) 8 | export class AppComponent { 9 | @ViewChild(ChartComponent) chartComponent: ChartComponent; 10 | 11 | type = 'line'; 12 | data = { 13 | labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], 14 | datasets: [ 15 | { 16 | label: 'My First dataset', 17 | data: [65, 59, 80, 81, 56, 55, 40], 18 | backgroundColor: '#FF6384' 19 | }, 20 | { 21 | label: 'My Second dataset', 22 | data: [60, 65, 75, 86, 49, 42, 35], 23 | backgroundColor: '#36A2EB' 24 | } 25 | ] 26 | }; 27 | options = { 28 | responsive: true, 29 | maintainAspectRatio: false, 30 | scales: { 31 | xAxes: [ 32 | { 33 | stacked: true 34 | } 35 | ], 36 | yAxes: [ 37 | { 38 | stacked: true 39 | } 40 | ] 41 | } 42 | }; 43 | 44 | constructor() { 45 | } 46 | 47 | change() { 48 | this.type = 'bar'; 49 | this.data = { 50 | labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], 51 | datasets: [ 52 | { 53 | label: 'My First dataset', 54 | data: [65, 59, 80, 81, 56, 55, 40], 55 | backgroundColor: '#FF6384' 56 | }, 57 | { 58 | label: 'My Second dataset', 59 | data: [10, 30, 20, 40, 60, 50, 70], 60 | backgroundColor: '#36A2EB' 61 | }, 62 | { 63 | label: 'My Third dataset', 64 | data: [35, 59, 50, 61, 76, 46, 35], 65 | backgroundColor: '#FFCE56' 66 | } 67 | ] 68 | }; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/chart.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ElementRef, OnInit, OnChanges, SimpleChanges, Output, EventEmitter, NgZone } from '@angular/core'; 2 | 3 | declare var Chart; 4 | 5 | @Component({ 6 | selector: 'chart', 7 | template: '', 8 | styles: [':host { display: block; }'] 9 | }) 10 | export class ChartComponent implements OnInit, OnChanges { 11 | chart: any; 12 | 13 | @Input() type: string; 14 | @Input() data: any; 15 | @Input() options: any; 16 | @Output() clickCanvas = new EventEmitter(); 17 | @Output() clickDataset = new EventEmitter(); 18 | @Output() clickElements = new EventEmitter(); 19 | @Output() clickElement = new EventEmitter(); 20 | 21 | private canvas; 22 | 23 | constructor(private elementRef: ElementRef, private ngZone: NgZone) { } 24 | 25 | ngOnInit() { 26 | this.create(); 27 | } 28 | 29 | ngOnChanges(changes: SimpleChanges) { 30 | if (this.chart) { 31 | if (changes['type'] || changes['options']) { 32 | this.create(); 33 | } else if (changes['data']) { 34 | let currentValue = changes['data'].currentValue; 35 | ['datasets', 'labels', 'xLabels', 'yLabels'].forEach(property => { 36 | this.chart.data[property] = currentValue[property]; 37 | }) 38 | this.chart.update(); 39 | } 40 | } 41 | } 42 | 43 | private create() { 44 | this.ngZone.runOutsideAngular(() => { 45 | if (this.canvas) { 46 | this.elementRef.nativeElement.removeChild(this.canvas); 47 | } 48 | this.canvas = document.createElement('canvas'); 49 | this.elementRef.nativeElement.appendChild(this.canvas); 50 | this.chart = new Chart(this.canvas, { 51 | type: this.type, 52 | data: this.data, 53 | options: this.options 54 | }); 55 | this.canvas.onclick = e => { 56 | this.ngZone.run(() => { 57 | this.clickCanvas.next(e); 58 | if (this.clickDataset.observers.length) { 59 | this.clickDataset.next(this.chart.getDatasetAtEvent(e)); 60 | } 61 | if (this.clickElements.observers.length) { 62 | this.clickElements.next(this.chart.getElementsAtEvent(e)); 63 | } 64 | if (this.clickElement.observers.length) { 65 | this.clickElement.next(this.chart.getElementAtEvent(e)); 66 | } 67 | }); 68 | }; 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular2-chartjs 2 | Chart.js component for Angular2+ 3 | 4 | ## Installation 5 | You can install angular2-chartjs by using npm. 6 | ``` 7 | npm install angular2-chartjs 8 | ``` 9 | 10 | ## Usage 11 | Add `ChartModule` to your module, eg. 12 | ```JavaScript 13 | import { ChartModule } from 'angular2-chartjs'; 14 | 15 | @NgModule({ 16 | imports: [ ChartModule ] 17 | // ... 18 | }) 19 | export class AppModule { 20 | } 21 | ``` 22 | And you can use selector `chart` in your template. 23 | 24 | JavaScript 25 | ```JavaScript 26 | type = 'line'; 27 | data = { 28 | labels: ["January", "February", "March", "April", "May", "June", "July"], 29 | datasets: [ 30 | { 31 | label: "My First dataset", 32 | data: [65, 59, 80, 81, 56, 55, 40] 33 | } 34 | ] 35 | }; 36 | options = { 37 | responsive: true, 38 | maintainAspectRatio: false 39 | }; 40 | ``` 41 | HTML 42 | ```HTML 43 | 44 | ``` 45 | 46 | ## Options 47 | ### [type] 48 | *string*, required 49 | Chart type. 50 | 51 | ### [data] 52 | *object*, required 53 | To display data, the chart must be passed a data object that contains all of the information needed by the chart. [See](http://www.chartjs.org/docs/#chart-configuration-chart-data). 54 | 55 | ### [options] 56 | *object*, optional 57 | To create a chart with configuration options, simply pass an object containing your configuration to the constructor. [See](http://www.chartjs.org/docs/#chart-configuration-creating-a-chart-with-options). 58 | 59 | ## Events 60 | ### (clickCanvas) 61 | *Event* 62 | Return click event. 63 | 64 | ### (clickDataset) 65 | *Array* 66 | Return the clicked dataset array. 67 | 68 | ### (clickElement) 69 | *Array* 70 | Return the clicked element in array. 71 | 72 | ### (clickElements) 73 | *Array* 74 | Return the clicked elements in array. 75 | 76 | ## Members 77 | ### chart 78 | *Chart* 79 | Chart instance. You can call Chart.js methods via this member. 80 | 81 | Example: 82 | ```JavaScript 83 | chartComponent.chart.destroy(); 84 | ``` 85 | 86 | ## SystemJs 87 | Add following settings 88 | ```JavaScript 89 | { 90 | map: { 91 | 'angular2-chartjs': 'npm:angular2-chartjs', 92 | 'chart.js': 'npm:chart.js/dist/Chart.bundle.js' 93 | }, 94 | packages: { 95 | 'angular2-chartjs': { 96 | main: './dist/index.js', 97 | defaultExtension: 'js' 98 | } 99 | } 100 | } 101 | ``` 102 | 103 | ## FAQ 104 | How to call Chart.js methods - [#7](https://github.com/emn178/angular2-chartjs/issues/7), [#2](https://github.com/emn178/angular2-chartjs/issues/2) 105 | 106 | ## License 107 | The project is released under the [MIT license](http://www.opensource.org/licenses/MIT). 108 | 109 | ## Contact 110 | The project's website is located at https://github.com/emn178/angular2-chartjs 111 | Author: Chen, Yi-Cyuan (emn178@gmail.com) 112 | --------------------------------------------------------------------------------