├── .angular-cli.json ├── .gitignore ├── README.md ├── license ├── package.json ├── src ├── app │ ├── about │ │ ├── about.component.html │ │ └── about.component.ts │ ├── app.component.html │ ├── app.component.ts │ ├── app.module.ts │ ├── app.router.ts │ ├── chart │ │ ├── chart.component.html │ │ ├── chart.component.ts │ │ └── stock-data.ts │ ├── main.ts │ ├── menu │ │ ├── menu.component.html │ │ └── menu.component.ts │ └── stock-data.ts ├── assets │ ├── images │ │ ├── About-Normal.svg │ │ ├── About-Selection.svg │ │ ├── Analysis-Normal.svg │ │ ├── Analysis-Selection.svg │ │ ├── Information.svg │ │ ├── Stock_Analysis.png │ │ ├── fonts │ │ │ ├── Expense-Analysis-Sample.eot │ │ │ ├── Expense-Analysis-Sample.svg │ │ │ ├── Expense-Analysis-Sample.ttf │ │ │ ├── Expense-Analysis-Sample.woff │ │ │ ├── controls.eot │ │ │ ├── controls.svg │ │ │ ├── controls.ttf │ │ │ ├── controls.woff │ │ │ ├── icons.eot │ │ │ ├── icons.svg │ │ │ ├── icons.ttf │ │ │ └── icons.woff │ │ └── sb-icons │ │ │ ├── Syncfusion-logo.svg │ │ │ ├── Syncfusion-mobile-logo.svg │ │ │ ├── fonts │ │ │ ├── icons.eot │ │ │ ├── icons.svg │ │ │ ├── icons.ttf │ │ │ └── icons.woff │ │ │ ├── new-light.svg │ │ │ ├── preview-light.svg │ │ │ └── updated-light.svg │ ├── index.css │ └── index.scss ├── environments │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── styles.css ├── test.ts ├── tsconfig.app.json └── tsconfig.spec.json ├── tsconfig-aot.json └── tsconfig.json /.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "ej2-ng-stock-chart" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.css" 23 | ], 24 | "scripts": [], 25 | "environmentSource": "environments/environment.ts", 26 | "environments": { 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "e2e": { 33 | "protractor": { 34 | "config": "./protractor.conf.js" 35 | } 36 | }, 37 | "lint": [ 38 | { 39 | "project": "src/tsconfig.app.json", 40 | "exclude": "**/node_modules/**" 41 | }, 42 | { 43 | "project": "src/tsconfig.spec.json", 44 | "exclude": "**/node_modules/**" 45 | }, 46 | { 47 | "project": "e2e/tsconfig.e2e.json", 48 | "exclude": "**/node_modules/**" 49 | } 50 | ], 51 | "test": { 52 | "karma": { 53 | "config": "./karma.conf.js" 54 | } 55 | }, 56 | "defaults": { 57 | "styleExt": "css", 58 | "component": {} 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | *d.ts 3 | *.map 4 | .vscode/ 5 | src/**/*.js 6 | *.ngstyle.ts 7 | src/**/*.map 8 | node_modules/ 9 | npm-debug.log 10 | *ngfactory.ts 11 | *metadata.json 12 | *ngsummary.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Essential JS 2 for Angular - Stock Chart 2 | 3 | This Stock Chart demo application showcases the usage of Chart and Range Navigator in a real world application scenario. You can use this application to track and visualize stock price of any company over a specific period using charting and range tools 4 | 5 | ## Deployment 6 | 7 | ### Install 8 | 9 | To install all dependent packages, use the below command 10 | 11 | ``` 12 | npm install 13 | ``` 14 | 15 | ### Run 16 | 17 | To run the sample, use the below command 18 | 19 | ``` 20 | ng serve 21 | ``` 22 | 23 | ## Demo 24 | 25 | #### https://ej2.syncfusion.com/showcase/angular/stockchart/ 26 | 27 | Check all the showcase samples from here. -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | Essential JS 2 library is available under the Syncfusion Essential Studio program, and can be licensed either under the Syncfusion Community License Program or the Syncfusion commercial license. 2 | 3 | To be qualified for the Syncfusion Community License Program you must have a gross revenue of less than one (1) million U.S. dollars ($1,000,000.00 USD) per year and have less than five (5) developers in your organization, and agree to be bound by Syncfusion’s terms and conditions. 4 | 5 | Customers who do not qualify for the community license can contact sales@syncfusion.com for commercial licensing options. 6 | 7 | Under no circumstances can you use this product without (1) either a Community License or a commercial license and (2) without agreeing and abiding by Syncfusion’s license containing all terms and conditions. 8 | 9 | The Syncfusion license that contains the terms and conditions can be found at 10 | https://www.syncfusion.com/content/downloads/syncfusion_license.pdf -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@syncfusion/ej2-ng-stock-chart", 3 | "version": "0.0.1", 4 | "description": "Essential JS 2 for Angular - Stock Chart application", 5 | "author": "Syncfusion Inc.", 6 | "license": "SEE LICENSE IN license", 7 | "dependencies": { 8 | "rxjs": "^5.0.1", 9 | "tslint": "4.0.2", 10 | "zone.js": "^0.8.4", 11 | "core-js": "^2.4.1", 12 | "systemjs": "^0.19.40", 13 | "gulp-print": "^2.0.1", 14 | "gulp-tslint": "^7.0.1", 15 | "browser-sync": "2.11.2", 16 | "gulp-sass-lint": "^1.1.1", 17 | "reflect-metadata": "^0.1.9", 18 | "tslint-microsoft-contrib": "^4.0.0", 19 | "@angular/core": "10.2.5", 20 | "@angular/http": "~5.0.0", 21 | "@angular/forms": "~5.0.0", 22 | "@angular/router": "^5.0.0", 23 | "@angular/common": "~5.0.0", 24 | "@angular-devkit/core": "^0.4.5", 25 | "@angular/upgrade": "^5.0.0", 26 | "@angular/compiler": "~5.0.0", 27 | "@angular/platform-browser": "~5.0.0", 28 | "@angular/platform-browser-dynamic": "~5.0.0", 29 | "@syncfusion/ej2-ng-base": "*", 30 | "@syncfusion/ej2-ng-charts": "*", 31 | "@syncfusion/ej2-ng-popups": "*", 32 | "request": "3.0.0", 33 | "minimist": "1.2.6", 34 | "ua-parser-js": "0.7.33", 35 | "debug": "2.6.9", 36 | "ms": "2.0.0", 37 | "json5": "1.0.2", 38 | "qs": "6.5.3", 39 | "decode-uri-component": ">=0.2.1", 40 | "engine.io": ">=3.6.1", 41 | "socket.io-parser": ">=3.3.3", 42 | "loader-utils": ">=1.4.1", 43 | "minimatch": ">=3.0.5", 44 | "got": ">=11.8.5", 45 | "async": ">=2.6.4", 46 | "eventsource": ">=1.1.1", 47 | "ejs": ">=3.1.7", 48 | "axios": ">=0.21.2", 49 | "ansi-regex": ">=3.0.1", 50 | "node-forge": ">=1.3.0", 51 | "url-parse": ">=1.5.9", 52 | "follow-redirects": ">=1.14.8", 53 | "node-sass": ">=7.0.0", 54 | "shelljs": ">=0.8.5", 55 | "json-schema": ">=0.4.0", 56 | "set-value": ">=2.0.1", 57 | "jsonpointer": ">=5.0.0", 58 | "object-path": ">=0.11.8", 59 | "tar": ">=4.4.18", 60 | "path-parse": ">=1.0.7", 61 | "dns-packet": ">=1.3.2", 62 | "xmlhttprequest-ssl": ">=1.6.2", 63 | "chownr": ">=1.1.0", 64 | "ajv": ">=6.12.3", 65 | "hosted-git-info": ">=2.8.9", 66 | "sockjs": ">=0.3.20", 67 | "lodash": ">=4.17.21", 68 | "underscore": ">=1.12.1", 69 | "braces": ">=2.3.1", 70 | "merge": ">=2.1.1", 71 | "y18n": ">=4.0.1", 72 | "elliptic": ">=6.5.4", 73 | "socket.io": ">=2.4.0", 74 | "ini": ">=1.3.6", 75 | "yargs-parser": ">=13.1.2", 76 | "webpack-subresource-integrity": ">=1.5.1", 77 | "http-proxy": ">=1.18.1", 78 | "tree-kill": ">=1.2.2", 79 | "lodash.mergewith": ">=4.6.2", 80 | "lodash.merge": ">=4.6.2", 81 | "connect": ">=2.8.1", 82 | "dot-prop": ">=4.2.1", 83 | "serialize-javascript": ">=3.1.0", 84 | "acorn": ">=5.7.4", 85 | "ws": ">=1.1.5", 86 | "mixin-deep": ">=1.3.2", 87 | "underscore.string": ">=3.3.5", 88 | "js-yaml": ">=3.13.1", 89 | "fstream": ">=1.0.12", 90 | "engine.io-client": ">=1.6.9", 91 | "webpack-dev-server": ">=3.1.11", 92 | "express": ">=3.11.0", 93 | "negotiator": ">=0.6.1", 94 | "parsejson": "0.0.4", 95 | "fresh": ">=0.5.2", 96 | "mime": ">=1.4.1", 97 | "hoek": ">=4.2.1" 98 | }, 99 | "devDependencies": { 100 | "@angular/cli": "1.5.6", 101 | "@angular/compiler-cli": "5.0.0", 102 | "@angular/platform-server": "5.0.0", 103 | "@types/jasmine": "^2.2.29", 104 | "@types/requirejs": "^2.1.26", 105 | "@types/node": "^6.0.46", 106 | "gulp": "^3.9.0", 107 | "webpack": "2.5.1", 108 | "shelljs": ">=0.8.5", 109 | "typescript": "~2.4.2", 110 | "gulp-sass": "^3.1.0", 111 | "gulp-clean": "^0.3.2", 112 | "run-sequence": "2.2.0", 113 | "webpack-stream": "^3.2.0", 114 | "karma-systemjs": "^0.16.0", 115 | "gulp-typescript": "^2.13.0", 116 | "es6-module-loader": "^0.17.11", 117 | "systemjs-plugin-babel": "0.0.17", 118 | "decode-uri-component": ">=0.2.1", 119 | "engine.io": ">=3.6.1", 120 | "socket.io-parser": ">=3.3.3", 121 | "loader-utils": ">=1.4.1", 122 | "minimatch": ">=3.0.5", 123 | "got": ">=11.8.5", 124 | "async": ">=2.6.4", 125 | "eventsource": ">=1.1.1", 126 | "ejs": ">=3.1.7", 127 | "axios": ">=0.21.2", 128 | "ansi-regex": ">=3.0.1", 129 | "node-forge": ">=1.3.0", 130 | "url-parse": ">=1.5.9", 131 | "follow-redirects": ">=1.14.8", 132 | "node-sass": ">=7.0.0", 133 | "json-schema": ">=0.4.0", 134 | "set-value": ">=2.0.1", 135 | "jsonpointer": ">=5.0.0", 136 | "object-path": ">=0.11.8", 137 | "tar": ">=4.4.18", 138 | "path-parse": ">=1.0.7", 139 | "dns-packet": ">=1.3.2", 140 | "xmlhttprequest-ssl": ">=1.6.2", 141 | "chownr": ">=1.1.0", 142 | "ajv": ">=6.12.3", 143 | "hosted-git-info": ">=2.8.9", 144 | "sockjs": ">=0.3.20", 145 | "lodash": ">=4.17.21", 146 | "underscore": ">=1.12.1", 147 | "braces": ">=2.3.1", 148 | "merge": ">=2.1.1", 149 | "y18n": ">=4.0.1", 150 | "elliptic": ">=6.5.4", 151 | "socket.io": ">=2.4.0", 152 | "ini": ">=1.3.6", 153 | "yargs-parser": ">=13.1.2", 154 | "webpack-subresource-integrity": ">=1.5.1", 155 | "http-proxy": ">=1.18.1", 156 | "tree-kill": ">=1.2.2", 157 | "lodash.mergewith": ">=4.6.2", 158 | "lodash.merge": ">=4.6.2", 159 | "connect": ">=2.8.1", 160 | "dot-prop": ">=4.2.1", 161 | "serialize-javascript": ">=3.1.0", 162 | "acorn": ">=5.7.4", 163 | "ws": ">=1.1.5", 164 | "mixin-deep": ">=1.3.2", 165 | "underscore.string": ">=3.3.5", 166 | "js-yaml": ">=3.13.1", 167 | "fstream": ">=1.0.12", 168 | "engine.io-client": ">=1.6.9", 169 | "webpack-dev-server": ">=3.1.11", 170 | "express": ">=3.11.0", 171 | "negotiator": ">=0.6.1", 172 | "fresh": ">=0.5.2", 173 | "mime": ">=1.4.1", 174 | "hoek": ">=4.2.1" 175 | }, 176 | "keywords": [ 177 | "ej2", 178 | "samples", 179 | "stock-chart", 180 | "syncfusion", 181 | "ej2-samples", 182 | "ej2-ng-stock-chart", 183 | "ej2-showcase-samples", 184 | "syncfusion-samples", 185 | "syncfusion-stock-chart" 186 | ], 187 | "scripts": { 188 | "build": "npm run scripts && gulp styles && gulp bundle", 189 | "scripts": "ngc -p tsconfig-aot.json", 190 | "bundle": "gulp bundle", 191 | "ci-publish": "gulp publish-samples" 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/app/about/about.component.html: -------------------------------------------------------------------------------- 1 |
2 |
{{title}}
3 |
{{description}}
4 |
{{listTitle}}
5 |
6 |
7 | 8 | {{item.control}} 9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /src/app/about/about.component.ts: -------------------------------------------------------------------------------- 1 | import { LowerCasePipe } from '@angular/common'; 2 | import { Directive, HostListener } from '@angular/core'; 3 | import { Component, ViewEncapsulation, OnInit } from '@angular/core'; 4 | 5 | import { MenuComponent } from '../menu/menu.component'; 6 | 7 | 8 | @Component({ 9 | templateUrl: 'about.component.html', 10 | encapsulation: ViewEncapsulation.None, 11 | }) 12 | export class AboutComponent implements OnInit { 13 | public title: string; 14 | public listTitle: string; 15 | public description: string; 16 | public controlList: Object[]; 17 | 18 | /** Configurations for the About page */ 19 | constructor( 20 | public menu: MenuComponent 21 | ) { 22 | this.title = 'About this sample'; 23 | this.listTitle = 'List of EJ2 components used in this sample'; 24 | this.description = 'This stock chart demo application showcases using Essential JS 2 ' 25 | + 'components together in a real-world application scenario. You can further explore the source ' 26 | + 'code of this application and use it as a reference for integrating Essential JS 2 components ' 27 | + 'into your applications.'; 28 | 29 | this.controlList = [ 30 | { 'control': 'Chart', 'link': 'http://ej2.syncfusion.com/angular/documentation/chart/getting-started.html' }, 31 | { 'control': 'Button', 'link': 'http://ej2.syncfusion.com/angular/documentation/button/getting-started.html' }, 32 | { 'control': 'DropDownButton', 'link': 'http://ej2.syncfusion.com/angular/documentation/drop-down-button/getting-started.html' }, 33 | { 'control': 'Toolbar', 'link': 'http://ej2.syncfusion.com/angular/documentation/toolbar/getting-started.html' }, 34 | { 'control': 'DateRangePicker', 'link': 'http://ej2.syncfusion.com/angular/documentation/daterangepicker/getting-started.html' }, 35 | { 'control': 'RangeNavigator', 'link': 'http://ej2.syncfusion.com/angular/documentation/daterangepicker/getting-started.html' }, 36 | ]; 37 | this.handleResize(); 38 | } 39 | 40 | 41 | public ngOnInit(): void { 42 | } 43 | 44 | public handleResize(): void { 45 | setTimeout(() => { 46 | if (document.documentElement.offsetWidth > 1400) { 47 | document.getElementById('about-overall').style.minHeight = 'auto'; 48 | document.getElementById('about-overall').style.minHeight = document.documentElement.offsetHeight + 'px'; 49 | } 50 | }, 100); 51 | } 52 | 53 | @HostListener('window:resize', ['$event']) 54 | onResize(event: any): void { 55 | /** Document height alignment corrections for high resoultion screens */ 56 | this.handleResize(); 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html' 7 | }) 8 | export class AppComponent implements OnInit { 9 | 10 | public ngOnInit(): void { 11 | } 12 | } -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy} from '@angular/common'; 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | 5 | import { ChartAllModule, RangeNavigatorAllModule } from '@syncfusion/ej2-ng-charts'; 6 | 7 | import { DialogAllModule } from '@syncfusion/ej2-ng-popups'; 8 | 9 | import { routing } from './app.router'; 10 | import { ChartComponent } from '../app/chart/chart.component'; 11 | import { MenuComponent } from '../app/menu/menu.component'; 12 | import { AboutComponent } from '../app/about/about.component'; 13 | import { AppComponent } from './app.component'; 14 | 15 | 16 | @NgModule({ 17 | imports: [ 18 | BrowserModule, 19 | ChartAllModule, 20 | DialogAllModule, 21 | RangeNavigatorAllModule, 22 | routing 23 | ], 24 | declarations: [ 25 | ChartComponent, 26 | MenuComponent, 27 | AboutComponent, 28 | AppComponent 29 | ], 30 | entryComponents: [ 31 | AppComponent, 32 | ChartComponent 33 | ], 34 | bootstrap: [AppComponent], 35 | providers: [ {provide: APP_BASE_HREF, useValue : '/' }, Location, {provide: LocationStrategy, useClass: HashLocationStrategy} ] 36 | }) 37 | export class AppModule { 38 | private location: Location; 39 | constructor(location: Location) { this.location = location; } 40 | } -------------------------------------------------------------------------------- /src/app/app.router.ts: -------------------------------------------------------------------------------- 1 | import { ModuleWithProviders } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { AboutComponent } from './about/about.component'; 4 | import { ChartComponent } from './chart/chart.component'; 5 | import { MenuComponent } from './menu/menu.component'; 6 | 7 | // Route Configuration 8 | export const routes: Routes = [ 9 | { path: '', redirectTo: 'stockChart', pathMatch: 'full' }, 10 | { path: 'stockChart', component: ChartComponent}, 11 | { path: 'about', component: AboutComponent } 12 | ]; 13 | 14 | export const routing: ModuleWithProviders = RouterModule.forRoot(routes); -------------------------------------------------------------------------------- /src/app/chart/chart.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | -------------------------------------------------------------------------------- /src/app/chart/chart.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild, OnInit } from '@angular/core'; 2 | import { Browser, remove, EmitType } from '@syncfusion/ej2-base'; 3 | import { Directive, HostListener } from '@angular/core'; 4 | import { Chart, RangeNavigator, IRangeLoadedEventArgs, IRangeSelectorRenderEventArgs, ILoadEventArgs } from '@syncfusion/ej2-ng-charts'; 5 | import { ChartTheme, PeriodSelectorSettingsModel, IChangedEventArgs, ChartSeriesType } from '@syncfusion/ej2-ng-charts'; 6 | import { TechnicalIndicators, TechnicalIndicatorModel, TrendlineTypes, AxisModel, Axis } from '@syncfusion/ej2-charts'; 7 | import { ItemModel } from '@syncfusion/ej2-navigations'; 8 | import { ChartAreaModel, TooltipSettingsModel, CrosshairSettingsModel, ZoomSettingsModel, getElement } from '@syncfusion/ej2-ng-charts'; 9 | import { ITooltipRenderEventArgs, IPointEventArgs, IAxisLabelRenderEventArgs, ILoadedEventArgs } from '@syncfusion/ej2-ng-charts'; 10 | import { IMouseEventArgs, MarginModel, IPointRenderEventArgs, AnimationModel, withInBounds, Series } from '@syncfusion/ej2-ng-charts'; 11 | import { RowModel, LegendSettingsModel, IAxisRangeCalculatedEventArgs, VisibleLabels, ExportType } from '@syncfusion/ej2-ng-charts'; 12 | import { goog, googl, aapl, amzn, tsla, IVolume, IClose } from './stock-data'; 13 | import { DropDownButton, MenuEventArgs } from '@syncfusion/ej2-splitbuttons'; 14 | import { Button } from '@syncfusion/ej2-buttons'; 15 | 16 | 17 | @Component({ 18 | selector: 'stock', 19 | templateUrl: 'chart.component.html', 20 | }) 21 | 22 | 23 | export class ChartComponent implements OnInit { 24 | 25 | //component initialization 26 | @ViewChild('chart') 27 | public chart: Chart; 28 | @ViewChild('range') 29 | public range: RangeNavigator; 30 | 31 | // range navigator 32 | public width: string = '90%'; 33 | public selectedTheme: string = location.hash.split('/')[1] ? location.hash.split('/')[1] : 'Material'; 34 | public theme: ChartTheme = (this.selectedTheme.charAt(0).toUpperCase() + this.selectedTheme.slice(1)); 35 | public periods: PeriodSelectorSettingsModel; 36 | public rangeChanged: EmitType; 37 | public rangeLoaded: EmitType; 38 | public rangeLoad: EmitType; 39 | public chartLoad: EmitType; 40 | public selectorRender: EmitType; 41 | public data: Object[] = googl; 42 | public secondaryData: Object[] = aapl; 43 | public thirdData: Object[] = goog; 44 | public fourthData: Object[] = amzn; 45 | public fifthData: Object[] = tsla; 46 | public firstContent: string; 47 | public setValue: boolean = false; 48 | public setValue1: boolean = false; 49 | public setValue2: boolean = false; 50 | public setValue3: boolean = false; 51 | //chart initialization 52 | public chartArea: ChartAreaModel; 53 | public primaryXAxis: AxisModel; 54 | public primaryYAxis: AxisModel; 55 | public tooltip: TooltipSettingsModel; 56 | public crosshair: CrosshairSettingsModel; 57 | public tooltipRender: EmitType; 58 | public pointRender: EmitType; 59 | public margin: MarginModel; 60 | public zoomSettings: ZoomSettingsModel; 61 | public axisLabelRender: EmitType; 62 | public loaded: EmitType; 63 | public chartClick: EmitType; 64 | public chartMouseMove: EmitType; 65 | public chartMouseLeave: EmitType; 66 | public axes: AxisModel[]; 67 | public rows: RowModel[]; 68 | public legendSettings: LegendSettingsModel; 69 | public axisRangeCalculated: EmitType; 70 | public period: number; 71 | public fastPeriod: number = 8; 72 | public slowPeriod: number = 5; 73 | public macdType: string = 'Both'; 74 | public annotationString: string = '
'; 75 | public animation: AnimationModel = { enable: false }; 76 | public opacity: number; 77 | public secondaryOpacity: number; 78 | public thirdOpacity: number; 79 | public fourthOpacity: number; 80 | public fifthOpacity: number; 81 | public trendLineTooltip: boolean; 82 | public upperLine: object = { 83 | color: '#FFE200', 84 | width: 1 85 | }; 86 | public periodLine: object = { 87 | width: 2 88 | }; 89 | public lowerLine: object = { 90 | color: '#FAA512', 91 | width: 1 92 | }; 93 | 94 | public pointColors: string[] = []; 95 | 96 | 97 | 98 | //private variables: 99 | private indicators: TechnicalIndicators[] = []; 100 | private secondayIndicators: TechnicalIndicators[] = []; 101 | private secondaryValue: string = null; 102 | private thirdValue: string = null; 103 | private fourthValue: string = null; 104 | private fifthValue: string = null; 105 | private tmaValue: string = ': $124.79'; 106 | private bollingerValue: string = ': $9.979'; 107 | private rsiValue: string = ': $99.279'; 108 | private smaValue: string = ': $106.719'; 109 | private macdValue: string = ': 2.719'; 110 | public sidePlacement: boolean = false; 111 | private candleValue: string = '534.07'; 112 | private content: string; 113 | public ngOnInit(): void { 114 | 115 | //range navigator 116 | this.tmaValue = ': $124.79'; 117 | this.bollingerValue = ': $9.979'; 118 | this.rsiValue = ': $99.279'; 119 | this.smaValue = ': $106.719'; 120 | this.macdValue = ': 2.719'; 121 | this.content = this.candle(this.candleValue); 122 | this.firstContent = this.candle('534.07'); 123 | this.periods = { 124 | position: 'Top', 125 | periods: [ 126 | { text: '1M', interval: 1, intervalType: 'Months' }, 127 | { text: '3M', interval: 3, intervalType: 'Months', selected: Browser.isDevice ? true : false }, 128 | { text: '6M', interval: 6, intervalType: 'Months' }, { text: 'YTD' }, 129 | { text: '1Y', interval: 1, intervalType: 'Years', selected: Browser.isDevice ? false : true }, 130 | { text: '2Y', interval: 2, intervalType: 'Years' }, 131 | { text: 'All' } 132 | ] 133 | }; 134 | 135 | this.rangeChanged = (args: IChangedEventArgs) => { 136 | let returnPoint: number; 137 | if (args.selectedData.length > 2000) { 138 | returnPoint = 10; 139 | } else if (args.selectedData.length > 1000) { 140 | returnPoint = 8; 141 | } else if (args.selectedData.length > 600) { 142 | returnPoint = 6; 143 | } else if (args.selectedData.length > 100) { 144 | returnPoint = 3; 145 | } else { 146 | returnPoint = 2; 147 | } 148 | let data: IVolume[] = googl.filter((data: IVolume, index: number) => { 149 | return ((data['x'].getTime() >= (args.start as Date).getTime() && 150 | data['x'].getTime() <= (args.end as Date).getTime()) && index % returnPoint === 0); 151 | }); 152 | let data1: IVolume[] = aapl.filter((data1: IVolume, index: number) => { 153 | return ((data1['x'].getTime() >= (args.start as Date).getTime() && 154 | data1['x'].getTime() <= (args.end as Date).getTime()) && index % returnPoint === 0); 155 | }); 156 | let data2: IClose[] = goog.filter((data2: IClose, index: number) => { 157 | return ((data2['x'].getTime() >= (args.start as Date).getTime() && 158 | data2['x'].getTime() <= (args.end as Date).getTime()) && index % returnPoint === 0); 159 | }); 160 | 161 | let data3: IClose[] = amzn.filter((data3: IClose, index: number) => { 162 | /* tslint:disable:no-string-literal */ 163 | return ((data3['x'].getTime() >= (args.start as Date).getTime() && 164 | data3['x'].getTime() <= (args.end as Date).getTime()) && index % returnPoint === 0); 165 | }); 166 | let data4: IClose[] = tsla.filter((data4: IClose, index: number) => { 167 | /* tslint:disable:no-string-literal */ 168 | return ((data4['x'].getTime() >= (args.start as Date).getTime() && 169 | data4['x'].getTime() <= (args.end as Date).getTime()) && index % returnPoint === 0); 170 | }); 171 | let diff: number = ((args.end as Date).getTime() - (args.start as Date).getTime()) / 1000; 172 | diff /= (60 * 60 * 24 * 7 * 4); 173 | let totalMonths: number = Math.abs(Math.round(diff)); 174 | if (totalMonths >= 13) { 175 | this.chart.primaryXAxis.labelFormat = 'MMM yyy'; 176 | } else if (totalMonths <= 6) { 177 | this.chart.primaryXAxis.labelFormat = 'MMM dd'; 178 | } 179 | this.chart.series[0].animation.enable = false; this.chart.primaryXAxis.zoomPosition = 0; 180 | this.chart.primaryXAxis.zoomFactor = 1; this.chart.series[1].animation.enable = false; 181 | this.chart.primaryXAxis.stripLines = [{ visible: true }]; 182 | this.pointColors = []; this.chart.series[6].dataSource = data4; 183 | this.chart.series[0].dataSource = data; this.chart.series[1].dataSource = data; this.chart.series[2].dataSource = data; 184 | this.chart.series[3].dataSource = data1; this.chart.series[4].dataSource = data2; this.chart.series[5].dataSource = data3; 185 | this.chart.refresh(); this.chart.setAnnotationValue(0, '
'); 186 | }; 187 | this.chartLoad = (args: ILoadedEventArgs) => { 188 | if (document.documentElement.offsetHeight) { 189 | let height: number = (document.documentElement.offsetHeight - 245); 190 | args.chart.height = height > 450 ? (height + '') : null; 191 | } else { 192 | args.chart.height = null; 193 | } 194 | document.body.style.overflowY = args.chart.height ? 'hidden' : 'auto'; 195 | if (document.documentElement.offsetHeight > 700 && document.getElementById('_dialog-content')) { 196 | document.getElementById('_dialog-content').style.overflowY = 'hidden'; 197 | } 198 | document.getElementById('close').style.display = Browser.isDevice ? 'none' : 'block'; 199 | document.getElementById('atClose').style.display = Browser.isDevice ? 'none' : 'block'; 200 | document.getElementById('stockRange').style.paddingTop = Browser.isDevice ? '1%' : '0.5%'; 201 | document.getElementById('stockRange').style.paddingBottom = Browser.isDevice ? '1%' : '0.5%'; 202 | } 203 | this.rangeLoaded = (args: IRangeLoadedEventArgs) => { 204 | let calendar: Element = document.getElementById('customRange'); 205 | calendar.classList.add('e-flat'); 206 | 207 | let icon: Element = document.getElementById('dateIcon'); 208 | icon.classList.add('e-btn-icon'); 209 | 210 | let rect: ClientRect = document.getElementsByClassName('chart-element')[0].getBoundingClientRect(); 211 | let size: number = rect.width > 350 ? 10 : 18; 212 | document.getElementById('range_Secondary_Element').style.transform = 'translateX(' + (rect.left - size) + 'px)'; 213 | document.getElementById('range_Secondary_Element').style.width = rect.width + 'px'; 214 | document.getElementById('stockRange').style.transform = 'translateX(' + (rect.left - 10) + 'px)'; 215 | let seriesType: DropDownButton = new DropDownButton({ 216 | items: [{ text: 'Line' }, { text: 'Hilo' }, { text: 'HiloOpenClose' }, 217 | { text: 'Hollow Candle' }, { text: 'Spline' }, { text: 'Candle' }], 218 | select: (args: MenuEventArgs) => { 219 | if (args.item.text === 'Candle') { 220 | this.chart.series[1].enableSolidCandles = true; 221 | this.chart.series[1].type = 'Candle'; 222 | } else if (args.item.text === 'Hollow Candle') { 223 | this.chart.series[1].enableSolidCandles = false; 224 | this.chart.series[1].type = 'Candle'; 225 | } else { 226 | this.chart.series[1].type = args.item.text; 227 | } 228 | this.chart.refresh(); 229 | this.removeSecondaryElement(0); 230 | }, 231 | iconCss: 'e-icons e-add', cssClass: 'e-caret-hide' 232 | }); 233 | seriesType.appendTo('#seriesType'); 234 | let comparision: DropDownButton = new DropDownButton({ 235 | items: [{ text: 'GOOG' }, { text: 'AAPL' }, { text: 'GOOGL' }, { text: 'AMZN' }, { text: 'TSLA' }], 236 | select: (args: MenuEventArgs) => { 237 | if (args.item.text === 'AAPL' && !this.setValue) { 238 | this.secondaryValue = '467.5' 239 | this.chart.series[3].opacity = 1; 240 | this.chart.series[3].visible = true; 241 | this.setValue = true; 242 | this.chart.refresh(); 243 | } else if (args.item.text === 'GOOGL' && !this.setValue1) { 244 | this.thirdValue = '467.5' 245 | this.chart.series[4].opacity = 1; 246 | this.chart.series[4].visible = true; 247 | this.setValue1 = true; 248 | this.chart.refresh(); 249 | } else if (args.item.text === 'AMZN' && !this.setValue2) { 250 | this.fourthValue = '389.51' 251 | this.chart.series[5].opacity = 1; 252 | this.chart.series[5].visible = true; 253 | this.setValue2 = true; 254 | this.chart.refresh(); 255 | } else if (args.item.text === 'TSLA' && !this.setValue3) { 256 | this.fifthValue = '205.27' 257 | this.chart.series[6].opacity = 1; 258 | this.chart.series[6].visible = true; 259 | this.setValue3 = true; 260 | this.chart.refresh(); 261 | } 262 | this.removeSecondaryElement(0); 263 | this.renderAnnotation(); 264 | }, 265 | iconCss: 'e-icons e-add', cssClass: 'e-caret-hide' 266 | }); 267 | comparision.appendTo('#comparision'); 268 | let reset: Button = new Button({ 269 | iconCss: 'e-icons e-reset', cssClass: 'e-flat' 270 | }); 271 | reset.appendTo('#resetClick'); 272 | let print: Button = new Button({ 273 | iconCss: 'e-icons e-play-icon', cssClass: 'e-flat' 274 | }); 275 | print.appendTo('#print'); 276 | let exportChart: DropDownButton = new DropDownButton({ 277 | items: [{ text: 'JPEG' }, { text: 'PNG' }, { text: 'SVG' }], 278 | iconCss: 'e-icons e-export', cssClass: 'e-caret-hide', 279 | select: (args: MenuEventArgs) => { 280 | let type: ExportType = args.item.text; 281 | this.chart.export(type, 'chart'); 282 | } 283 | }); 284 | exportChart.appendTo('#export'); 285 | 286 | document.getElementById('print').onclick = () => { 287 | this.chart.print(['chartStock']); 288 | }; 289 | document.getElementById('resetClick').onclick = () => { 290 | while (this.chart.indicators.length) { 291 | this.chart.indicators.pop(); 292 | } 293 | this.indicators = []; 294 | this.secondayIndicators = []; 295 | this.chart.series[1].trendlines[0].width = 0; 296 | this.chart.series[1].type = 'Candle'; 297 | this.secondaryValue = null; 298 | this.secondaryOpacity = 0; 299 | this.chart.series[3].opacity = 0; 300 | this.chart.series[3].visible = false; 301 | this.chart.indicatorElements = null; 302 | this.setValue = false; 303 | 304 | this.thirdValue = null; 305 | this.fourthValue = null; 306 | this.thirdOpacity = 0; 307 | this.fourthOpacity = 0; 308 | this.fifthValue = null; 309 | this.fifthOpacity = 0; 310 | 311 | this.chart.series[4].opacity = 0; 312 | this.chart.series[4].visible = false; 313 | this.setValue1 = false; 314 | 315 | this.chart.series[5].opacity = 0; 316 | this.chart.series[5].visible = false; 317 | this.setValue2 = false; 318 | 319 | this.chart.series[6].opacity = 0; 320 | this.chart.series[6].visible = false; 321 | this.setValue3 = false; 322 | this.chart.rows = [ 323 | { height: '15%' }, 324 | { height: '85%' } 325 | ]; 326 | this.chart.axes = [{ 327 | name: 'secondary', opposedPosition: true, rowIndex: 0, desiredIntervals: 2, 328 | majorGridLines: { width: 0, color: '#EDEDED' }, 329 | lineStyle: { width: 1, color: 'whitesmoke' }, majorTickLines: { width: 0 }, rangePadding: 'None' 330 | }]; 331 | this.chart.primaryYAxis = { 332 | crosshairTooltip: { enable: true }, 333 | labelFormat: 'n0', plotOffset: 25, 334 | desiredIntervals: 5, 335 | rowIndex: 1, opposedPosition: true, 336 | lineStyle: { width: 1, color: 'whitesmoke' }, 337 | rangePadding: 'None', 338 | majorGridLines: { width: 1, color: '#EDEDED' }, 339 | }; 340 | this.chart.refresh(); 341 | 342 | if (window.innerWidth > 450) { 343 | this.range.periodSelectorModule.selectedIndex = 8; 344 | this.range.rangeSlider.performAnimation(1398105000000, 1429641000000, this.range); 345 | } else { 346 | this.range.periodSelectorModule.selectedIndex = 4; 347 | this.range.rangeSlider.performAnimation(1421971200000, 1429641000000, this.range); 348 | } 349 | this.chart.setAnnotationValue(1, this.candle(': $534.07')); 350 | }; 351 | let indicatorType: DropDownButton = new DropDownButton({ 352 | items: [{ text: 'TMA' }, { text: 'Bollinger Bands' }, { text: 'RSI' }, { text: 'SMA' }, 353 | { text: 'MACD' }], 354 | iconCss: 'e-icons e-add', cssClass: 'e-caret-hide', 355 | select: (args: MenuEventArgs) => { 356 | let text: string = args.item.text.split(' ')[0].toLocaleLowerCase() + (args.item.text.split(' ')[1] ? args.item.text.split(' ')[1] : ''); 357 | text = text.substr(0, 1).toUpperCase() + text.substr(1); 358 | let type: TechnicalIndicators = text; 359 | if (type === 'Tma' || type === 'BollingerBands' || type === 'Sma') { 360 | if (this.indicators.indexOf(type) === -1) { 361 | let indicator: TechnicalIndicatorModel[] = [{ 362 | type: type, period: 3, fastPeriod: 8, slowPeriod: 5, 363 | seriesName: 'Apple Inc', macdType: 'Both', width: 2, 364 | macdPositiveColor: '#6EC992', macdNegativeColor: '#FF817F', 365 | fill: type === 'Sma' ? '#32CD32' : '#6063ff', 366 | animation: { enable: false }, 367 | upperLine: { color: '#FFE200', width: 1 }, 368 | periodLine: { width: 2 }, 369 | bandColor: 'rgba(245, 203, 35, 0.12)', 370 | lowerLine: { color: '#FAA512', width: 1 } 371 | }]; 372 | 373 | this.indicators.push(type); 374 | this.chart.indicators = this.chart.indicators.concat(indicator); 375 | this.chart.refresh(); 376 | } 377 | } else { 378 | if (this.indicators.indexOf(type) === -1) { 379 | this.indicators.push(type); 380 | this.secondayIndicators.push(type); 381 | let axis: AxisModel[]; 382 | let row: RowModel[] 383 | let indicator: TechnicalIndicatorModel[]; 384 | let len: number = this.chart.rows.length; 385 | this.chart.rows[this.chart.rows.length - 1].height = '15%'; 386 | row = [{ height: '' + (100 - len * 15) + 'px' }]; 387 | this.chart.rows = this.chart.rows.concat(row); 388 | axis = [{ 389 | plotOffset: 10, name: type.toString(), opposedPosition: true, rowIndex: 0, desiredIntervals: 1, 390 | majorGridLines: { width: 0, color: '#EDEDED' }, lineStyle: { width: 1, color: 'whitesmoke' }, 391 | majorTickLines: { width: 0 }, rangePadding: 'None' 392 | }]; 393 | for (let i: number = 0; i < this.chart.axes.length; i++) { 394 | this.chart.axes[i].rowIndex += 1; 395 | } 396 | this.chart.axes = this.chart.axes.concat(axis); 397 | this.chart.primaryYAxis.rowIndex = len + 1; 398 | indicator = [{ 399 | type: type, period: 3, fastPeriod: 8, slowPeriod: 5, 400 | seriesName: 'Apple Inc', macdType: 'Both', width: 2, 401 | macdPositiveColor: '#6EC992', macdNegativeColor: '#FF817F', 402 | fill: '#6063ff', yAxisName: type.toString(), animation: { enable: false }, 403 | upperLine: { color: '#FFE200', width: 1 }, 404 | periodLine: { width: 2 }, 405 | bandColor: 'rgba(245, 203, 35, 0.12)', 406 | lowerLine: { color: '#FAA512', width: 1 } 407 | }]; 408 | this.chart.indicators = this.chart.indicators.concat(indicator); 409 | this.chart.refresh(); 410 | } 411 | } 412 | this.removeSecondaryElement(0); 413 | this.renderAnnotation(); 414 | }, 415 | }); 416 | indicatorType.appendTo('#indicatorType'); 417 | let trendType: DropDownButton = new DropDownButton({ 418 | items: [{ text: 'Linear' }, { text: 'Polynomial' }, { text: 'MovingAverage' }], 419 | select: (args: MenuEventArgs) => { 420 | let type: TrendlineTypes = args.item.text; 421 | this.chart.series[1].trendlines[0].animation.enable = false; 422 | this.chart.series[1].trendlines[0].width = 3; 423 | this.chart.series[1].trendlines[0].type = type; 424 | this.chart.refresh(); 425 | }, 426 | iconCss: 'e-icons e-add', cssClass: 'e-caret-hide' 427 | }); 428 | trendType.appendTo('#trendType'); 429 | args.rangeNavigator.periodSelectorModule.toolbar.refreshOverflow(); 430 | }; 431 | this.selectorRender = (args: IRangeSelectorRenderEventArgs) => { 432 | args.enableCustomFormat = true; 433 | args.content = 'Date Range'; 434 | let seriesModel: ItemModel = { 435 | template: ' ', align: 'Left' 436 | }; 437 | let indicatorModel: ItemModel = { 438 | template: ' ', align: 'Left' 439 | }; 440 | let comparisionModel: ItemModel = { 441 | template: ' ', align: 'Left' 442 | }; 443 | let trendLineModel: ItemModel = { 444 | template: ' ', align: 'Left' 445 | }; 446 | let resetModel: ItemModel = { 447 | template: ' ', align: 'Right', tooltipText: 'Reset' 448 | }; 449 | let printModel: ItemModel = { 450 | template: ' ', align: 'Right', tooltipText: 'Print' 451 | }; 452 | let exportModel: ItemModel = { 453 | template: ' ', align: 'Right', tooltipText: 'Export' 454 | }; 455 | args.selector.splice(0, 0, trendLineModel); 456 | args.selector.splice(0, 0, indicatorModel); 457 | args.selector.splice(0, 0, comparisionModel); 458 | args.selector.splice(0, 0, seriesModel); 459 | args.selector.push(resetModel); 460 | args.selector.push(printModel); 461 | args.selector.push(exportModel); 462 | }; 463 | 464 | 465 | //chart initialization 466 | this.trendLineTooltip = false; 467 | this.opacity = 0; 468 | this.secondaryOpacity = 0; 469 | this.thirdOpacity = 0; 470 | this.fourthOpacity = 0; 471 | this.fifthOpacity = 0; 472 | this.primaryXAxis = { 473 | valueType: 'DateTime', majorGridLines: { width: 0, color: '#EDEDED' }, crosshairTooltip: { enable: true }, 474 | edgeLabelPlacement: 'Hide' 475 | }; 476 | this.primaryYAxis = { 477 | crosshairTooltip: { enable: true }, 478 | labelFormat: 'n0', plotOffset: 25, 479 | desiredIntervals: 5, 480 | rowIndex: 1, opposedPosition: true, 481 | lineStyle: { width: 1, color: 'whitesmoke' }, 482 | rangePadding: 'None', 483 | majorGridLines: { width: 1, color: '#EDEDED' }, 484 | }; 485 | this.rows = [ 486 | { height: '15%' }, 487 | { height: '85%' } 488 | ]; 489 | 490 | this.axes = [{ 491 | name: 'secondary', opposedPosition: true, rowIndex: 0, desiredIntervals: 2, 492 | majorGridLines: { width: 0, color: '#EDEDED' }, 493 | lineStyle: { width: 1, color: 'whitesmoke' }, majorTickLines: { width: 0 }, rangePadding: 'None' 494 | }]; 495 | 496 | this.axisLabelRender = (args: IAxisLabelRenderEventArgs) => { 497 | if (args.axis.name === 'secondary') { 498 | args.text = Math.round((args.value / 10000000)) + 'B'; 499 | } else if (args.axis.orientation === 'Vertical') { 500 | args.text = '$' + Math.round(args.value); 501 | } 502 | }; 503 | this.axisRangeCalculated = (args: IAxisRangeCalculatedEventArgs) => { 504 | this.chart.setAnnotationValue(0, '
'); 505 | }; 506 | this.loaded = (args: ILoadedEventArgs) => { 507 | document.getElementById('stock-details').style.visibility = 'visible'; 508 | document.getElementById('waitingpopup').style.display = 'none'; 509 | let labels: VisibleLabels[] = (args.chart.axisCollections[0]).visibleLabels; 510 | let maxValue: number = args.chart.axisCollections[0].visibleRange.max; 511 | if (args.chart.primaryXAxis.stripLines.length === 1) { 512 | for (let i: number = 0; i < labels.length; i += 2) { 513 | args.chart.primaryXAxis.stripLines.push({ 514 | start: new Date(labels[i].value), end: labels[i + 1] ? new Date(labels[i + 1].value) : new Date(maxValue), 515 | zIndex: 'Behind', border: { width: 0, color: 'transparent' }, rotation: null, 516 | opacity: 0.6, textStyle: {}, text: '', color: '#F1F5FB', visible: true 517 | }); 518 | } 519 | args.chart.refresh(); 520 | } 521 | this.handleResize(); 522 | }; 523 | 524 | this.chartClick = (args: IMouseEventArgs) => { 525 | if (args.target === 'tsla' || args.target === 'amzn' || args.target === 'aapl' || args.target === 'googl' || args.target === 'tma' || args.target === 'bollingerbands' || args.target === 'rsi' || args.target === 'sma' || args.target === 'macd') { 526 | this.removeSecondaryElement(0); 527 | if (args.target === 'aapl') { 528 | this.secondaryValue = null; 529 | this.secondaryOpacity = 0; 530 | this.chart.series[3].opacity = 0; 531 | this.chart.series[3].visible = false; 532 | this.setValue = false; 533 | } 534 | if (args.target === 'googl') { 535 | this.thirdValue = null; 536 | this.thirdOpacity = 0; 537 | this.chart.series[4].opacity = 0; 538 | this.chart.series[4].visible = false; 539 | this.setValue1 = false; 540 | } 541 | 542 | if (args.target === 'amzn') { 543 | this.fourthValue = null; 544 | this.fourthOpacity = 0; 545 | this.chart.series[5].opacity = 0; 546 | this.chart.series[5].visible = false; 547 | this.setValue2 = false; 548 | } 549 | 550 | if (args.target === 'tsla') { 551 | this.fifthValue = null; 552 | this.fifthOpacity = 0; 553 | this.chart.series[6].opacity = 0; 554 | this.chart.series[6].visible = false; 555 | this.setValue3 = false; 556 | } 557 | this.content = this.candle(this.candleValue); 558 | this.indicators = []; 559 | let removeIndex: number; 560 | this.chart.indicators.map((indicator: TechnicalIndicatorModel, index: number) => { 561 | let type: string = indicator.type.toLocaleLowerCase(); 562 | if (type === args.target) { 563 | removeIndex = index; 564 | if (type === 'macd' || type === 'rsi') { 565 | this.secondayIndicators.splice(0, 1); 566 | this.chart.rows.splice(0, 1); 567 | let len: number = this.chart.rows.length; 568 | this.chart.rows[this.chart.rows.length - 1].height = '' + (100 - (len - 1) * 15) + 'px'; 569 | for (let i: number = 0; i < this.chart.axes.length; i++) { 570 | if (this.chart.axes[i].name.toLowerCase() === type) { 571 | this.chart.axes.splice(i, 1); 572 | break; 573 | } 574 | } 575 | for (let i: number = 0; i < this.chart.axes.length; i++) { 576 | this.chart.axes[i].rowIndex -= 1; 577 | } 578 | 579 | this.chart.primaryYAxis.rowIndex = len - 1; 580 | } 581 | type = null; 582 | } 583 | if (type === 'tma') { 584 | this.indicators.push('Tma'); 585 | this.content += this.tma(this.tmaValue); 586 | } else if (type === 'bollingerbands') { 587 | this.indicators.push('BollingerBands'); 588 | this.content += this.bollinger(this.bollingerValue); 589 | } else if (type === 'rsi') { 590 | this.indicators.push('Rsi'); 591 | this.content += this.rsi(this.rsiValue); 592 | } else if (type === 'sma') { 593 | this.indicators.push('Sma'); 594 | this.content += this.sma(this.smaValue); 595 | } else if (type === 'macd') { 596 | this.indicators.push('Macd'); 597 | this.content += this.macd(this.macdValue); 598 | } 599 | }); 600 | if (removeIndex !== undefined) { 601 | this.chart.indicators.splice(removeIndex, 1); 602 | } 603 | if (this.secondaryValue) { 604 | this.content += this.compare(this.secondaryValue); 605 | } 606 | if (this.thirdValue) { 607 | this.content += this.compare1(this.thirdValue); 608 | } 609 | if (this.fourthValue) { 610 | this.content += this.compare2(this.fourthValue); 611 | } 612 | if (this.fifthValue) { 613 | this.content += this.compare3(this.fifthValue); 614 | } 615 | if (document.getElementById('chartStock_Annotation_1').childNodes.length === 1) { 616 | this.chart.indicatorElements = null; 617 | } 618 | if (this.chart.indicators.length === 0) { 619 | this.chart.indicatorElements = null; 620 | } 621 | this.chart.refresh(); 622 | this.chart.setAnnotationValue(1, this.content); 623 | } 624 | }; 625 | this.tooltip = { 626 | enable: true, 627 | shared: true, 628 | header: '', 629 | format: '${point.x}
High : ${point.high}
Low :' + 630 | ' ${point.low}
Open : ${point.open}
Close : ${point.close}
Volume : ${point.volume}' 631 | }; 632 | this.crosshair = { 633 | enable: true, lineType: 'Both' 634 | }; 635 | 636 | this.legendSettings = { 637 | visible: false 638 | }; 639 | this.period = 3; 640 | this.chartArea = { 641 | border: { width: 1, color: 'whitesmoke' } 642 | }; 643 | this.zoomSettings = { enableMouseWheelZooming: true, mode: 'X', toolbarItems: [] }; 644 | 645 | this.tooltipRender = (args: ITooltipRenderEventArgs) => { 646 | if (args.series.name === 'Apple Inc') { 647 | this.content += this.candle(' :$' + args.text.split('
')[4].split('')[1].split('')[0]); 648 | } 649 | if (args.series.type === 'Candle') { 650 | this.chart.setAnnotationValue(0, this.annotationString + (this.getContent(args.text) + '') + '
'); 651 | } else if (args.series.name === 'AAPL' && this.setValue) { 652 | this.content += this.compare(args.text.split('
')[4].split('')[1].split('')[0]); 653 | } else if (args.series.name === 'GOOGL' && this.setValue1) { 654 | this.content += this.compare1(args.text.split('
')[4].split('')[1].split('')[0]); 655 | } else if (args.series.name === 'AMZN' && this.setValue2) { 656 | this.content += this.compare2(args.text.split('
')[4].split('')[1].split('')[0]); 657 | } else if (args.series.name === 'TSLA' && this.setValue3) { 658 | this.content += this.compare3(args.text.split('
')[4].split('')[1].split('')[0]); 659 | } else { 660 | /* tslint:disable:no-string-literal */ 661 | this.setIndicatorAnnotation(args.text, (args.series as Series)['parentObj']['type']); 662 | } 663 | args.text = ''; 664 | }; 665 | 666 | this.pointRender = (args: IPointRenderEventArgs) => { 667 | if (args.series.type === 'Candle') { 668 | this.pointColors.push(args.fill); 669 | } else { 670 | args.fill = this.pointColors[args.point.index]; 671 | } 672 | }; 673 | 674 | this.chartMouseLeave = (args: IMouseEventArgs) => { this.removeSecondaryElement(); }; 675 | this.chartMouseMove = (args: IMouseEventArgs) => { 676 | if (!withInBounds(this.chart.mouseX, this.chart.mouseY, this.chart.chartAxisLayoutPanel.seriesClipRect)) { 677 | this.removeSecondaryElement(); 678 | } 679 | }; 680 | 681 | } 682 | public renderAnnotation(): void { 683 | this.content = this.candle(this.candleValue); 684 | if (this.secondaryValue) { 685 | this.content += this.compare(this.secondaryValue); 686 | } 687 | if (this.thirdValue) { 688 | this.content += this.compare1(this.thirdValue); 689 | } 690 | if (this.fourthValue) { 691 | this.content += this.compare2(this.fourthValue); 692 | } 693 | if (this.fifthValue) { 694 | this.content += this.compare3(this.fifthValue); 695 | } 696 | this.chart.indicators.map((indicator: TechnicalIndicatorModel) => { 697 | let type: string = indicator.type.toLocaleLowerCase(); 698 | if (type === 'tma') { 699 | this.content += this.tma(this.tmaValue); 700 | } else if (type === 'bollingerbands') { 701 | this.content += this.bollinger(this.bollingerValue); 702 | } else if (type === 'rsi') { 703 | this.content += this.rsi(this.rsiValue); 704 | } else if (type === 'sma') { 705 | this.content += this.sma(this.smaValue); 706 | } else if (type === 'macd') { 707 | this.content += this.macd(this.macdValue); 708 | } 709 | }); 710 | this.chart.setAnnotationValue(1, this.content); 711 | } 712 | public candle(value: string): string { 713 | this.candleValue = value.indexOf('$') > -1 ? value.split('$')[1] : value; 714 | return '
' + 718 | '' + 720 | 'GOOG: $' + this.candleValue + '
'; 721 | } 722 | 723 | public tma(value: string): string { 724 | this.tmaValue = value.indexOf(':') > -1 ? value.split(':')[1] : value; 725 | return '
' + 729 | 'TMA:' + this.tmaValue + '' + 730 | '
'; 731 | }; 732 | public compare(value: string): string { 733 | this.secondaryValue = value; 734 | return '
' + 738 | '' + 740 | 'AAPL: $' + value + '' + 741 | '
'; 742 | }; 743 | 744 | public compare1(value: string): string { 745 | this.thirdValue = value; 746 | return '
' + 750 | '' + 752 | 'GOOGL: $' + value + '' + 753 | '
'; 754 | }; 755 | 756 | 757 | public compare2(value: string): string { 758 | this.fourthValue = value; 759 | return '
' + 763 | '' + 765 | 'AMZN: $' + value + '' + 766 | '
'; 767 | }; 768 | 769 | public compare3(value: string): string { 770 | this.fifthValue = value; 771 | return '
' + 775 | '' + 777 | 'TSLA: $' + value + '' + 778 | '
'; 779 | }; 780 | public bollinger(value: string): string { 781 | this.bollingerValue = value.indexOf(':') > -1 ? value.split(':')[1] : value; 782 | return '
' + 786 | 'Bollinger: ' + this.bollingerValue + '' + 787 | '
'; 788 | }; 789 | public rsi(value: string): string { 790 | this.rsiValue = value.indexOf(':') > -1 ? value.split(':')[1] : value; 791 | return '
' + 795 | 'RSI:' + this.rsiValue + '' + 796 | '
'; 797 | }; 798 | public sma(value: string): string { 799 | this.smaValue = value.indexOf(':') > -1 ? value.split(':')[1] : value; 800 | return '
' + 804 | 'SMA:' + this.smaValue + '' + 805 | '
'; 806 | }; 807 | public macd(value: string): string { 808 | this.macdValue = value.indexOf(':') > -1 ? value.split(':')[1] : value; 809 | return '
' + 813 | 'MACD:' + this.macdValue + '' + 814 | '
'; 815 | }; 816 | 817 | public setIndicatorAnnotation(value: string, type: string): string { 818 | if (value.indexOf('SignalLine') > -1) { 819 | value = value.replace('SignalLine', '') 820 | if (type === 'Tma') { 821 | this.tmaValue = value.replace(' : ', ': $'); 822 | } else if (type === 'Macd') { 823 | value = value; 824 | this.macdValue = value; 825 | } else if (type === 'BollingerBands') { 826 | this.bollingerValue = value.replace(' : ', ': $'); 827 | } else if (type === 'Rsi') { 828 | this.rsiValue = value.replace(' : ', ': $'); 829 | } else { 830 | this.smaValue = value.replace(' : ', ': $'); 831 | } 832 | } 833 | this.renderAnnotation(); 834 | return this.content; 835 | } 836 | 837 | public getContent(value: string): string { 838 | let text: string[] = value.split('
'); let html: string = ''; 839 | for (let i: number = 1; i < text.length; i++) { 840 | let value: string[] = text[i].split(':'); 841 | if (i === text.length - 1) { 842 | html += ''; 847 | } 848 | } 849 | return html; 850 | }; 851 | 852 | public removeSecondaryElement = (time?: number): void => { 853 | setTimeout(() => { 854 | if (getElement('annotation')) { 855 | remove(getElement('annotation')); 856 | } 857 | }, 858 | // tslint:disable-next-line:align 859 | time === 0 ? this.chart.setAnnotationValue(0, '
') : 2000 860 | ); 861 | } 862 | 863 | public handleResize(): void { 864 | document.getElementById('stock-details').style.minHeight = 'auto'; 865 | document.getElementById('stock-details').style.minHeight = document.documentElement.offsetHeight + 'px'; 866 | 867 | let elements: NodeList = document.querySelectorAll('.e-popup-open'); 868 | let length: number = elements.length; 869 | for (let i: number = 0; i < length; i++) { 870 | (elements[i] as HTMLElement).classList.remove('e-popup-open'); 871 | (elements[i] as HTMLElement).classList.add('e-popup-close'); 872 | } 873 | } 874 | 875 | @HostListener('window:resize', ['$event']) 876 | onResize(event: any): void { 877 | /** Document height alignment corrections for high resoultions screens */ 878 | this.handleResize(); 879 | } 880 | } -------------------------------------------------------------------------------- /src/app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowser } from '@angular/platform-browser'; 2 | import { AppModule } from './app.module'; 3 | platformBrowser().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /src/app/menu/menu.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | Stock  Analysis Demo 7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 | 15 | 17 | 18 |
19 |
20 |
{{description}}
21 |
{{listTitle}}
22 |
23 |
24 | 25 | {{item.control}} 26 |
27 |
28 |
29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /src/app/menu/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Directive, ElementRef } from '@angular/core'; 2 | import { HostListener } from '@angular/core'; 3 | import { Browser, rippleEffect, isNullOrUndefined as isNOU, enableRipple } from '@syncfusion/ej2-base'; 4 | import { ViewChild, AfterViewInit } from '@angular/core'; 5 | import { DialogComponent } from '@syncfusion/ej2-ng-popups'; 6 | import { EmitType } from '@syncfusion/ej2-base'; 7 | enableRipple(true); 8 | 9 | 10 | @Component({ 11 | selector: 'menu', 12 | templateUrl: 'menu.component.html' 13 | }) 14 | 15 | export class MenuComponent { 16 | public menu: HTMLElement; 17 | public userName: string; 18 | public filterMenu: HTMLElement; 19 | public overlay: HTMLElement; 20 | // Define Dialog properties 21 | @ViewChild('confirmDialog') 22 | public confirmDialog: DialogComponent; 23 | public confirmHeader: string = 'About'; 24 | public showCloseIcon: Boolean = false; 25 | public visible: Boolean = true; 26 | public hidden: Boolean = false; 27 | public confirmCloseIcon: Boolean = true; 28 | public position: object = { X: 'center', Y: 'center' }; 29 | public target: string = '.stock-details'; 30 | public confirmWidth: string = '50%'; 31 | public animationSettings: Object = { effect: 'None' }; 32 | public hide: any; 33 | public title: string; 34 | public listTitle: string; 35 | public description: string; 36 | public controlList: Object[]; 37 | public confirmHeight: string = '400px'; 38 | 39 | constructor(public eleRef: ElementRef) { 40 | /** Loads the user data in the profile from the sidebar */ 41 | rippleEffect(document.body, { selector: '.ripple-element', rippleFlag: true }); 42 | this.title = 'About this sample'; 43 | this.listTitle = 'List of EJ2 components used in this sample'; 44 | this.description = ' This demo helps to track and visualize the stock price of various sectors/industries over a specific' + 45 | ' period using Essential JS 2 components. Different types of technical indicators' + 46 | ' in chart help you to track the price movement based on the past prices, and the time periods ' + 47 | 'can be selected using range navigator. In addition to this, the DateRangePicker helps you to ' + 48 | 'select custom periods to check the stock price. Different types of series help to visualize the' + 49 | ' open, high, low, and close values of the stock. You can further explore the source code of this ' + 50 | 'application and use it as a reference for integrating Essential JS 2 components into your applications.'; 51 | 52 | this.controlList = [ 53 | { 'control': 'Chart', 'link': 'http://ej2.syncfusion.com/angular/documentation/chart/getting-started.html' }, 54 | { 'control': 'Button', 'link': 'http://ej2.syncfusion.com/angular/documentation/button/getting-started.html' }, 55 | { 'control': 'DropDownButton', 'link': 'http://ej2.syncfusion.com/angular/documentation/drop-down-button/getting-started.html' }, 56 | { 'control': 'Toolbar', 'link': 'http://ej2.syncfusion.com/angular/documentation/toolbar/getting-started.html' }, 57 | { 'control': 'Dialog', 'link': 'https://ej2.syncfusion.com/16.1.37/angular/documentation/dialog/getting-started.html' }, 58 | { 'control': 'DateRangePicker', 'link': 'http://ej2.syncfusion.com/angular/documentation/daterangepicker/getting-started.html' }, 59 | { 'control': 'RangeNavigator', 'link': 'https://ej2.syncfusion.com/angular/documentation/rangenavigator/getting-started.html ' }, 60 | ]; 61 | } 62 | 63 | public ngAfterViewInit(): void { 64 | /** Holds the sidebar elements for later use */ 65 | this.menu = this.eleRef.nativeElement.querySelector('#sidebar-wrapper'); 66 | this.overlay = this.eleRef.nativeElement.querySelector('#overlay'); 67 | } 68 | 69 | 70 | /** Toggles the sidebar open and close actions - for small resoultion */ 71 | public toggleMenu(): void { 72 | this.confirmDialog.show(); 73 | this.dialogOpen(); 74 | } 75 | 76 | public confirmDlgBtnClick: EmitType = () => { 77 | this.confirmDialog.hide(); 78 | } 79 | 80 | 81 | // On Dialog close, show the buttons 82 | public dialogClose: EmitType = () => { 83 | (document.querySelectorAll('.container-control')[0] as HTMLElement).classList.remove('disabled-elemment') 84 | } 85 | // On Dialog open, hide the buttons 86 | public dialogOpen: EmitType = () => { 87 | (document.querySelectorAll('.container-control')[0] as HTMLElement).classList.add('disabled-elemment') 88 | } 89 | 90 | 91 | public handleResize(): void { 92 | this.confirmDialog.refreshPosition(); 93 | } 94 | 95 | @HostListener('window:resize', ['$event']) 96 | onResize(event: any): void { 97 | /** Document height alignment corrections for high resoultion screens */ 98 | this.handleResize(); 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/assets/images/About-Normal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | path1 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/About-Selection.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | path1 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/Analysis-Normal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stroke 5 Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/Analysis-Selection.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stroke 5 Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/Information.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/images/Stock_Analysis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/Stock_Analysis.png -------------------------------------------------------------------------------- /src/assets/images/fonts/Expense-Analysis-Sample.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/Expense-Analysis-Sample.eot -------------------------------------------------------------------------------- /src/assets/images/fonts/Expense-Analysis-Sample.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/fonts/Expense-Analysis-Sample.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/Expense-Analysis-Sample.ttf -------------------------------------------------------------------------------- /src/assets/images/fonts/Expense-Analysis-Sample.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/Expense-Analysis-Sample.woff -------------------------------------------------------------------------------- /src/assets/images/fonts/controls.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/controls.eot -------------------------------------------------------------------------------- /src/assets/images/fonts/controls.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/controls.ttf -------------------------------------------------------------------------------- /src/assets/images/fonts/controls.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/controls.woff -------------------------------------------------------------------------------- /src/assets/images/fonts/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/icons.eot -------------------------------------------------------------------------------- /src/assets/images/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/icons.ttf -------------------------------------------------------------------------------- /src/assets/images/fonts/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/fonts/icons.woff -------------------------------------------------------------------------------- /src/assets/images/sb-icons/Syncfusion-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | Artboard 2 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/assets/images/sb-icons/Syncfusion-mobile-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | Sync-logo 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/images/sb-icons/fonts/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/sb-icons/fonts/icons.eot -------------------------------------------------------------------------------- /src/assets/images/sb-icons/fonts/icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/assets/images/sb-icons/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/sb-icons/fonts/icons.ttf -------------------------------------------------------------------------------- /src/assets/images/sb-icons/fonts/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/assets/images/sb-icons/fonts/icons.woff -------------------------------------------------------------------------------- /src/assets/images/sb-icons/new-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 75 | 76 | 77 | 79 | 80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/assets/images/sb-icons/preview-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 52 | 53 | 54 | 56 | 61 | 62 | 63 | 64 | 65 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syncfusion/ej2-showcase-angular-stockchart/66edca757e65820af6f42360ead5157b01bc9ac3/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Essential JS 2 for Angular - Stock chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Required to support Web Animations `@angular/platform-browser/animations`. 51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 52 | **/ 53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 54 | 55 | 56 | 57 | /*************************************************************************************************** 58 | * Zone JS is required by default for Angular itself. 59 | */ 60 | import 'zone.js/dist/zone'; // Included with Angular CLI. 61 | 62 | 63 | 64 | /*************************************************************************************************** 65 | * APPLICATION IMPORTS 66 | */ 67 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* Add application styles & imports to this file! */ 2 | @import "./assets/index.css"; -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "types": [ 8 | "jasmine", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "test.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig-aot.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "es2015", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "declaration": true, 10 | "lib": ["es2015", "dom"], 11 | "noImplicitAny": true, 12 | "suppressImplicitAnyIndexErrors": true, 13 | "types": ["requirejs"] 14 | }, 15 | "exclude": [ 16 | "node_modules" 17 | ], 18 | "files": [ 19 | "src/app/app.module.ts", 20 | "src/app/main.ts" 21 | ], 22 | "angularCompilerOptions": { 23 | "skipMetadataEmit": true 24 | } 25 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "amd", 5 | "declaration": true, 6 | "removeComments": true, 7 | "noLib": false, 8 | "lib": ["es2015", "dom"], 9 | "experimentalDecorators": true, 10 | "emitDecoratorMetadata": true, 11 | "sourceMap": true, 12 | "pretty": true, 13 | "allowUnreachableCode": false, 14 | "allowUnusedLabels": false, 15 | "noImplicitAny": true, 16 | "noImplicitReturns": true, 17 | "noImplicitUseStrict": false, 18 | "noFallthroughCasesInSwitch": true, 19 | "allowJs": false, 20 | "forceConsistentCasingInFileNames": true, 21 | "moduleResolution": "node", 22 | "types": ["requirejs"] 23 | }, 24 | "exclude": [ 25 | "node_modules" 26 | ], 27 | "compileOnSave": false 28 | } --------------------------------------------------------------------------------
' + value[0] + '' + 843 | Math.round(((+value[1].split('')[0].split('')[1]) / 10000000)) + 'B'; 844 | } else { 845 | html += '
' + value[0] + '$' + 846 | (+value[1].split(' ')[1].split('')[0]).toFixed(2) + '